ホームページ > 記事 > ウェブフロントエンド > vuex の実装原則について詳しく見る
面接でvuexの実装原理について聞かれたら、どう答えますか? vuex の実装原理については以下の記事で詳しく解説していますので、お役に立てれば幸いです。
vuex
の詳細については説明しません。簡単に復習しましょう: アプリケーションが 複数のコンポーネントの共有状態
に遭遇したとき、単に 一方向のデータ フロー
は簡単に壊れます。まず、複数のビューが同じ状態に依存します。次に、異なるビューからのアクションには同じ状態への変更が必要です。前者がパラメーターを渡すことによって解決される場合、多層のネストされたコンポーネントおよび兄弟コンポーネントには適していません。後者が、親子コンポーネントからの直接参照またはイベント変更と同期状態の複数のコピーを使用することによって解決される場合、適切ではありません。コードのメンテナンスに役立ちます。
したがって、最良の方法は、コンポーネントの共有状態を抽出し、グローバル シングルトン モードで管理することです。これが vuex
の基本的な考え方です。
[関連する推奨事項: vuejs ビデオ チュートリアル、Web フロントエンド開発]
つまり、 vuex の一般的な考え方 フレームワークは次のとおりです:
class Store { constructor() { // state // getters // mutations // actions } // commit // dipatch }
次に、書いて読むだけです。
vue create vue2-vuex//创建vue2项目 yarn add vuex@next --save//安装vuex yarn serve//启动项目
1. 状態
#(1)
//store.js // 仓库 import Vue from 'vue' import Vuex from 'vuex' import extra from './extra.js' Vue.use(Vuex) //引入vuex的方式,说明Store需要install方法 export default new Vuex.Store({ // 仓库数据源 state: { count: 1, dowhat: 'addCount' }, }
//app.vue <template> <div class="testState"> <p>{{mycount}}</p> <p>{{dowhat}}:{{count}}</p> </div> </template> <script> export default { import { mapState } from 'vuex' // 推荐方式 computed: mapState()({ mycount: state => state.count }), // 推荐方式的简写方式 computed: { // 解构的是getters ...mapState(['count', 'dowhat']) }, } </script>##(2) を使用します。
##Vuex の状態ストレージは応答性があるため、ストアから取得します。インスタンスの状態を読み取る方法は、 計算プロパティ
で特定の状態を返すことです。このパターン により、コンポーネントはグローバル状態シングルトン に依存します。モジュラー ビルド システムでは、状態を使用する必要がある各コンポーネントを頻繁にインポートする必要があり、コンポーネントのテスト時に状態をシミュレートする必要があります。
Vuex は、ルートから状態を「注入」するメカニズムを提供します。コンポーネントを各サブコンポーネントに追加します (
Vue.use(Vuex)
(3) 実装
Store の 5 つの内部属性に加えて、プラグインの install
メソッドも考慮する必要があるため、一般的なフレームワークは次のようになります。これは具体的に実装できます。class Store { constructor() { // state // getters // mutations // actions //modules } // commit // dipatch } let Vuex = { Store, Install } export default Vuex
ただし、上記の状態実装には欠点があります。データが変更されたときに、
state のデータを動的にレンダリングすることができません。では、
state のデータをどのようにレスポンシブにするかが重要な問題となるでしょうか?実際、vue
のdata と同様に、この方法で応答性を高めることもできます。次に、
install メソッドから
Vue を渡す必要があるため、変更後は次のようになります:
class Store { constructor(options) { // state this.state = options.state } } let install = function(_Vue) { _Vue.mixin({ beforeCreate() { //在组件创建之前自动调用,每个组件都有这个钩子 if (this.$options && this.$options.store) { //this.$options读取根组件 this.$store = this.$options.store } else { this.$store = this.$parent && this.$parent.$store } } }) }
2, getters
## (1) let Vue=null
class Store {
constructor(options) {
// state
this.vm = new _Vue({
data: {
state: options.state//data中的数据才是响应式
}
})
}
get state() {
return this.vm.state
}
}
let install = function(_Vue) {//用于Vue.use(plugin)
Vue=_Vue
_Vue.mixin({
onBeforeCreate() { //在组件创建之前自动调用,每个组件都有这个钩子
if (this.$options && this.$options.store) { //this.$options读取根组件
this.$store = this.$options.store
} else {
this.$store = this.$parent && this.$parent.$store
}
}
})
}
を使用します (2)
場合によっては状態から導出する必要があることに注意してくださいストア内 一部の状態 (追加、削除、フィルタリングなど) については、Vuex を使用してストア内で「ゲッター」を定義できます (ストアの計算されたプロパティと考えることができます)。計算されたプロパティと同様に、ゲッターの戻り値は依存関係に従ってキャッシュされ、依存関係の値が変更された場合にのみ再計算されます。ゲッターは状態を最初のパラメーターとして受け入れ、ゲッターはメソッドを通じてアクセスされます。呼び出しは結果をキャッシュせずに毎回行われます
(3) 実装//store.js
export default new Vuex.Store({
// 计算属性
getters: {
// 这里的函数不需要调用,可以直接使用,官方默认前面有get
getCount(state) {//接受 state 作为其第一个参数
return state.count * 100;
}
},
}
3、変異
(1)
// getters
let getters = options.getters || {}
this.getters = {}
Object.keys(getters).forEach(getterName => {
Object.defineProperty(this.getters, getterName, {
get: () => {
return getters[getterName](this.state)
}
})
})
//store.js
export default new Vuex.Store({
// 相当于methods
mutations: {
// mutations内部的函数,天生具备一个形参
add(state, n) {
state.count += n;
},
decrease(state, n) {
state.count -= n;
}
},
}
を使用します (2)
が Vuex ストアの状態を変更する唯一の方法であることに注意してくださいその方法は、突然変異を提出することです。 Vuex のミューテーションはイベントに似ています。各ミューテーションには、文字列 イベント タイプ (タイプ) と
コールバック関数 (ハンドラー)があります。このコールバック関数は状態の変更が行われる場所であり、最初のパラメーターとして状態を受け取りますが、突然変異ハンドラーを直接呼び出すことはできません。このオプションはイベント登録に似ています: 「タイプ increment の突然変異がトリガーされたとき、この関数を呼び出します。」 突然変異ハンドラーを起動するには、次のオプションを指定して
store.commit# を呼び出す必要があります。 ## メソッド は、突然変異 の ペイロードである store.commit に追加パラメータを渡すことができます。ほとんどの場合、ペイロードはオブジェクト。複数のフィールドを含めることができ、記録された変異が読みやすくなります。
(3) 実装
methods: { submit() { console.log('success'); }, // 解构仓库mutations里面的方法,要啥解构啥 ...mapMutations(['add', 'decrease']), // this.$store.commit('add'), ...mapActions(['addAction', 'decreaseAction']), // this.addAction()调用actions里面的方法 // this.$store.dispatch('add'), }
4、アクション
(1)
// mutations let mutations = options.mutations || {} this.mutations = {} Object.keys(mutations).forEach(mutationName => { this.mutations[mutationName] = (arg) => {//保证多个(第二个)参数的传入 mutations[mutationName](this.state, arg) } }) commit = (method, arg) => {//使用箭头函数改变被调用的this的指向 // console.log(this); this.mutations[method](arg) }を使用します (2) 注
store.dispatch
方法触发store.dispatch
可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch
仍旧返回 Promisestore.dispatch
在不同模块中可以触发多个 action 函数。在这种情况下,只有当所有触发函数完成后,返回的 Promise 才会执行(3)实现
// actions let actions = options.actions || {} this.actions = {} Object.keys(actions).forEach(actionName => { this.actions[actionName] = (arg) => { actions[actionName](this, arg) } }) dispatch=(method, arg) =>{ this.actions[method](arg) }
5、modules
(1)使用
// actions let actions = options.actions || {} this.actions = {} Object.keys(actions).forEach(actionName => { this.actions[actionName] = (arg) => { actions[actionName](this, arg) } }) dispatch=(method, arg) =>{ this.actions[method](arg) }
//store.js modules: { extra: extra }
(2)注意
context.state
暴露出来,根节点状态则为 context.rootState
对于模块内部的 getter,根节点状态(rootState)会作为第三个参数暴露出来
let Vue = null//全局的_Vue class Store { constructor (options) { // state //this.state = options.state 写法不完美,当改变数据的时候,不能动态的渲染,所以需要把data中的数据做成响应式的 this.vm = new _Vue({ data: { state: options.state//data中的数据才是响应式 } }) // getters let getters = options.getters || {} this.getters = {} Object.keys(getters).forEach(getterName => { Object.defineProperty(this.getters, getterName, { get: () => { return getters[getterName](this.state) } }) }) // mutations let mutations = options.mutations || {} this.mutations = {} Object.keys(mutations).forEach(mutationName => { this.mutations[mutationName] = (arg) => {//保证多个(第二个)参数的传入 mutations[mutationName](this.state, arg) } }) // actions let actions = options.actions || {} this.actions = {} Object.keys(actions).forEach(actionName => { this.actions[actionName] = (arg) => { actions[actionName](this, arg) } }) } dispatch=(method, arg) =>{ this.actions[method](arg) } commit = (method, arg) => { // console.log(this); this.mutations[method](arg) } get state() { return this.vm.state } } let install = function(_Vue) { Vue = _Vue Vue.mixin({ beforeCreate() {//在组件创建之前自动调用,每个组件都有这个钩子 if (this.$options && this.$options.store) { // this.$options读取到根组件 this.$store = this.$options.store } else { // //如果不是根组件的话,也把$store挂到上面,因为是树状组件 this.$store = this.$parent && this.$parent.$store } } }) } let Vuex = { Store, install } export default Vuex
以上がvuex の実装原則について詳しく見るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。