main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
// vuex 动态注册一个 modules
store.registerModule('c', {
state: {
text: 3
}
})
// vuex 动态解绑一个 modules
// store.unregisterModule('c')
// vuex 监听一个指定字段是否发生变化
// store.watch((state) => state.count + 1, (newCount) => {
// store.watch((state) => state.count, (newCount) => {
// console.log('new count watch', newCount)
// })
// // vuex 拿到所有 mutation 的变化
// store.subscribe((mutation, state) => {
// // 触动了 mutation 里面的哪个方法
// console.log(mutation.type)
// // mutation 里面更新的最新值
// console.log(mutation.payload)
// })
// vuex 拿到所有 action 的变化
// store.subscribeAction((action, state) => {
// // 触动了 action 里面的哪个方法
// console.log(action.type)
// // action 里面更新的最新值
// console.log(action.payload)
// })
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
store - index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 是否为开发环境
const isDev = process.env.NODE_ENV === 'development'
// 建立一个 Store
const store = new Vuex.Store({
// 开启规范检测
strict: isDev,
// 定义属性
state: {
count: 0,
firstName: 'dzm',
lastName: 'xyq'
},
// 更新(同步),mutations 不能存在异步操作
mutations: {
updateCount (state, num) {
state.count = num
}
},
// 更新(异步),actions 允许异步操作
actions: {
updateCountAsync (store, data) {
setTimeout(() => {
store.commit('updateCount', data.num)
}, data.time)
}
},
// 获取计算属性
getters: {
fullName (state) {
return `${state.firstName} ${state.lastName}`
}
},
// 插件列表
plugins: [
(store) => {
console.log('初始化插件列表')
}
],
// 模块功能
modules: {
// 模块A
a: {
// 默认 vuex 是会把所有的 mutations 放在一个全局的对象中,如果需要根据模块区分,那么需要在模块中配置 namespaced: true
// 这样的好处就是,每个模块里面都可以写相同名字的 mutations,如果不声明,那么所有的 mutations 都会在一个对象中,就会命名重复冲突
namespaced: true,
state: {
text: 1
},
mutations: {
updateText (state, text) {
// 这里面的 state 就是 a 模块里面的 state 了
state.text = text
}
},
getters: {
// state 当前A模块的 state
// getters 当前A模块所有的 getters
// rootState 当前父类的 state
textPlus (state, getters, rootState) {
// 这样就可以直接使用父类中的属性了
return state.text + rootState.count
// 同时也可以使用别的模块中的值
// return state.text + rootState.b.text
}
},
actions: {
// add (ctx) { }
add ({ state, commit, rootState }) {
// 直接调用A模块内的 updateText
// commit('updateText', rootState.count)
// 直接调用父模块内的 updateCount
commit('updateCount', 123, { root: true })
}
},
modules: {
// 还可以在子模块中继续嵌套模块
}
},
// 模块B
b: {
state: {
text: 2
}
}
}
})
export default store
App.vue
<template>
<div id="app">
<!-- 显示vuex的值 -->
<div>{{count}}</div>
<div>{{fullName}}</div>
<div>{{textA}}</div>
<div>{{textPlus}}</div>
<div>{{textC}}</div>
</div>
</template>
<script>
import {
mapState,
mapGetters,
mapActions,
mapMutations
} from 'vuex'
export default {
name: 'app',
mounted () {
// vuex 不能直接通过点语法直接修改数据,这么写会报错的:
// this.$store.state.count = 3
// 下面这个是 mutations 同步修改:
// let i = 1
// setInterval(() => {
// this.$store.commit('updateCount', i++)
// }, 1000)
// mutations 同步修改使用 ...mapMutations 之后可以这么使用:
let i = 1
setInterval(() => {
this.updateCount(i++)
}, 1000)
// 下面这个是 actions 异步修改:
// this.$store.dispatch('updateCountAsync', {
// num: 5,
// time: 1000
// })
// actions 异步修改使用 ...mapActions 之后可以这么使用:
// this.updateCountAsync({
// num: 5,
// time: 1000
// })
// modules 根据模块获取数据
// 通过 ...mapMutations 修改数据
// namespaced: false
// this.updateText('123')
// namespaced: true
// this['a/updateText']('456')
this['a/add']()
},
methods: {
...mapActions(['updateCountAsync', 'a/add']),
// updateText 是模块里面的更新属性,但是默认 vuex 是会把所有的 mutations 放在一个全局的对象中,如果需要根据模块区分,那么需要在模块中配置:
// namespaced: true, 这样的好处就是,每个模块里面都可以写相同名字的 mutations, 如果不声明,那么所有的 mutations 都会在一个对象中,就会命名重复冲突
// namespaced: false
// ...mapMutations(['updateCount', 'updateText'])
// namespaced: true
...mapMutations(['updateCount', 'a/updateText'])
},
computed: {
// mapState
// 获取属性方式一
...mapState(['count']),
// 获取属性方式二
// ...mapState({
// counter: 'count'
// }),
// 获取属性方式三
// ...mapState({
// count: (state) => state.count
// }),
// 获取属性方式四
// count () {
// return this.$store.state.count
// },
// mapGetters 也跟上面一样
// 如果 namespaced: true, 那么 'a/textPlus' 这种方式是不好去使用的
// ...mapGetters(['fullName', 'a/textPlus']),
// 就需要这样去使用
...mapGetters({
fullName: 'fullName',
textPlus: 'a/textPlus'
}),
// fullName () {
// return this.$store.getters.fullName
// }
// modules 根据模块获取数据
// 获取属性方式一
// textA () {
// return this.$store.state.a.text
// },
// 获取属性方式二
...mapState({
textA: state => state.a.text,
textC: state => state.c.text
})
}
}
</script>
<style scoped>
</style>