簡単な例としては、活字体でVuexを作成する方法を教えるために

ケース出典:github.com/danielhuoo / ...

序文

私は、私のような多くの人が、使用することを学ぶと信じてvuexプロジェクトを書き換えしようとすると、ポストをTypescriptしかし、公式のチュートリアルでは、どちらかはっきりしないか、鮮やかな例を欠いています。私はいくつかの経験を総括し、一日を過ごしました。この中で出て共有します。

説明するために、簡単なデモを書き込むことにより、このチュートリアルvuexの実装を、そしてどのように基づくvue2.x既存のプロジェクトは、活字体再建しました。

プロジェクトの初期化

9012は、今、私たちは直接使用VUE-cliの3.xのをすぐにシステムを構築します。

# 搭建项目
vue create vue2.x-vuex-typescript-demo

cd vue2.x-vuex-typescript-demo
# 引入vuex
vue add vuex
# 由于我实在不想写任何样式,所以我又加一个element
vue add element
复制代码

モジュール説明

実際のコードを説明するためにはにはvuex、モジュール間だけでなく、コミュニケーションを構築する方法で、私は非常に簡単な例を使用(例は公式よりたくさん明確にする必要があります)

シーン

女の子の花の少年。

  1. 各少年は10人の女の子は感謝の気持ちを表現取り出しました。
  2. 女の子は男の子の値の勇気のおかげで増加します。
  3. 少年は花屋に花を購入することができます。

ディレクトリ構造

あなたは次のようにデフォルトのディレクトリ構造があるでしょう。


README.md├── 
├──babel.config.js 
├──package.json 
├──公共
│├──favicon.icoを
│└──index.htmlを
├──SRC 
│├──App.vue 
│ ├──資産
││└──logo.png 
│├──部品
││└──HelloWorld.vue 
│├──main.js 
│├──プラグイン
││└──element.js 
│└──店.js 
└──yarn.lock

しかし、我々は、モジュール式になってvuexたいです。だから我々は、次のような構造に変更されました:


README.md├── 
├──babel.config.js 
├──package.json 
├──公共
│├──favicon.icoを
│└──index.htmlを
├──SRC 
│├──App.vue 
│ ├──資産
││└──logo.png 
│├──部品
││└──HelloWorld.vue 
│├──main.js 
│├──プラグイン
││└──element.js 
│└──店
│├──index.js 
│└──モジュール
│├──boy.js 
│└──girl.js 
└──yarn.lock
  1. index.jsそれはstoreメインファイル
  2. /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 {
                // 送出一朵花,自己的库存减 1
                commit('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({
    // 根 state
    state: {
        flowersInStock: 10
    },
    // 根 mutations
    mutations: {
        updateFlowersInStock(state, payload) {
            state.flowersInStock = state.flowersInStock + payload
        }
    },
    // 根 actions
    actions: {
        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プランmapStatemapActionsおよび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覚えていないだろう、何をstateactionsmutationsどこが配置します。実際には、覚えやすいです:

  • 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サフィックスA。今回のプロジェクトは、アップ実行されません。コマンドラインコンソールは数十を破りました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)
复制代码

ルート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他の方法、使用はStateActionMutationデコレータ結合しますvuex
  • 放棄されたcomputedmethodsdata使用して書かれており、他のget + 方法表現computedmethods直接抽出方法において、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を

  • 著者:ダニエル・フオ
  • リンク:danielhuoo.github.io/2019/06/18 / ...
  • 著作権は著者が保有します。商業転載は非商用の転載は、ソースを明記してください、権限の作者に連絡してください。

ます。https://juejin.im/post/5d09682d518825531e0648a7で再現

おすすめ

転載: blog.csdn.net/weixin_33763244/article/details/93169441