vue3?使用setup語(yǔ)法糖實(shí)現(xiàn)分類管理功能
setup語(yǔ)法糖簡(jiǎn)介
直接在 script 標(biāo)簽中添加 setup 屬性就可以直接使用 setup 語(yǔ)法糖了。
使用 setup 語(yǔ)法糖后,不用寫 setup 函數(shù),組件只需要引入不需要注冊(cè),屬性和方法也不需要再返回,可以直接在 template 模板中使用。
setup語(yǔ)法糖中新增的api
- defineProps:子組件接收父組件中傳來(lái)的
props - defineEmits:子組件調(diào)用父組件中的方法
- defineExpose:子組件暴露屬性,可以在父組件中拿到
模塊簡(jiǎn)介
本次模塊使用 vue3+element-plus 實(shí)現(xiàn)一個(gè)新聞?wù)镜暮笈_(tái)分類管理模塊,其中新增、編輯采用對(duì)話框方式公用一個(gè)表單。
分類模塊路由
添加分類模塊的路由
import { createRouter, createWebHistory } from "vue-router";
import Layout from "@/views/layout/IndexView";
const routes = [
{
path: "/sign_in",
component: () => import("@/views/auth/SignIn"),
meta: { title: "登錄" },
},
{
path: "/",
component: Layout,
children: [
{
path: "",
component: () => import("@/views/HomeView"),
meta: { title: "首頁(yè)" },
},
// 分類管理
{
path: "/categories",
component: () => import("@/views/categories/ListView"),
meta: { title: "分類列表" },
},
],
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
分類列表組件
在 views/categories/ListView.vue 中
<template>
<div>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首頁(yè)</el-breadcrumb-item>
<el-breadcrumb-item>內(nèi)容管理</el-breadcrumb-item>
<el-breadcrumb-item>分類列表</el-breadcrumb-item>
</el-breadcrumb>
<el-divider />
<el-button type="primary">新增</el-button>
<el-table :data="categories" style="width: 100%" class="set-top">
<el-table-column prop="id" label="編號(hào)" width="180" />
<el-table-column label="名稱" width="180">
<template #default="scope">
<el-tag>{{ scope.row.name }}</el-tag>
</template>
</el-table-column>
<el-table-column label="排序" width="180">
<template #default="scope">
{{ scope.row.sort }}
</template>
</el-table-column>
<el-table-column label="創(chuàng)建日期" width="180">
<template #default="scope">
{{ formatter(scope.row.createdAt) }}
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.row)"
>編輯
</el-button>
<el-popconfirm
title="確定要?jiǎng)h除么?"
confirm-button-text="確定"
cancel-button-text="取消"
@confirm="handleDelete(scope.row)"
>
<template #reference>
<el-button size="small" type="danger">刪除 </el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
</template>
獲取分類列表數(shù)據(jù)
<script setup>
import { ref } from "vue"; // 5、導(dǎo)入 ref
import { fetchCategoryList } from "@/api/categories"; // 6、導(dǎo)入接口 api
import moment from "moment"; // 7、導(dǎo)入 moment 包
import { ElMessage, ElNotification } from "element-plus"; // 9、導(dǎo)入消息通知包
// 4、定義分類列表數(shù)組
const categories = ref([]);
// 1、獲取分類列表數(shù)據(jù)
const init = async () => {
const res = await fetchCategoryList();
// 3、賦值
categories.value = res.data.categories;
};
// 2、調(diào)用 init 方法
init();
// 8、時(shí)間格式化
const formatter = (date) => {
if (!date) {
return "";
}
moment.locale("zh-cn");
return moment(date).format("LL");
};
const handleEdit = (row) => {
console.log(row);
};
// 10、點(diǎn)擊刪除按鈕
const handleDelete = (row) => {
try {
const res = await deleteCategory(row.id);
if (res.code === 20000) {
init();
ElNotification({
title: "成功",
message: res.message,
type: "success",
});
}
} catch (e) {
if (e.Error) {
ElMessage.error(e.Error);
}
}
};
</script>
分類表單組件
1、新建 src/views/categories/components/CategoryForm.vue
<template>
<el-dialog v-model="dialogFormVisible" title="新增分類">
<el-form :model="form" :rules="rules" ref="ruleFormRef">
<el-form-item label="名稱" :label-width="formLabelWidth" prop="name">
<el-input v-model="form.name" autocomplete="off" size="large" />
</el-form-item>
<el-form-item label="排序" :label-width="formLabelWidth" prop="sort">
<el-input v-model.number="form.sort" autocomplete="off" size="large" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">立即創(chuàng)建</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { reactive, ref } from "vue";
// 1、定義對(duì)話框?qū)傩裕J(rèn)值為 false
const dialogFormVisible = ref(false);
// 2、定義表單對(duì)象和屬性
const form = ref({
name: "",
sort: 0,
});
const formLabelWidth = "140px";
// 3、表單驗(yàn)證
const ruleFormRef = ref();
const rules = reactive({
name: [
{ required: true, message: "請(qǐng)輸入分類名稱", trigger: "blur" },
{ min: 2, max: 20, message: "長(zhǎng)度在 2 ~ 20 位", trigger: "blur" },
],
sort: [
{ required: true, message: "請(qǐng)輸入排序", trigger: "blur" },
{ type: "number", message: "排序必須為數(shù)字值" },
],
});
// 4、表單提交
const submitForm = async (formEl) => {
await formEl.validate(async (valid) => {
if (valid) {
console.log('submit');
}
}
}
</script>
2、在 categories/ListView.vue 中引入上述表單組件
<template>
<div>
.
.
<!--表單對(duì)話框-->
<CategoryForm ref="dialogShow" />
</div>
</template>
<script setup>
import CategoryForm from "./components/CategoryForm"; // 導(dǎo)入對(duì)話框組件
</script>
ref=“dialogShow”:給表單對(duì)話框起別名
3、給新增、編輯按鈕分別綁定事件,點(diǎn)擊后彈出對(duì)話框
<el-button type="primary" @click="handleCreate">新增</el-button> <el-button size="small" @click="handleEdit(scope.row)">編輯</el-button>
// 點(diǎn)擊新增按鈕觸發(fā)子組件的 showForm 方法,并傳參 create,代表新增
const dialogShow = ref(null);
const handleCreate = async () => {
dialogShow.value.showForm("create");
};
// 點(diǎn)擊編輯按鈕鈕觸發(fā)子組件的 showForm 方法,并傳參 edit 和編輯所需的 id 值,代表編輯
const handleEdit = async (row) => {
dialogShow.value.showForm("edit", { id: row.id });
};
4、在表單組件中
<script setup>
// 顯示對(duì)話框
const showForm = async (type, data) => {
console.log(type);
console.log(data);
}
</script>
測(cè)試:此時(shí)點(diǎn)擊新增或編輯按鈕,發(fā)現(xiàn)無(wú)法觸發(fā) showForm 方法。原因在于我們要在父組件中調(diào)用子組件的方法,需導(dǎo)出子組件的方法后才能調(diào)用
<script setup>
import { defineExpose } from "vue";
defineExpose({
showForm,
});
</script>
此時(shí)再次點(diǎn)擊新增或編輯按鈕,發(fā)現(xiàn)已經(jīng)拿到了 type 和 data 的值了。
5、完成新增和編輯的對(duì)話框正常顯示
// 定義表單類型的默認(rèn)值為 create
const formType = ref("create");
// 完成新增和編輯正常對(duì)話框顯示
const showForm = async (type, data) => {
dialogFormVisible.value = true;
formType.value = type;
if (type == "create") {
form.value = {};
} else {
fetchCategory(data.id).then((res) => {
form.value = res.data.category;
});
}
};
對(duì)話框字體顯示
根據(jù) formType 的值判斷顯示新增或編輯
<template>
<el-dialog
v-model="dialogFormVisible"
:title="formType == 'create' ? '新增分類' : '編輯分類'"
>
<el-form :model="form" :rules="rules" ref="ruleFormRef">
<el-form-item label="名稱" :label-width="formLabelWidth" prop="name">
<el-input v-model="form.name" autocomplete="off" size="large" />
</el-form-item>
<el-form-item label="排序" :label-width="formLabelWidth" prop="sort">
<el-input v-model.number="form.sort" autocomplete="off" size="large" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogFormVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm(ruleFormRef)">{{
formType == "create" ? "立即創(chuàng)建" : "立即更新"
}}</el-button>
</span>
</template>
</el-dialog>
</template>
完成新增和編輯功能
import {
createCategory,
fetchCategory,
updateCategory,
} from "@/api/categories";
import { ElMessage, ElNotification } from "element-plus";
// 表單提交
const submitForm = async (formEl) => {
await formEl.validate(async (valid) => {
if (valid) {
let res;
try {
if (formType.value == "create") {
res = await createCategory(form.value);
} else {
res = await updateCategory(form.value.id, form.value);
}
if (res.code === 20000) {
ElNotification({
title: "成功",
message: res.message,
type: "success",
});
dialogFormVisible.value = false;
}
} catch (e) {
if (e.Error) {
ElMessage.error(e.Error);
}
}
}
});
};
當(dāng)新增或編輯表單提交后,新的數(shù)據(jù)要同步渲染到頁(yè)面,根據(jù)思路,我們需要調(diào)用父組件的 init 方法即可,所以這里涉及到子組件調(diào)用父組件的方法
修改父組件引用子組件的代碼,增加 @init 事件,綁定 init 方法
<!--表單對(duì)話框--> <CategoryForm ref="dialogShow" @init="init" />
在子組件中調(diào)用,注意注釋中的代碼
// eslint-disable-next-line no-undef
const emit = defineEmits(["init"]); // 引入父組件的 init 方法
const submitForm = async (formEl) => {
await formEl.validate(async (valid) => {
if (valid) {
let res;
try {
if (formType.value == "create") {
res = await createCategory(form.value);
} else {
res = await updateCategory(form.value.id, form.value);
}
if (res.code === 20000) {
ElNotification({
title: "成功",
message: res.message,
type: "success",
});
dialogFormVisible.value = false;
emit("init"); // 調(diào)用 init
}
} catch (e) {
if (e.Error) {
ElMessage.error(e.Error);
}
}
}
});
};
到此這篇關(guān)于vue3 使用setup語(yǔ)法糖實(shí)現(xiàn)分類管理的文章就介紹到這了,更多相關(guān)vue3 setup語(yǔ)法糖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3?setup語(yǔ)法糖之組件傳參(defineProps、defineEmits、defineExpose)示例詳解
- vue3中setup語(yǔ)法糖下通用的分頁(yè)插件實(shí)例詳解
- vue3:setup語(yǔ)法糖使用教程
- Vue3?$emit用法指南(含選項(xiàng)API、組合API及?setup?語(yǔ)法糖)
- 詳解如何在Vue3使用<script lang=“ts“ setup>語(yǔ)法糖
- Vue3中的?computed,watch,watchEffect的使用方法
- Vue3中的setup語(yǔ)法糖、computed函數(shù)、watch函數(shù)詳解
相關(guān)文章
vue?使用el-table循環(huán)生成表格的過(guò)程
這篇文章主要介紹了vue?使用el-table循環(huán)生成表格的過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例
這篇文章主要介紹了vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下2021-04-04
vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決
這篇文章主要介紹了vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
vue實(shí)現(xiàn)動(dòng)態(tài)列表點(diǎn)擊各行換色的方法
今天小編就為大家分享一篇vue實(shí)現(xiàn)動(dòng)態(tài)列表點(diǎn)擊各行換色的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
基于Vue + Axios實(shí)現(xiàn)全局Loading自動(dòng)顯示關(guān)閉效果
在vue項(xiàng)目中,我們通常會(huì)使用Axios來(lái)與后臺(tái)進(jìn)行數(shù)據(jù)交互,而當(dāng)我們發(fā)起請(qǐng)求時(shí),常常需要在頁(yè)面上顯示一個(gè)加載框(Loading),然后等數(shù)據(jù)返回后自動(dòng)將其隱藏,本文介紹了基于Vue + Axios實(shí)現(xiàn)全局Loading自動(dòng)顯示關(guān)閉效果,需要的朋友可以參考下2024-03-03
Vue中渲染系統(tǒng)模塊的實(shí)現(xiàn)詳解
想要實(shí)現(xiàn)一個(gè)簡(jiǎn)潔版的Mini-Vue框架,應(yīng)該包含三個(gè)模塊:分別是:渲染系統(tǒng)模塊、可響應(yīng)式系統(tǒng)模塊、應(yīng)用程序入庫(kù)模塊,本文主要介紹的是渲染系統(tǒng)模塊的實(shí)現(xiàn),需要的可以參考一下2023-07-07
詳解Vue基于 Nuxt.js 實(shí)現(xiàn)服務(wù)端渲染(SSR)
直接使用 Vue 構(gòu)建前端單頁(yè)面應(yīng)用,頁(yè)面源碼時(shí)只有簡(jiǎn)單的幾行 html,這并不利于網(wǎng)站的 SEO,這時(shí)候就需要服務(wù)端渲染,本篇文章主要介紹了詳解Vue基于 Nuxt.js 實(shí)現(xiàn)服務(wù)端渲染(SSR),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Vue鼠標(biāo)點(diǎn)擊事件和鍵盤事件舉例詳解
在Vue框架中我們經(jīng)常需要綁定各種JS事件,如"點(diǎn)擊事件"、"鼠標(biāo)移動(dòng)事件"、"鍵盤事件"等等,這篇文章主要給大家介紹了關(guān)于Vue鼠標(biāo)點(diǎn)擊事件和鍵盤事件的相關(guān)資料,需要的朋友可以參考下2024-01-01
Vue動(dòng)態(tài)生成el-checkbox點(diǎn)擊無(wú)法賦值的解決方法
這篇文章主要給大家介紹了關(guān)于Vue動(dòng)態(tài)生成el-checkbox點(diǎn)擊無(wú)法賦值的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02

