Vue技术点整理-Vuex
什么是Vuex?
1,Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
2,每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)
3,其实也就是,应用中各个组件之间共享状态的一个状态库,并可以时时映射到视图
什么时候用的到Vuex?
1,如果你需要构建一个大中型应用的时候,会使用到很多组件嵌套,很多业务处理,此时需要是用Vuex更好地在组件外部管理所有的状态。
2,如果你需要构建的应用是轻量的,则完全没有必要引入Vuex,使用简单的 store 模式 或者组件之间的传递方式即可实现功能。
一,vue cli中简单使用Vuex示例
1,state用法
注:main.js为定义store的代码,后面为接收state的几种方式
- main.js
import Vue from 'vue' import Vuex from 'vuex' import App from './App.vue' import router from './router/' Vue.use(Vuex) const store = new Vuex.Store({ namespaced: false, state: { title: '标题', backFlag: false }, mutations: { updateTitle (state, title) { state.title = title }, updateBackFlag (state, backFlag) { state.backFlag = backFlag } } }) Vue.config.productionTip = false new Vue({ router, store, render: h => h(App) }).$mount('#app')
- 适合获取状态个数少的时候
<template> {{title}} {{backFlag}} </template> <script> export default { name: "第一种接收方式", computed: { title () { return this.$store.state.title; }, backFlag () { return this.$store.state.backFlag; } } } </script>
- 适合多个状态的时候
<template> {{title}} {{backFlag}} </template> <script> import { mapState } from 'vuex' export default { name: "第二种接收方式", computed: mapState({
//'title',//此种方式也可以获取状态 title: state => state.title, backFlag: state => state.backFlag }) } </script>
- 适合与局部计算属性混合使用的时候
<template> {{title}} {{backFlag}} </template> <script> import { mapState } from 'vuex' export default { name: "第三种接收方式", ...mapState({ title: state => state.title, backFlag: state => state.backFlag }) } </script>
2,Getter用法
注:Getter适用于状态库里面的数据需要进行一遍过滤,或者状态值需要依赖其他状态进行一定计算,此时可以使用Getter方法,进行计算并返回
- 定义getter代码:
const store = new Vuex.Store({ namespaced: false, state: { todos: [ { id: 1, text: '第一条', done: false }, { id: 2, text: '第二条', done: false }, { id: 3, text: '第三条', done: true } ] }, mutations: { updateTodos (state, todos) { state.todos = todos } }, getters: { //根据id值,查询todos状态库里的值 getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) }, //查询todos状态库里done为true的值 doneTodos: state => { return state.todos.filter(todo => todo.done) } } })
- 接收getter代码:
<template> <div>{{doneTodos}}</div> </template> <script> import { mapState,mapGetters } from 'vuex' export default { name: "test", computed: { //自动查询doneTodos,为赋值为doneTodos ...mapGetters({ doneTodos: 'doneTodos' }) }, mounted:function() { //查询todos状态库里done为true的值 console.info(this.$store.getters.doneTodos) //查询todos状态库里done为true的值 console.info(this.$store.getters.getTodoById(2)) } }; </script> <style lang="less"> </style>
3,Mutation用法
注:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,直接改变状态,但Mutation必须是同步函数,如需要使用调用api等异步操作,请使用4 actions
- 定义Mutation代码
const store = new Vuex.Store({ namespaced: false, state: { title: '标题', backFlag: false }, mutations: { updateTitle (state, title) { state.title = title }, updateBackFlag (state, backFlag) { state.backFlag = backFlag } } })
- 调用接收Mutation代码
<template> <div>{{title}}</div> </template> <script> import { mapState,mapMutations } from 'vuex' export default { name: "test", computed: { //自动赋值title值 ...mapState({ title: state => state.title, }) }, mounted:function() { //第一种方法 动态更新title内容 this.$store.commit('updateTitle',"腾讯_首页") //第二种方法 动态更新title内容 this.updateTitle('阿里_首页') }, methods: { // 将 `this.add()` 映射为 `this.$store.commit('navbar/updateTitle')` ...mapMutations({ updateTitle: 'updateTitle' }) } }; </script> <style lang="less"> </style>
4,Action的用法
注:Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作,可以使用promise、await等处理异步调用
- 定义Action
import HttpService from '../../service/httpService.js'; const store = new Vuex.Store({ namespaced: false, state: { title: '标题', backFlag: false }, mutations: { updateTitle (state, title) { state.title = title }, updateBackFlag (state, backFlag) { state.backFlag = backFlag } }, actions: { updateTitleAsync (context,obj) { return new Promise((resolve, reject) => { let channelId = '001' HttpService.queryGoods(channelId) .then(data => { context.commit('updateTitle',obj.title) resolve() }) .catch(error => { console.info(error); }); }) } } })
- 接收action代码
<template> <div>{{title}}</div> </template> <script> import { mapState,mapMutations,mapActions } from 'vuex' export default { name: "test", //自动赋值title值 ...mapState({ title: state => state.title, }) }, mounted:function() { // this.updateTitleAsync("异步赋值,不关心返回值") this.updateTitleAsync({ title: "异步赋值,切需立即使用返回值" }).then(() => {
//console.info(context.backFlag) console.info(this.$store.state.title) }) }, methods: { // 将 `this.updateTitleAsync()` 映射为 `this.$store.dispatch('increment')` ...mapActions({ updateTitleAsync: 'updateTitleAsync' }) } }; </script> <style lang="less"> </style>
5,Module的用法
注:当应用比较复杂时,状态比较多并难管理时,Vuex 允许我们将 store 分割成模块(module)
- 创建module模块
const store new Vuex.Store({ modules: {
//navbar模块: navbar: { namespaced: true, state: { title: '默认值', backFlag: false }, mutations: { updateTitle (state, title) { state.title = title }, updateBackFlag (state, backFlag) { state.backFlag = backFlag } } } } })
- 如何接收使用模块值,参考如下,加上模块名称即可
<template> <div>{{title}}</div> </template> <script> import { mapState,mapMutations } from 'vuex' export default { name: "test", computed: { //自动赋值title值 ...mapState({ title: state => state.navbar.title, }) }, mounted:function() { //第一种方法 动态更新title内容 this.$store.commit('navbar/updateTitle',"腾讯_首页") //第二种方法 动态更新title内容 this.updateTitle('阿里_首页') }, methods: { // 将 `this.add()` 映射为 `this.$store.commit('navbar/updateTitle')` ...mapMutations({ updateTitle: 'navbar/updateTitle' }) } }; </script> <style lang="less"> </style>
GitHub示例地址 vue-ht-cli