vue3?使用setup語法糖實現(xiàn)分類管理功能
setup語法糖簡介
直接在 script 標簽中添加 setup 屬性就可以直接使用 setup 語法糖了。
使用 setup 語法糖后,不用寫 setup 函數(shù),組件只需要引入不需要注冊,屬性和方法也不需要再返回,可以直接在 template 模板中使用。
setup語法糖中新增的api
- defineProps:子組件接收父組件中傳來的
props - defineEmits:子組件調(diào)用父組件中的方法
- defineExpose:子組件暴露屬性,可以在父組件中拿到
模塊簡介
本次模塊使用 vue3+element-plus 實現(xiàn)一個新聞站的后臺分類管理模塊,其中新增、編輯采用對話框方式公用一個表單。
分類模塊路由
添加分類模塊的路由
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: "首頁" },
},
// 分類管理
{
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: '/' }">首頁</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="編號" 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="確定要刪除么?"
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、導入 ref
import { fetchCategoryList } from "@/api/categories"; // 6、導入接口 api
import moment from "moment"; // 7、導入 moment 包
import { ElMessage, ElNotification } from "element-plus"; // 9、導入消息通知包
// 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、時間格式化
const formatter = (date) => {
if (!date) {
return "";
}
moment.locale("zh-cn");
return moment(date).format("LL");
};
const handleEdit = (row) => {
console.log(row);
};
// 10、點擊刪除按鈕
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、定義對話框?qū)傩?,默認值為 false
const dialogFormVisible = ref(false);
// 2、定義表單對象和屬性
const form = ref({
name: "",
sort: 0,
});
const formLabelWidth = "140px";
// 3、表單驗證
const ruleFormRef = ref();
const rules = reactive({
name: [
{ required: true, message: "請輸入分類名稱", trigger: "blur" },
{ min: 2, max: 20, message: "長度在 2 ~ 20 位", trigger: "blur" },
],
sort: [
{ required: true, message: "請輸入排序", 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>
.
.
<!--表單對話框-->
<CategoryForm ref="dialogShow" />
</div>
</template>
<script setup>
import CategoryForm from "./components/CategoryForm"; // 導入對話框組件
</script>
ref=“dialogShow”:給表單對話框起別名
3、給新增、編輯按鈕分別綁定事件,點擊后彈出對話框
<el-button type="primary" @click="handleCreate">新增</el-button> <el-button size="small" @click="handleEdit(scope.row)">編輯</el-button>
// 點擊新增按鈕觸發(fā)子組件的 showForm 方法,并傳參 create,代表新增
const dialogShow = ref(null);
const handleCreate = async () => {
dialogShow.value.showForm("create");
};
// 點擊編輯按鈕鈕觸發(fā)子組件的 showForm 方法,并傳參 edit 和編輯所需的 id 值,代表編輯
const handleEdit = async (row) => {
dialogShow.value.showForm("edit", { id: row.id });
};
4、在表單組件中
<script setup>
// 顯示對話框
const showForm = async (type, data) => {
console.log(type);
console.log(data);
}
</script>
測試:此時點擊新增或編輯按鈕,發(fā)現(xiàn)無法觸發(fā) showForm 方法。原因在于我們要在父組件中調(diào)用子組件的方法,需導出子組件的方法后才能調(diào)用
<script setup>
import { defineExpose } from "vue";
defineExpose({
showForm,
});
</script>
此時再次點擊新增或編輯按鈕,發(fā)現(xiàn)已經(jīng)拿到了 type 和 data 的值了。
5、完成新增和編輯的對話框正常顯示
// 定義表單類型的默認值為 create
const formType = ref("create");
// 完成新增和編輯正常對話框顯示
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;
});
}
};
對話框字體顯示
根據(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);
}
}
}
});
};
當新增或編輯表單提交后,新的數(shù)據(jù)要同步渲染到頁面,根據(jù)思路,我們需要調(diào)用父組件的 init 方法即可,所以這里涉及到子組件調(diào)用父組件的方法
修改父組件引用子組件的代碼,增加 @init 事件,綁定 init 方法
<!--表單對話框--> <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語法糖實現(xiàn)分類管理的文章就介紹到這了,更多相關(guān)vue3 setup語法糖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Vue + Axios實現(xiàn)全局Loading自動顯示關(guān)閉效果
在vue項目中,我們通常會使用Axios來與后臺進行數(shù)據(jù)交互,而當我們發(fā)起請求時,常常需要在頁面上顯示一個加載框(Loading),然后等數(shù)據(jù)返回后自動將其隱藏,本文介紹了基于Vue + Axios實現(xiàn)全局Loading自動顯示關(guān)閉效果,需要的朋友可以參考下2024-03-03
詳解Vue基于 Nuxt.js 實現(xiàn)服務端渲染(SSR)
直接使用 Vue 構(gòu)建前端單頁面應用,頁面源碼時只有簡單的幾行 html,這并不利于網(wǎng)站的 SEO,這時候就需要服務端渲染,本篇文章主要介紹了詳解Vue基于 Nuxt.js 實現(xiàn)服務端渲染(SSR),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
Vue動態(tài)生成el-checkbox點擊無法賦值的解決方法
這篇文章主要給大家介紹了關(guān)于Vue動態(tài)生成el-checkbox點擊無法賦值的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-02-02

