日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

一个简单案例教你如何用Typescript写Vuex

發布時間:2025/5/22 170 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个简单案例教你如何用Typescript写Vuex 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

案例源代碼: github.com/danielhuoo/…

前言

相信很多人都像我一樣,學習使用了vuex后,想把項目改寫成Typescript。但是官方教程要么晦澀難懂,要么缺少鮮活的例子。我花了一天時間,總結出了一些經驗。在此分享出來。

本教程通過編寫一個簡單的demo講解vuex的實現方式,以及如何對基于vue2.x的已有項目進行Typescript重構。

項目初始化

現在都9012了,所以我們直接使用vue-cli 3.x快速搭建系統。

# 搭建項目 vue create vue2.x-vuex-typescript-democd vue2.x-vuex-typescript-demo # 引入vuex vue add vuex # 由于我實在不想寫任何樣式,所以我又加一個element vue add element 復制代碼

模塊說明

為了用實際的代碼解釋vuex是如何搭建的,以及模塊間的通訊方式,我用了一個很淺顯的例子(應該比官方的例子明朗很多)

情景

男孩給女孩送花。

  • 男孩每送出10朵花,女孩會表達感謝。
  • 女孩的感謝會增加男孩的勇氣值。
  • 男孩可以向花店買花。
  • 目錄結構

    你會發現默認的目錄結構是這樣的:

    . ├── README.md ├── babel.config.js ├── package.json ├── public │?? ├── favicon.ico │?? └── index.html ├── src │?? ├── App.vue │?? ├── assets │?? │?? └── logo.png │?? ├── components │?? │?? └── HelloWorld.vue │?? ├── main.js │?? ├── plugins │?? │?? └── element.js │?? └── store.js └── yarn.lock

    但是我們想讓vuex變得模塊化。所以我們改成以下的結構:

    . ├── README.md ├── babel.config.js ├── package.json ├── public │?? ├── favicon.ico │?? └── index.html ├── src │?? ├── App.vue │?? ├── assets │?? │?? └── logo.png │?? ├── components │?? │?? └── HelloWorld.vue │?? ├── main.js │?? ├── plugins │?? │?? └── element.js │?? └── store │?? ├── index.js │?? └── module │?? ├── boy.js │?? └── girl.js └── yarn.lock
  • index.js 是store的主文件
  • /module 下存放模塊文件。 boy.js 是男孩模塊,girl.js 是女孩模塊
  • 模塊定義

    boy.js

    該模塊定義了三個action方法。action通俗來說就是你想讓模塊做的事情,它們可以是異步或者同步的。所有對state的增刪查改的邏輯都應該在這里,而mutation僅僅負責執行增刪查改。

    import { Message } from 'element-ui'; export default {namespaced: true,// state 的屬性只能通過 mutation的方法進行修改state: {currentFlower: 50,braveScore: 0},mutations: {// 修改 state 的 currentFlower 的值updateCurrentFlower(state, payload) {state.currentFlower = state.currentFlower + payload},// 修改 state 的 braveScore 的值updateBraveScore(state, payload) {state.braveScore = state.braveScore + payload.score}},actions: {// 送花// 方法里 調用了 commit 和 state,需要在傳參時聲明sendFlower({ commit, state }, params) {if (!state.currentFlower) {Message({showClose: true,message: "沒花可送了",type: "warning"});} else {// 送出一朵花,自己的庫存減 1commit('updateCurrentFlower', -params.sendNumber)// 女孩收到一朵花,女孩庫存加 1。// 注意這里是跨模塊調用,所以需要加上模塊前綴 'girl/',并且 傳入參數 {root:true} 表明通過根路徑尋找目標函數。commit('girl/updateCurrentFlower', params.sendNumber, { root: true })}},// 受到鼓勵beEncouraged({ commit }) {commit('updateBraveScore', { score: 10 })},// 買花// 方法里調用了 commit, dispatch。 dispatch跨模塊調用根store的action,跟送花的commit一樣,需要加上前綴和傳入{root:true}buyFlower({ commit, dispatch }, params) {setTimeout(() => {dispatch('sellFlower', null, { root: true }).then(() => {commit('updateCurrentFlower', params.buyNumber)}).catch(() => {Message({showClose: true,message: "庫存不足",type: "warning"});})}, 100)}} } 復制代碼

    girl.js

    export default {namespaced: true,state: {currentFlower: 0},mutations: {updateCurrentFlower(state, payload) {state.currentFlower = state.currentFlower + payload}},actions: {// 對男孩進行鼓舞encourage({ dispatch }, params) {dispatch('boy/beEncouraged', null, { root: true })}} } 復制代碼

    index.js

    import Vue from 'vue' import Vuex from 'vuex' // 引入模塊 import boy from './module/boy' import girl from './module/girl' Vue.use(Vuex)export default new Vuex.Store({// 根 statestate: {flowersInStock: 10},// 根 mutationsmutations: {updateFlowersInStock(state, payload) {state.flowersInStock = state.flowersInStock + payload}},// 根 actionsactions: {sellFlower({ commit, state }, params) {return new Promise((resolve, reject) => {if (state.flowersInStock > 0) {commit('updateFlowersInStock', -1)resolve()} else {reject()}})}},// 注冊模塊modules: {boy,girl} }) 復制代碼

    連接到vue組件

    現在倉庫的邏輯已經寫好了,我們就可以在組件上使用了。實際上vuex倉庫早在main.js被引入了vue實例里了。例如,this.$store.state.flowersInStock即代表根state的屬性值。但是這種寫法太過繁瑣,我們引入了vuex提供的 mapState、mapActions 和 mapMutations 進行映射。

    boy.vue

    <template><div><div>男孩</div><div>手上有{{currentFlower}}朵花</div><div><el-button @click="sendFlower({sendNumber:1})">送花</el-button><el-button @click="buyFlower({buyNumber:1})">買花</el-button></div><div>勇氣值:{{braveScore}}</div></div> </template> <script> import { mapState, mapActions } from "vuex"; export default {computed: {// 你會發現state的映射放在了computed里面。這么做的好處是由于 Vuex 的狀態存儲是響應式的,從 store 實例中讀取狀態最簡單的方法就是在計算屬性中返回某個狀態。// 通過映射,this.$store.state.currentFlower 就可以表示為 this.currentFlower...mapState("boy", {currentFlower: state => state.currentFlower,braveScore: state => state.braveScore})},methods: {// actions 放在了methods里面。這不奇怪,因為actions跟mutations一樣,都是vuex里面的方法。...mapActions("boy", ["sendFlower", "buyFlower"])} }; </script> <style> </style> 復制代碼

    很多人在剛開始用vuex都會記不住,究竟state、actions和mutations放哪里。其實很好記:

    • state是屬性,放computed里。
    • actions和mutations是方法,放methods里。

    girl.vue 同理,就不贅述了。下一步,我們開始用Typescript改寫代碼。

    安裝Typescript

    在安裝之前,請一定要先做備份。因為安裝后App.vue會被改寫。

    yarn add vuex-class vue add typescript ? Use class-style component syntax? (Y/n) Yes ? Use Babel alongside TypeScript for auto-detected polyfills? (Y/n) Yes 復制代碼

    改寫開始

    你會發現所有.js文件都被改成.ts后綴了。這時候整個項目是跑不起來的。命令行控制臺會爆出幾十個error。事實上,在你沒有把所有該改的地方改好之前,項目是不會跑通的。

    index.ts

    被改寫的地方:

    • 引入module的方式。改為import對象中的一個屬性
    • 定義了store的類別。
    • 新增了一個RootState。
    import Vue from 'vue' import Vuex, { StoreOptions } from 'vuex' import { boy } from './module/boy' import { girl } from './module/girl' import { RootState } from './root-types'; Vue.use(Vuex) const store: StoreOptions<RootState> = {// 里面的內容不用修改state: {flowersInStock: 10},modules: {boy,girl},mutations: {updateFlowersInStock(state, payload) {state.flowersInStock = state.flowersInStock + payload}},actions: {sellFlower({ commit, state }) {return new Promise((resolve, reject) => {if (state.flowersInStock > 0) {commit('updateFlowersInStock', -1)resolve()} else {reject()}})}} } export default new Vuex.Store<RootState>(store) 復制代碼

    root-types.ts

    這是對根state的約束

    export interface RootState {flowersInStock: number } 復制代碼

    boy.ts

    模塊的改動是巨大的。

    • 新增了模塊的State接口
    • 定義mutations的類為 MutationTree
    • 定義actions的類為 ActionTree
    • 定義模塊的類為 Module
    import { Message } from 'element-ui'; import { BoyState } from './module-types'; import { MutationTree, ActionTree, Module } from 'vuex'; import { RootState } from '../root-types'; const state: BoyState = {currentFlower: 50,braveScore: 0 }// 傳入的泛型可以通過查看源代碼得知。 const mutations: MutationTree<BoyState> = {updateCurrentFlower(state, payload) {state.currentFlower = state.currentFlower + payload},updateBraveScore(state, payload) {state.braveScore = state.braveScore + payload.score} } const actions: ActionTree<BoyState, RootState> = {sendFlower({ commit, state }, params) {if (!state.currentFlower) {Message({showClose: true,message: "沒花可送了",type: "warning"});} else {commit('updateCurrentFlower', -params.sendNumber)commit('girl/updateCurrentFlower', params.sendNumber, { root: true })}},buyFlower({ commit, dispatch }, params) {setTimeout(() => {dispatch('sellFlower', null, { root: true }).then(() => {commit('updateCurrentFlower', params.buyNumber)}).catch(() => {Message({showClose: true,message: "庫存不足",type: "warning"});})}, 100)},beEncouraged({ commit }) {commit('updateBraveScore', { score: 10 })} } export const boy: Module<BoyState, RootState> = {namespaced: true,state,mutations,actions } 復制代碼

    boy.vue

    vue文件改動的地方也是很多的:

    • script標簽指定了ts語言
    • 使用Component修飾組件
    • export 組件 從 對象變為 類
    • 棄用 mapState 等方法,使用 State、Action、Mutation 修飾器綁定 vuex
    • 棄用computed、methods、data 等寫法,使用get + 方法表示 computed,methods里的方法直接被抽出來,data的屬性直接被抽出來。
    <script lang="ts"> import { Vue, Component, Watch } from "vue-property-decorator"; import { State, Action, Mutation, namespace } from "vuex-class"; import { BoyState } from "../store/module/module-types"; @Component export default class boyComponent extends Vue {@State("boy") // 感嘆號不能省略boyState!: BoyState;@Action("sendFlower", { namespace: "boy" })sendFlower: any;@Action("buyFlower", { namespace: "boy" })buyFlower: any;get currentFlower(): number {return this.boyState.currentFlower;}get braveScore(): number {return this.boyState.braveScore;} } </script> 復制代碼

    其他文件也是用類似的方法去改寫。換湯不換藥。

    以上就是Typescript改寫的例子。有些地方沒有解釋得很清楚,因為我也是一個小白啊,不懂的地方還是不要誤導大家了。如果你的項目的邏輯比這個更復雜(肯定吧),而本項目沒有覆蓋到你的疑惑,你可以去看我的另一個改好的項目Jessic。

    • 作者:Daniel Huo
    • 鏈接:danielhuoo.github.io/2019/06/18/…
    • 著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

    轉載于:https://juejin.im/post/5d09682d518825531e0648a7

    總結

    以上是生活随笔為你收集整理的一个简单案例教你如何用Typescript写Vuex的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。