vue3?使用setup語法糖實現(xiàn)分類管理功能
setup語法糖簡介
直接在 script
標簽中添加 setup
屬性就可以直接使用 setup
語法糖了。
使用 setup
語法糖后,不用寫 setup
函數,組件只需要引入不需要注冊,屬性和方法也不需要再返回,可以直接在 template
模板中使用。
setup語法糖中新增的api
- defineProps:子組件接收父組件中傳來的
props
- defineEmits:子組件調用父組件中的方法
- 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>內容管理</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>
獲取分類列表數據
<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、定義分類列表數組 const categories = ref([]); // 1、獲取分類列表數據 const init = async () => { const res = await fetchCategoryList(); // 3、賦值 categories.value = res.data.categories; }; // 2、調用 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、定義對話框屬性,默認值為 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: "排序必須為數字值" }, ], }); // 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 方法。原因在于我們要在父組件中調用子組件的方法,需導出子組件的方法后才能調用
<script setup> import { defineExpose } from "vue"; defineExpose({ showForm, }); </script>
此時再次點擊新增或編輯按鈕,發(fā)現(xiàn)已經拿到了 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; }); } };
對話框字體顯示
根據 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); } } } }); };
當新增或編輯表單提交后,新的數據要同步渲染到頁面,根據思路,我們需要調用父組件的 init
方法即可,所以這里涉及到子組件調用父組件的方法
修改父組件引用子組件的代碼,增加 @init
事件,綁定 init
方法
<!--表單對話框--> <CategoryForm ref="dialogShow" @init="init" />
在子組件中調用,注意注釋中的代碼
// 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"); // 調用 init } } catch (e) { if (e.Error) { ElMessage.error(e.Error); } } } }); };
到此這篇關于vue3 使用setup語法糖實現(xiàn)分類管理的文章就介紹到這了,更多相關vue3 setup語法糖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Vue + Axios實現(xiàn)全局Loading自動顯示關閉效果
在vue項目中,我們通常會使用Axios來與后臺進行數據交互,而當我們發(fā)起請求時,常常需要在頁面上顯示一個加載框(Loading),然后等數據返回后自動將其隱藏,本文介紹了基于Vue + Axios實現(xiàn)全局Loading自動顯示關閉效果,需要的朋友可以參考下2024-03-03詳解Vue基于 Nuxt.js 實現(xiàn)服務端渲染(SSR)
直接使用 Vue 構建前端單頁面應用,頁面源碼時只有簡單的幾行 html,這并不利于網站的 SEO,這時候就需要服務端渲染,本篇文章主要介紹了詳解Vue基于 Nuxt.js 實現(xiàn)服務端渲染(SSR),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04Vue動態(tài)生成el-checkbox點擊無法賦值的解決方法
這篇文章主要給大家介紹了關于Vue動態(tài)生成el-checkbox點擊無法賦值的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-02-02