Vuex的实现原理解析(最清晰)

Vuex的实现原理解析(最清晰)

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,可以帮助我们管理共享状态。
在这里插入图片描述
如何在Vue中使用Vuex?
如下先来回顾一下使用Vuex的正确姿势:

  1. 引入Vuex插件;
// store.js
Vue.use(Vuex);
  1. 将Vuex.Store这个类实例化,并传入一些配置,这里以计数器作为一个例子;
// store.js
const store = new Vuex.Store({
    state:{
        count:0
    },
    mutations:{
        increment(state){
            state.count++;
        },
        del(state){
            state.count--;
        },
    },
    actions:{
        asyncAdd({commit}){
            setTimeout(() => {
                commit("increment");
            }, 2000);
        }
    }
})
  1. 将store的实例配置给Vue
new Vue({
  store,
  render: h => h(App),
}).$mount('#app')
  1. 组件中使用时
<template>
    <div>计数器
        <span>{{$store.state.count}}</span>
        <br/>
        <button @click="this.add">+</button>
        <button @click="this.del">-</button>
        <button @click="this.asyncAdd">异步+</button>
    </div>
</template>
<script>
export default {
    methods:{
        add(){
            this.$store.commit('increment');
        },
        del(){
            this.$store.commit('del');
        },
        asyncAdd(){
            this.$store.dispatch('asyncAdd');
        }
    }
}
</script>
  1. 效果
    页面上点击+时,调用this. s t o r e . c o m m i t ( " x x x " ) 方 法 , 实 现 t h i s . store.commit("xxx")方法,实现this. store.commit("xxx")this.store.state.count的修改

Vuex的核心源码解析:
目标:

  1. 作为插件一定有install方法,可以在其中进行混入,当Vue实例化后挂载前拿到给其配置的store实例,把store放在原型上,以便全局可用;
  2. 持有基本的state,保存实例化router时配置的mutations,actions对象;
  3. 实现commit及dispatch等方法,可对state进行一定的修改;

Vuex的核心源码简版:

let Vue;
class Store {
    // 持有state,并使其响应化
    constructor(options){
        this.state = new Vue({
            data:options.state
        })
        this.mutations = options.mutations;// mutations 是对象
        this.actions = options.actions;// mutations 是对象
        // 绑定this
        this.commit=this.commit.bind(this);
        this.dispatch=this.dispatch.bind(this);
    }
    // 实现commit和dispatch方法
    commit(type,arg){
        this.mutations[type](this.state,arg);
    }
    dispatch(type,arg){
        console.log(this.actions[type])
        return this.actions[type](this,arg)
    }
}
function install(_vue){
    Vue = _vue;
    Vue.mixin({// 为什么用混入?use是先执行,而this指向的是vue实例,是在main.js中后创建的,使用混入才能在vue实例的指定周期里拿到store实例并做些事情
        beforeCreate(){
            if (this.$options.store) {
                Vue.prototype.$store=this.$options.store;
            }
        }
    })
}
export default {
    Store,
    install
}

其实,Vuex.Store是个类,使用他的时候,你给他传入了参数(state,mutations,actions)并让他实例化。你把这个实例配置给了Vue,Vuex帮你把他给了Vue原型上的$store。

Vuex还送给你个commit和dispatch方法让你能有办法改 s t o r e . s t a t e , 当 然 你 也 能 通 过 store.state,当然你也能通过 store.statestore.state方法到你要的状态。

加油,陌生人!(来来往往不陌生,希望对您有所帮助)

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的使用Vuex实现TodoList的示例代码: 首先,需要安装Vuex: ``` npm install vuex --save ``` 然后,创建一个store.js文件,用于定义Vuex的状态、mutations、actions等: ```javascript import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); const store = new Vuex.Store({ state: { todos: [ { id: 1, text: '学习Vue', completed: false }, { id: 2, text: '学习Vuex', completed: false }, { id: 3, text: '学习Vue Router', completed: false } ] }, mutations: { addTodo (state, payload) { state.todos.push({ id: Date.now(), text: payload.text, completed: false }); }, toggleTodo (state, payload) { const todo = state.todos.find(todo => todo.id === payload.id); todo.completed = !todo.completed; }, deleteTodo (state, payload) { state.todos = state.todos.filter(todo => todo.id !== payload.id); } }, actions: { addTodo ({ commit }, payload) { commit('addTodo', payload); }, toggleTodo ({ commit }, payload) { commit('toggleTodo', payload); }, deleteTodo ({ commit }, payload) { commit('deleteTodo', payload); } } }); export default store; ``` 在上面的代码中,我们定义了一个todos数组作为状态,然后定义了三个mutations来修改这个状态。addTodo用于添加一个todo项,toggleTodo用于切换一个todo项的完成状态,deleteTodo用于删除一个todo项。最后,我们定义了三个actions,这些actions用于触发mutations来修改状态。 接下来,我们可以在组件中使用Vuex: ```vue <template> <div> <h2>TodoList</h2> <form @submit.prevent="addTodo"> <input type="text" v-model="newTodoText"> <button type="submit">Add Todo</button> </form> <ul> <li v-for="todo in todos" :key="todo.id" :class="{ completed: todo.completed }"> <input type="checkbox" v-model="todo.completed" @change="toggleTodo(todo)"> <span>{{ todo.text }}</span> <button @click="deleteTodo(todo)">Delete</button> </li> </ul> </div> </template> <script> import { mapState, mapActions } from 'vuex'; export default { computed: { ...mapState(['todos']), newTodoText: { get () { return ''; }, set (value) { this.$data.newTodoText = value; } } }, methods: { ...mapActions(['addTodo', 'toggleTodo', 'deleteTodo']) } }; </script> ``` 在上面的代码中,我们使用了Vuex提供的mapState和mapActions辅助函数,来将todos状态和addTodo、toggleTodo、deleteTodo等actions映射到组件的computed和methods中。 最后,在组件的created钩子中,我们可以使用Vuex的actions来初始化状态: ```javascript import store from './store'; export default { created () { this.$store.dispatch('addTodo', { text: '学习Vuex' }); this.$store.dispatch('addTodo', { text: '学习Vue Router' }); }, store }; ``` 以上就是使用Vuex实现TodoList的示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值