一開始我以為的vue3僅僅是改變寫法,去掉datamethodscomputed的位置規範,可以自由地穿插變數、函式的位置。

什麼意思呢?就是在vue2的時候我們會把所有的變數放在data,所有的函式放在methods

但是當你的頁面中有兩個模組,假設是登入和註冊,這樣你的登入和註冊的form參數會一起放在data中,而送出登入和送出註冊的函式會一起放在methods中。

當你要編寫註冊的函式時,會去到data裡面的所有變數裡找到註冊的form來參照,但是data裡面放了很多其他模組的變數啊,要是一多起來就變得很難查找。就像官網自己打臉的這張示意圖XD

那進入vue3後這問題是怎麼被初步解決的呢?

setup(){
// 登入模組
  const loginFormModel = reactive({
    username: '',
    password: '',
  })
  const loginFormLoading = ref(false)
  const handleLogin = () => {
    const params = { ...loginForm }
    request('/login', params)
    // 打登入的api
  }

// 註冊模組
  const registerFormModel = reactive({
    email: '',
    displayName: '',
    password: '',
  })
  const registerFormLoading = ref(false)
  const handleRegister = () => {
    const params = { ...registerForm }
    request('/register', params)
    // 打註冊的api
  }
}

差異整個就出來了XD

登入的變數、方法、有的沒的都放在一起,如果現在寫到登入相關的,就只要在登入那範圍找來找去,就不用像vue2一樣一下子滾到最上面找data,找到後又滾到最下面去改methods


再來假設一個情境就是我們在頁面中要請求數據,通常在vue2是這樣的:

data(){
  return {
    orderList: [],
    currentOrderPage: 1,
    orderLoading: false
  }
}

methods:{
  async handleGetOrderList(params = {}){
    this.orderLoading = true;
    const res = await fetch('/order/getList', params);
    this.orderLoading = false;
    this.data.list = res;
  },
  async handleChangeOrderPage(p){
    await this.handleGetList({p});
    this.data.currentOrderPage = p;
  }
}

created(){
  this.handleGetOrderList();
}

進入vue3後我們可能會改成這樣:

setup(){
  const orderStates = reactive({
    list: [],
    currentPage: 1,
    loading: false
  })
  const handleGetOrderList = async (params={}) => {
    orderStates.loading = true;
    const res = await fetch('/order/getList', params);
    orderStates.loading = false;
    orderStates.list = res;
  }
  const handleChangeOrderPage = async (p) => {
    await handleGetOrderList({p});
    orderStates.currentPage = p;
  }

  onMounted(()=>{
    handleGetOrderList();
  })
}

看起來好像差異不大,但是因為你可能會不只有order一個模組,可能還會有report啊、member啊之類的東西~所以個寫下來就會很大一串。

因此我們還可以他再獨立出去到一個資料夾裡面管理。

新增一個資料夾叫做composables,裡面取名用use開頭的檔名,例如:composables/useOrder.js

import { onMounted, reactive } from "vue";
export default function () {
  const states = reactive({
    list: [],
    currentPage: 1,
    loading: false,
  });
  const handleGetList = async (params = {}) => {
    states.loading = true;
    const res = fetch('/order/getList',params)
    states.loading = false;
    states.list = res;
  };
  const handleChange = async p => {
    // change fetch
    states.currentPage = p;
    handleGetList();
  };
  const handleAdd = async formModel => {
    // add fetch
    handleGetList();
  };
  const handleDelete = async (id) => {
    // delete fetch
    handleGetList();
  };

  onMounted(() => {
    handleGetList();
  });
  return { states, handleGetList, handleChangePage, handleAdd, handleDelete };
}

這樣你在頁面中引入,就會像這樣子:

<template>
  //...
</template>
import useOrder from '@/composables/useOrder';
import useReport from '@/composables/useReport';
import useMember from '@/composables/useMember';

export default {
  setup() {
    const { states:orderStates, handleAdd:handleAddOrder } = useOrder();
    const { states:reportStates, handleAdd:handleAddReport } = useReport();
    const { states:memberStates, handleAdd:handleAddMember } = useMember();

    return { 
      orderStates,
      reportStates, 
      memberStates, 
      handleAddOrder,
      handleAddReport,
      handleAddMember 
    }
  }
}

這樣你在裡面的loading狀態、頁碼狀態都會跟著你設計的模組改變,是不是變得很簡單清爽呀。

這就有點像是物件導向的感覺,每個模組有自己的增刪查改、loading狀態之類的,互不干涉,又可以在同個畫面取用。

1+
0 回復

發表評論

想要加入討論嗎?
請盡情發表您的想法!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。