vue3?使用setup語(yǔ)法糖實(shí)現(xiàn)分類(lèi)管理功能
setup語(yǔ)法糖簡(jiǎn)介
直接在 script
標(biāo)簽中添加 setup
屬性就可以直接使用 setup
語(yǔ)法糖了。
使用 setup
語(yǔ)法糖后,不用寫(xiě) 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)分類(lèi)管理模塊,其中新增、編輯采用對(duì)話(huà)框方式公用一個(gè)表單。
分類(lèi)模塊路由
添加分類(lèi)模塊的路由
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è)" }, }, // 分類(lèi)管理 { path: "/categories", component: () => import("@/views/categories/ListView"), meta: { title: "分類(lèi)列表" }, }, ], }, ]; const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes, }); export default router;
分類(lèi)列表組件
在 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>分類(lèi)列表</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="名稱(chēng)" 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>
獲取分類(lèi)列表數(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、定義分類(lèi)列表數(shù)組 const categories = ref([]); // 1、獲取分類(lèi)列表數(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>
分類(lèi)表單組件
1、新建 src/views/categories/components/CategoryForm.vue
<template> <el-dialog v-model="dialogFormVisible" title="新增分類(lèi)"> <el-form :model="form" :rules="rules" ref="ruleFormRef"> <el-form-item label="名稱(chēng)" :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ì)話(huà)框?qū)傩?,默認(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)輸入分類(lèi)名稱(chē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ì)話(huà)框--> <CategoryForm ref="dialogShow" /> </div> </template> <script setup> import CategoryForm from "./components/CategoryForm"; // 導(dǎo)入對(duì)話(huà)框組件 </script>
ref=“dialogShow”:給表單對(duì)話(huà)框起別名
3、給新增、編輯按鈕分別綁定事件,點(diǎn)擊后彈出對(duì)話(huà)框
<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ì)話(huà)框 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ì)話(huà)框正常顯示
// 定義表單類(lèi)型的默認(rèn)值為 create const formType = ref("create"); // 完成新增和編輯正常對(duì)話(huà)框顯示 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ì)話(huà)框字體顯示
根據(jù) formType
的值判斷顯示新增或編輯
<template> <el-dialog v-model="dialogFormVisible" :title="formType == 'create' ? '新增分類(lèi)' : '編輯分類(lèi)'" > <el-form :model="form" :rules="rules" ref="ruleFormRef"> <el-form-item label="名稱(chēng)" :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ì)話(huà)框--> <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)分類(lèi)管理的文章就介紹到這了,更多相關(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-04vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例
這篇文章主要介紹了vue3利用store實(shí)現(xiàn)記錄滾動(dòng)位置的示例,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下2021-04-04vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決
這篇文章主要介紹了vue3.0 vant popup渲染不出來(lái)問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01vue實(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-03Vue中渲染系統(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-04Vue鼠標(biāo)點(diǎn)擊事件和鍵盤(pán)事件舉例詳解
在Vue框架中我們經(jīng)常需要綁定各種JS事件,如"點(diǎn)擊事件"、"鼠標(biāo)移動(dòng)事件"、"鍵盤(pán)事件"等等,這篇文章主要給大家介紹了關(guān)于Vue鼠標(biāo)點(diǎn)擊事件和鍵盤(pán)事件的相關(guān)資料,需要的朋友可以參考下2024-01-01Vue動(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