1. 程式人生 > 程式設計 >利用vue3+ts實現管理後臺(增刪改查)

利用vue3+ts實現管理後臺(增刪改查)

簡單的管理後臺基本上就是資料的增刪改查。主要就是 列表 + form 表單。每個頁面的邏輯基本上都相同。不同的地方就是每個頁面需要呼叫的具體 API 及引數。

以前 vue2 的時候最簡單的做法是寫出來一個頁面的邏輯,然後直接 copy 到各個頁面中,修改 API 及引數即可。高階一點的是利用 mixin 函式,將可複用邏輯抽離,每個頁面引入 mixin。

vue3 之後新增了composition API。本文就是利用composition API,將可複用的邏輯抽離到composition API中,並引入ts,實現一個簡單的管理後臺功能。

利用@vue/cli建立專案

首先需要將 @vue/cli 升級到最新版。本文用的是4.5.6版本。

vue create admin
cd admin
npm run serve

create選擇手動選擇Manually select features,會有一些互動性的選擇,是否要安裝router、vuex等選項,空格可以切換是否選中。我們選中TypeScript、Router、Vuex、CSS Pre-processors。

我們利用axios + axios-mock-adapter + mockjs來進行介面請求、介面模擬及假資料生成,接下來再安裝這幾個包。

npm install axios
npm install -D axios-mock-adapter mockjs

專案整體框架

假設我們的專案包含一個 Header,Header 的作用是切換頁面。兩個頁面,分別為 List 和 About,這兩個頁面都是簡單的列表+增刪改查的操作。

路由

需要在 router 中增加一個 list 的路由資訊。

const routes: Array<RouteRecordRaw> = [
 {
  path: '/',name: 'Home',component: Home,},{
  path: '/about',name: 'About',component: () => { return import(/* webpackChunkName: "about" */ '../views/About.vue'); },{
  path: '/list',name: 'List',component: () => { return import(/* webpackChunkName: "list" */ '../views/List.vue'); },];

列表頁

首先把列表頁的結構寫出來,List 和 About 的結構大體相似。

<template>
  <div class='content_page'>
    <div class='content_body'>
      <div class='content_button'>
        <button class='add primary' @click='addItem' title='新增'>新增</button>
      </div>
      <div class='content_table'>
        <table>
          <thead>
            <tr>
              <th v-for='item in thead' :key='item'>{{item}}</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for='(item,index) in list' :key='item.id'>
              <td>
                <span :title='item.id'>{{item.id}}</span>
              </td>
              <td>
                <div v-if='index === currentIndex'>
                  <input
                    v-model='item.name'
                    title='name'
                  />
                </div>
                <span :title='item.name' v-else>{{item.name}}</span>
              </td>
              <td :title='item.sex'>
               <div v-if='index === currentIndex'>
                  <input
                    v-model='item.sex'
                    title='sex'
                  />
                </div>
                <span :title='item.sex' v-else>{{item.sex ? '男' : '女'}}</span>
              </td>
              <td :title='item.birth'>
               <div v-if='index === currentIndex'>
                  <input
                    v-model='item.birth'
                    title='birth'
                  />
                </div>
                <span :title='item.birth' v-else>{{item.birth}}</span></td>
              <td :title='item.address'>
               <div v-if='index === currentIndex'>
                 <input
                   v-model='item.address'
                   title='birth'
                 />
               </div>
               <span :title='item.address' v-else>{{item.address}}</span>
              </td>
              <td>
                <div v-if='index === currentIndex'>
                  <button
                    class='primary confirm'
                    @click='confirm(item)'
                  >確定</button>
                  <button
                    @click='cancel(item)'
                  >取消</button>
                </div>
                <span v-else>
                  <span @click='editItem(index)'>
                    edit
                  </span>
                  <span @click='deleteItem(index,item)'>delete</span>
                </span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

其中用到了addItem、editItem、deleteItem、confirm、cancel這幾個方法,每個列表頁的這幾個方法功能都是相同的,唯一的不同就是請求的 API,我們可以將這幾個 API 做為引數,將增刪改查的方法提取到setup函式中,做到複用。接下來就來到重點的composition API。

composition API具體實現

import { ref,onMounted } from 'vue';
import {ItemType,FetchType,DeleteType,AddType,EditType} from '../../types/index';

export const compositionApi = (
 fetchApi: FetchType,deleteApi: DeleteType,confirmAddApi: AddType,confirmEditApi: EditType,itemData: ItemType,) => {
 const currentIndex = ref<number | null>(null);
 const list = ref([{}]);
 const getList = () => {
  fetchApi().then((res: any) => {
   list.value = res.data.list;
  });
 };
 const addItem = () => {
  list.value.unshift(itemData);
  currentIndex.value = 0;
 };
 const editItem = (index: number) => {
  currentIndex.value = index;
 };
 const deleteItem = (index: number,item: ItemType) => {
  deleteApi(item).then(() => {
   list.value.splice(index,1);
  //  getList();
  });
 };
 const cancel = (item: ItemType) => {
  currentIndex.value = null;
  if (!item.id) {
   list.value.splice(0,1);
  }
 };
 const confirm = (item: ItemType) => {
  const api = item.id ? confirmEditApi : confirmAddApi;
  api(item).then(() => {
   getList();
   cancel(item);
  });
 };
 onMounted(() => {
  getList();
 });
 return {
  list,currentIndex,getList,addItem,editItem,deleteItem,cancel,confirm,};
};

export default compositionApi;

接下來就是在 List 和 About 頁面中的setup方法中引入即可。

<script lang='ts'>
import axios from 'axios';
import { defineComponent,reactive } from 'vue';
import { compositionApi } from '../components/composables/index';
import {ItemType} from '../types/index';

const ListComponent = defineComponent({
 name: 'List',setup() {
  const state = reactive({
   itemData: {
    id: '',name: '',sex: 0,birth: '',address: '',});
  const fetchApi = () => {
   return axios.get('/users');
  };
  const deleteApi = (item: ItemType) => {
   return axios.post('/users/delete',{ id: item.id });
  };
  const confirmAddApi = (item: ItemType) => {
   return axios.post('/users/add',{ 
    name: item.name,birth: item.birth,address: item.address,});
  };
  const confirmEditApi = (item: ItemType) => {
   return axios.post('/users/edit',{
    id: item.id,name: item.name,});
  };
  const localPageData = compositionApi(fetchApi,deleteApi,confirmAddApi,confirmEditApi,state.itemData);
  return {
   state,...localPageData,};
 },data() {
  return {
   thead: [
    'id','name','sex','birth','address','option',],};
 }
});

這樣 List 頁面的邏輯基本上就完成了。同樣,About 頁面的邏輯也就完成了,不同的就是在 About 頁面更改一下介面請求的地址。

最終實現效果

利用vue3+ts實現管理後臺(增刪改查)

composition API vs Mixin

在vue3之前,程式碼複用的話一般都是用mixin,但是mixin相比於composition API的劣勢,在官網中的解釋如下:

  • mixin很容易發生衝突:因為每個特性的屬性都被合併到同一個元件中,所以為了避免 property名衝突和除錯,你仍然需要了解其他每個特性。
  • 可重用性是有限的:我們不能向mixin傳遞任何引數來改變它的邏輯,這降低了它們在抽象邏輯方面的靈活性

原始碼

專案中用到的一些 TS 介面的定義、模擬資料及介面請求本文中沒有具體介紹,如果想了解的話可以去看看原始碼。

戳這裡:vue3_ts_admin

到此這篇關於利用vue3+ts實現管理後臺(增刪改查)的文章就介紹到這了,更多相關vue3 TypeScript 管理後臺內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!