ケース出典: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
、モジュール間だけでなく、コミュニケーションを構築する方法で、私は非常に簡単な例を使用(例は公式よりたくさん明確にする必要があります)
シーン
女の子の花の少年。
- 各少年は10人の女の子は感謝の気持ちを表現取り出しました。
- 女の子は男の子の値の勇気のおかげで増加します。
- 少年は花屋に花を購入することができます。
ディレクトリ構造
あなたは次のようにデフォルトのディレクトリ構造があるでしょう。
。 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
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 {
// 送出一朵花,自己的库存减 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
プラン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
サフィックス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
他の方法、使用は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を。
- 著者:ダニエル・フオ
- リンク:danielhuoo.github.io/2019/06/18 / ...
- 著作権は著者が保有します。商業転載は非商用の転載は、ソースを明記してください、権限の作者に連絡してください。
ます。https://juejin.im/post/5d09682d518825531e0648a7で再現