溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用vue3+ts實(shí)現(xiàn)管理后臺(tái)

發(fā)布時(shí)間:2020-11-02 15:46:19 來源:億速云 閱讀:321 作者:Leah 欄目:開發(fā)技術(shù)

使用vue3+ts實(shí)現(xiàn)管理后臺(tái)?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

利用@vue/cli創(chuàng)建項(xiàng)目

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

vue create admin
cd admin
npm run serve

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

我們利用axios + axios-mock-adapter + mockjs來進(jìn)行接口請(qǐng)求、接口模擬及假數(shù)據(jù)生成,接下來再安裝這幾個(gè)包。

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

項(xiàng)目整體框架

假設(shè)我們的項(xiàng)目包含一個(gè) Header,Header 的作用是切換頁面。兩個(gè)頁面,分別為 List 和 About,這兩個(gè)頁面都是簡(jiǎn)單的列表+增刪改查的操作。

路由

需要在 router 中增加一個(gè) 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'); },
 },
];

列表頁

首先把列表頁的結(jié)構(gòu)寫出來,List 和 About 的結(jié)構(gòu)大體相似。

<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 &#63; '男' : '女'}}</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這幾個(gè)方法,每個(gè)列表頁的這幾個(gè)方法功能都是相同的,唯一的不同就是請(qǐng)求的 API,我們可以將這幾個(gè) API 做為參數(shù),將增刪改查的方法提取到setup函數(shù)中,做到復(fù)用。接下來就來到重點(diǎn)的composition API。

composition API具體實(shí)現(xiàn)

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 &#63; 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,
    birth: item.birth,
    address: item.address,
   });
  };
  const localPageData = compositionApi(fetchApi, deleteApi, confirmAddApi, confirmEditApi, state.itemData);
  return {
   state,
   ...localPageData,
  };
 },
 data() {
  return {
   thead: [
    'id',
    'name',
    'sex',
    'birth',
    'address',
    'option',
   ],
  };
 }
});

這樣 List 頁面的邏輯基本上就完成了。同樣,About 頁面的邏輯也就完成了,不同的就是在 About 頁面更改一下接口請(qǐng)求的地址。

最終實(shí)現(xiàn)效果

使用vue3+ts實(shí)現(xiàn)管理后臺(tái)

composition API vs Mixin

在vue3之前,代碼復(fù)用的話一般都是用mixin,但是mixin相比于composition API的劣勢(shì),在官網(wǎng)中的解釋如下:

  • mixin很容易發(fā)生沖突:因?yàn)槊總€(gè)特性的屬性都被合并到同一個(gè)組件中,所以為了避免 property名沖突和調(diào)試,你仍然需要了解其他每個(gè)特性。
  • 可重用性是有限的:我們不能向mixin傳遞任何參數(shù)來改變它的邏輯,這降低了它們?cè)诔橄筮壿嫹矫娴撵`活性

關(guān)于使用vue3+ts實(shí)現(xiàn)管理后臺(tái)問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI