淺析Vue3中的邏輯復用
使用了 Vue3 Composables 之后,邏輯復用比之前要順手很多,這里說說前端開發(fā)最常用的場景,管理頁面的列表查詢和增刪改查的邏輯復用,歡迎大家共同探討。
用免費的 render 服務(wù)搭建了個在線的預覽地址,源碼在這里,用了免費的 node 環(huán)境和免費的 pg 數(shù)據(jù)庫,對這部分有興趣的可以看看我以前的分享,我寫了個部署 spring-boot 的分享,使用 node 就更簡單了。
可能每個人的具體工作內(nèi)容不一致,但是應該都完成過這樣的工作內(nèi)容:
- 列表查詢,帶分頁和過濾條件
- 新增,修改,查看,刪除
- 進行一些快捷操作,比如:激活、通過
這些最基礎(chǔ)的工作可能占用了我們很大的時間和精力,下面來討論下如何邏輯復用,提高工作效率
需求分析
一個后臺管理中心,絕大部分都是這種管理頁面,那么需要:
- 首先是封裝一些通用的組件,這樣代碼量最低也容易保持操作邏輯和 UI 的一致性
- 其次要封裝一些邏輯復用,比如進入頁面就要進行一次列表查詢,翻頁的時候需要重新查詢
- 最后需要有一些定制化的能力,最基本的列需要自定義,頁面的過濾條件和操作也不一樣
統(tǒng)一復用
- 發(fā)起 http 請求
- 展示后端接口返回的信息,有成功或者參數(shù)校驗失敗等信息
列表的查詢過程
- 頁面加載后的首次列表查詢
- 頁面 loading 狀態(tài)的維護
- 翻頁的邏輯和翻頁后的列表重新查詢
- 過濾條件和模糊搜索的邏輯,還有對應的列表重新查詢
新增 Item、查詢 Item、修改 Item
- form 在提交過程的禁用狀態(tài)
- 發(fā)起網(wǎng)絡(luò)請求
- 后端接口返回的信息提示
- 列表重新查詢
刪除 Item
- 刪除按鈕狀態(tài)的維護(需要至少一個選中刪除按鈕才可用)
- 發(fā)起網(wǎng)絡(luò)請求
- 后端接口返回的信息提示
- 列表重新查詢
定制化的內(nèi)容
- table 的列數(shù)據(jù)
- item 的屬性,也就是具體的表單
- 快捷操作:改變 user 激活狀態(tài)
- 列表的過濾條件
成果展示
- 打開頁面會進行一次列表查詢
- 翻頁或者調(diào)整頁面數(shù)量,會進行一次列表查詢
- 右上角的是否激活篩選狀態(tài)變更會進行一次列表查詢
- 右上角模糊搜索,輸入內(nèi)容點擊搜索按鈕會進行一次列表查詢
- 點擊左上角的新增,彈出表單對話框,進行 item 的新增
- 點擊操作的“編輯”按鈕,彈出表單對話框,對點擊的 item 進行編輯
- 點擊“改變狀態(tài)”按鈕,彈出確認框,改變 user 的激活狀態(tài)
- 選中列表的 checkbox,可以進行刪除
代碼直接貼在下面了,使用邏輯復用完成以上的內(nèi)容一共 200 多行,大部分是各種縮進,可以輕松閱讀,還寫了一個 Work 的管理,也很簡單,證明這套東西復用起來沒有任何難度。
<template> <div class="user-mgmt"> <biz-table :operations="operations" :filters="filters" :loading="loading" :columns="columns" :data="tableData" :pagination="pagination" :row-key="rowKey" :checked-row-keys="checkedRowKeys" @operate="onOperate" @filter-change="onFilterChange" @update:checked-row-keys="onCheckedRow" @update:page="onUpdatePage" @update:page-size="onUpdatePageSize" /> <user-item :show="showModel" :item-id="itemId" @model-show-change="onModelShowChange" @refresh-list="queryList" /> </div> </template> <script setup name="user-mgmt"> import { h, ref, computed } from 'vue'; import urls from '@/common/urls'; import dayjs from 'dayjs'; import { NButton } from 'naive-ui'; import BizTable from '@/components/table/BizTable.vue'; import UserItem from './UserItem.vue'; import useQueryList from '@/composables/useQueryList'; import useDeleteList from '@/composables/useDeleteList'; import useChangeUserActiveState from './useChangeUserActiveState'; // 自定義列數(shù)據(jù) const columns = [ { type: 'selection' }, { title: '姓', key: 'firstName' }, { title: '名', key: 'lastName' }, { title: '是否激活', key: 'isActive', render(row) { return row.isActive ? '已激活' : '未激活'; } }, { title: '創(chuàng)建時間', key: 'createdAt' }, { title: '更新時間', key: 'updatedAt' }, { title: '操作', key: 'actions', render(row) { return [ h( NButton, { size: 'small', onClick: () => onEdit(row), style: { marginRight: '5px' } }, { default: () => '編輯' } ), h( NButton, { size: 'small', onClick: () => onChangeUserActiveState(row), style: { marginRight: '5px' } }, { default: () => '改變狀態(tài)' } ) ]; } } ]; // 自定義右上角篩選 const filters = ref([ { label: '是否激活', type: 'select', value: '0', class: 'filter-select', options: [ { label: '全部', value: '0' }, { label: '已激活', value: '1' }, { label: '未激活', value: '2' } ] }, { label: '', type: 'input', placeholder: '請輸入姓氏', value: '' } ]); // 篩選變化,需要重新查詢列表 const onFilterChange = ({ index, type, value }) => { filters.value[index].value = value; queryList(); }; // 自定義查詢列表參數(shù) const parmas = computed(() => { return { isActive: filters.value[0].value, like: filters.value[1].value }; }); // 封裝好的查詢列表方法和返回的數(shù)據(jù) const { data, loading, pagination, onUpdatePage, onUpdatePageSize, queryList } = useQueryList(urls.user.user, parmas); // 經(jīng)過處理的列表數(shù)據(jù),用于在 table 中展示 const tableData = computed(() => data.value.list.map(item => { return { ...item, createdAt: dayjs(item.createdAt).format('YYYY-MM-DD HH:mm:ss'), updatedAt: dayjs(item.updatedAt).format('YYYY-MM-DD HH:mm:ss') }; }) ); // 刪除列表相關(guān)邏輯封裝 const { checkedRowKeys, onCheckedRow, deleteList } = useDeleteList({ content: '確定刪除選中的用戶?', url: urls.user.userDelete, callback: () => { queryList(); } }); // 列表中的快捷操作 const operations = computed(() => { return [ { name: 'create', label: '新增', type: 'primary' }, { name: 'delete', label: '刪除', disabled: checkedRowKeys.value.length === 0 } ]; }); // 觸發(fā)操作函數(shù) const onOperate = function (name) { operationFucs.get(name)(); }; // 新創(chuàng)建 item const create = () => { showModel.value = true; itemId.value = 0; }; const onModelShowChange = () => { showModel.value = !showModel.value; }; const itemId = ref(0); // 控制模態(tài)對話框 const showModel = ref(false); // 編輯 item const onEdit = row => { itemId.value = row.id; showModel.value = true; }; const { changeUserActiveState } = useChangeUserActiveState(); // 改變激活狀態(tài) const onChangeUserActiveState = row => { changeUserActiveState({ id: row.id, isActive: !row.isActive, loading, callback: () => { queryList(); } }); }; // 指定 table 的 rowKey const rowKey = row => row['id']; // operation 函數(shù)集合 const operationFucs = new Map(); operationFucs.set('create', create); operationFucs.set('delete', deleteList); </script> <style lang="scss"> .user-mgmt { height: 100%; .filter-select { .biz-select { width: 100px; } } } </style>
以上就是淺析Vue3中的邏輯復用的詳細內(nèi)容,更多關(guān)于Vue邏輯復用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
elementUI使用el-upload上傳文件寫法及避坑總結(jié)(上傳圖片/視頻到本地/服務(wù)器及回顯+刪除)
upload上傳是前端開發(fā)很常用的一個功能,下面這篇文章主要給大家介紹了關(guān)于elementUI使用el-upload上傳文件寫法及避坑的相關(guān)資料,包括上傳圖片/視頻到本地/服務(wù)器及回顯+刪除,需要的朋友可以參考下2023-03-03一步步從Vue3.x源碼上理解ref和reactive的區(qū)別
vue3的數(shù)據(jù)雙向綁定,大家都明白是proxy數(shù)據(jù)代理,但是在定義響應式數(shù)據(jù)的時候,有ref和reactive兩種方式,如果判斷該使用什么方式,是大家一直不很清楚地問題,下面這篇文章主要給大家介紹了關(guān)于從Vue3.x源碼上理解ref和reactive的區(qū)別的相關(guān)資料,需要的朋友可以參考下2023-02-02vue 框架下自定義滾動條(easyscroll)實現(xiàn)方法
這篇文章主要介紹了vue 框架下自定義滾動條(easyscroll)實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08Vue中調(diào)用組件使用kebab-case短橫線命名法和使用大駝峰的區(qū)別詳解
這篇文章主要介紹了Vue中調(diào)用組件使用kebab-case(短橫線)命名法和使用大駝峰的區(qū)別,通過實例可以看出如果是在html中使用組件,那么就不能用大駝峰式寫法,如果是在.vue?文件中就可以,需要的朋友可以參考下2023-10-10vue?button的@click方法無效鉤子函數(shù)沒有執(zhí)行問題
這篇文章主要介紹了vue?button的@click方法無效鉤子函數(shù)沒有執(zhí)行問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03vue+elementUI實現(xiàn)表格關(guān)鍵字篩選高亮
這篇文章主要為大家詳細介紹了vue+elementUI實現(xiàn)表格關(guān)鍵字篩選高亮,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05