在src文件下创建store文件夹,在里面新建一个index.js文件,在文件里书写以下代码
import Vue from 'vue' import Vuex from 'vuex' // 启用vuex Vue.use(Vuex) // 声明vuex实例对象,创建四个对象属性 export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, getters: {} })在main.js文件中全局注入store实列对象
// 引入store实例对象 import store from '@/store/index' // 将store注入到vue实列对象中 new Vue({ el: '#app', store, render: h => h(Counter) })用来存储数据的对象,对象中的数据可以在所有组件中使用
1.存储数据
const state = { newData: 5 }2.在其他组件中获取数据
this.$store.state.newData // 例如:输出结果为5 <p>{{$store.state.newData}}</p>3.获取state中多个数据
// 通过引入mapState辅助函数实现 import {mapState} from 'vuex'注意mapState函数有两个方式赋值,需要结合计算属性 第一种是对象赋值
computed: mapState({ // 箭头函数让代码简练 count: state => state.count // 传字符串参数可以等价于箭头函数: 'count' == state => state.count countAlias: 'count' })案例演示:
// store>index.js export default new Vuex.Store({ state: { count: 1, sum: 10, add: 5 } }) // state.vue <script> import {mapState} from 'vuex' export default new Vue({ computed: mapState({ count: state => state.count, sum: state => state.sum, add: state => state.add }) }) </script> <template> <div id="state"> <p>{{count}}</p> // 1 <p>{{sum}}</p> // 10 <p>{{add}}</p> // 5 </div> </template>第二种是数组赋值(常用,推荐)
// 映射this.count为store.state.count computed: mapState([ 'count' ])案例演示:
// store>index.js export default new Vuex.Store({ state: { count: 3, sum: 6, add: 9 } }) // state.vue <script> import {mapState} from 'vuex' export default new Vue({ computed: mapState([ 'count', 'sum', 'add' ]) }) </script> <template> <div id="state"> <p>{{count}}</p> // 3 <p>{{sum}}</p> //6 <p>{{add}}</p> // 9 </div> </template>第三种是展开运算符,在组件的方法中使用
// 使用对象展开运算符将此对象混入到外部对象中 computed: { ...mapState({ count: 'count', sum: 'sum', add: 'add' }) }一个对象,保存的是更改state的函数,也只有它能更改state中的值,该函数可以传入两个参数,第一个参数为state,第二个参数为传入的数据,一般为一个对象
const mutations = { add (state, n) { state.count += n } }在其他组件中调用触发函数,改变state中变量的值
// 触发函数里有两个参数,第一个为调用的mutations里面的函数的函数名,第二个为数据 this.$store.commit('add', 2) // 例如: <button @click="$store.commit('add', 2)">点击改变count</button>如果想要触发事件像正常函数那样,如:@click="add",则需要通过mapMutations辅助函数,需要结合methods对象
// 将 this.increment() 映射为 this.$store.commit('adds') // 载荷:this.increment(amount) 映射为 this.$store.commit('adds', amount)引入mapMutations辅助函数
import {mapMutations} from 'vuex'第一种对象方式
// 注意命名不要和state中的变量重名 methods: mapMutations({ adds: 'adds', reduce: 'reduce' })案例演示:
第二种数组方式
methods: mapMutations([ 'adds', 'reduce' ])第三种展开运算符,在组件的方法中使用
methods: { ...mapMutations({ adds: 'adds', reduce: 'reduce' }) } methods: { ...mapMutations([ 'adds', 'reduce' ]) }一个对象,保存的是触发mutations的函数,让mutations去修改state中的值,也可以是异步请求获取数据,获取数据后再通过context.commit()触发更改
// 相当于将$store.commit上的commit对象传进来,让方法体逻辑和代码更清晰明了 const actions = { addsAction: ({commit}) => commit('adds') } // 传递参数 const actions = { addsAction({commit}, n){commit('adds', n)} } // 传入任意参数,相当于store本身 const actions = { reduceAction: (context) => context.commit('reduce') } // 传递参数 const actions = { reduceAction(context,n){context.commit('reduce', n)} }在其他组件中触发actions函数
this.$store.dispatch('addsAction') // 如果有参数的话,就传入参数,一般以对象的方式传入 this.$store.dispatch('addsAction', { amount: 10 }) // 例如: <button @click="$store.dispatch('addsAction', 1)">点击改变p的值</button> <button @click="$store.dispatch('reduceAction', 1)">点击改变p的值</button>如果想要触发事件像正常函数那样,如:@click="add",则需要通过mapActions辅助函数,需要结合methods对象方法
引入mapActions辅助函数
import {mapActions} from 'vuex'第一种对象方式
methods: mapActions({ addsAction: 'addsAction', reduceAction: 'reduceAction' })案例演示:
<button @click="addsAction(1)">点击改变p的值</button> <button @click="reduceAction(1)">点击改变p的值</button>第二种数组方式
methods: mapActions([ 'addsAction', 'reduceAction' ])第三种展开运算符,需要在组件方法中使用
methods: { ...mapActions({ addsAction: 'addsAction', reduceAction: 'reduceAction' }) } // 或者数组形式 methods: { ...mapActions([ 'addsAction', 'reduceAction' ]) }getters相当于计算属性,用来重新修改state中变量的值,再返回对应的值,类似于vue的过滤器
const getters = { getUsername: state => state.username + '1' // 也可以这样写 getUsername (state) { return state.username + '1' } }getters的使用方式同前面的差不多 第一种,正常使用方式
this.$store.getters.getUsername第二种,就是数组模式
computed: { ...mapGetters([ 'getUsername' ]) }第三种,就是对象模式
computed: { ...mapGetters({ getUsername: 'getUsername'(前面是重新定义的方法名,后面是你定义在getters里面的方法名) }) }一般都是通过vue的watch来监听,watch监听分为普通监听和深度监听(对象)
// 例如,我们把state获取到并去监听数据变化来执行我们想要执行的事件 computed: { ...mapState([ 'username' ]) } watch: { username (newVal, oldVal) { console.log('新值:' + newVal + '旧值:' + oldVal) // to do something here } }如果返回一个对象,我们要监听对象或者对象的某一个属性变化,则这样做
// 普通监听 computed: { ...mapGetters([ 'userInfo' ]) }, watch: { userInfo (newVal, oldVal) { console.log('新值:' + newVal + '旧值:' + oldVal) // to do something here } // 必须 deep: true } // 监听对象某个属性的变化 userInfo.username (newVal, oldVal) { console.log('新值:' + newVal + '旧值:' + oldVal) // to do something here } // 如果想要对象中某个属性值改变时执行操作,可以通过computed来作为中间层来实现 computed: { username () { return userInfo.username } } watch: { username (newVal, oldVal) { console.log('新值:' + newVal + '旧值:' + oldVal) // to do something here } }actions区别于mutations的地方在于mutations只能进行同步更改,而actions中的更改可以是异步执行。
所以基本上所有用户执行的直接数据更改都是触发mutations属性函数执行,而需要与后端进行数据交互的数据更改通常是通过actions属性函数去执行。
定义mutations属性函数时必须传递的第一个参数是state,因为要对state进行更改,第二个参数代表传入的新参数。
mutations属性函数只接受两个参数,如果要同时更改多个属性值,可以通过对象传入。
在actions属性函数中可以通过context.commit()方法触发mutations属性函数。定义actions属性函数时,必须传递的第一个参数是context,用于触发mutations函数。
在子组件中通过this.$store.commit()方法触发mutations属性函数。在注册store的Vue实例中(第三步中将会讲到)可以通过store.commit()触发。
commit函数第一个参数是mutations的属性函数名,第二个参数是传入的新值。
actions属性函数中可以进行异步操作,比如通过ajax或者Vue.Resource()进行数据获取,获取数据后再通过context.commit()触发更改。
触发actions属性函数使用this.$store.dispatch()或者store.dispatch() (在注册store的Vue实例中)函数。dispatch函数传递的一个参数是actions属性函数名称。
如果希望在Vue实例创建完成还未挂载时就从后端获取数据,则可以在created钩子函数中调用actions属性函数。
在Vue实例中可以通过this.$store.state对象获取state中的数据。如果希望在state中的数据发生更改之后,组件会自动更新,则应该使用组件的computed属性定义数据,而不是通过data属性定义。
如果使用data定义组件数据,则state中的数据发生更改之后组件不会发生变化。
转载于:https://www.cnblogs.com/zjh-study/p/10912413.html