vuex的基本使用
想要实现一个简单的vuex,先来了解一下它的使用
大致就是store中的数据通过辅助函数或者this.$store.state.属性的方式渲染到组件身上,当组件进行数据修改的时候通过this.$store.dispacth的方式来调用actions中的函数,actions中的函数通过调用commit这个方法来调用mutations里面的方法,mutations里面的方法是专门用来修改state中的数据,当state中的数据修改是,因为数据是响应式的因此组件视图优化方式改变
//store/index.js
import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); const store = new Vuex.Store({ state:{ n:10, m:0 inputVal:"", list:[] }, actions:{ handleActionsAdd({commit,dispatch}){ commit("handleMutationsAdd","di") }, }, mutations:{ handleMutationsChange(state,params){ state.inputVal = params; console.log(state); } } }) export default store;
//main.js上挂载store
import Vue from 'vue' import App from './App.vue' import store from "./store"; new Vue({ store, render: h => h(App) }).$mount('#app')
//在component/One.vue组件中调用
<template> <div> <h2>这是一个One组件</h2> <p>{{$store.state.n}}</p> <button @click="handleAdd">点击</button> </div> </template> <script> export default { data(){ return { message:"di" } }, methods:{ handleAdd(){ this.$store.dispatch("handleActionsAdd","di") } } } </script>
Vuex自己实现一个简单版
该版本实现有actions,mutations,state的调用
具体实现代码
/src/di-vuex/index.js
let Vue; //定义一个install方法用于接受Vue.use传递进的vue function install(_Vue){ Vue = _Vue; Vue.mixin({ //将store的实例挂在vue的实例身上 this.$store.state.属性 beforeCreate() { //vue实例属性$options是获取除了data之外的方法和属性的,options的具体内容见详情A if(this.$options.store){ console.log('this.$options',this.$options) Vue.prototype.$store = this.$options.store; } }, }) } class Store{ //初始化 constructor(options){ //将state中的状态转换为响应式状态 this.state = new Vue({ data:options.state }) //初始化mutations this.mutations = options.mutations || {}; //初始化actions this.actions = options.actions || {}; //初始化getters,当options.getters为true时,执行this.handleGetters(options.getters) options.getters && this.handleGetters(options.getters) } commit(eventName,params){ var fn = this.mutations[eventName]; fn(this.state,params); } dispatch(eventName,params){ var fn = this.actions[eventName]; //因为commit和dispatch会在其他地方调用,所以这里要使用bind先将this绑定到当前类中 fn({commit:this.commit.bind(this),dispatch:this.dispatch.bind(this),state:this.state},params); } } export default {Store,install}
使用自定义的diVuex
/src/store/index.js
import Vue from "vue"; import Vuex from "../di-vuex" Vue.use(Vuex); const store = new Vuex.Store({ state:{ n:10, }, actions:{
handleActionsAdd({commit,dispatch}){
commit("handleMutationsAdd","alley")
},
},
mutations:{
handleMutationsAdd(state,params){
state.n++;
}, }, }) export default store;
在main.js中
import Vue from 'vue' import App from './App.vue' import store from "./store"; Vue.config.productionTip = false new Vue({ store, render: h => h(App) }).$mount('#app')
在组件One.vue和组件Two.vue中
//One.vue <template> <div> <h2>这是一个One组件</h2> <p>{{$store.state.n}}</p> <button @click="handleAdd">点击</button> </div> </template> <script> export default { data(){ return { message:"di" } }, methods:{ handleAdd(){ this.$store.dispatch("handleActionsAdd","di") } } } </script>
//Two.vue <template> <div> <h2>这是一个Two组件</h2> <p>{{$store.state.n}}</p> </div> </template>
执行结果
当我按下“点击”按钮时,one和two组件会同时+1