赞
踩
Vuex 是一个专为 Vue.js 应用程序开发的状态管理架构。它借鉴了 Flux 和 Redux的设计思想,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。。状态?理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。
完整的应用Vuex开发的应用结构应该是这样的:
简单的理解:当vue组件(vue components)发生变化的(比如用户触发点击事情,需要改变vuex状态)——》通过dispatch提交action(这里面会很多的函数,需要dispatch触发这里的事情函数)——》通过 store.commit 方法触发状态变更(mutation的方法) ——》mutation改变state状态——》state状态改变之后,getter映射渲染vue 组件
State负责存储整个应用的状态数据,一般需要在使用的时候在跟节点注入store对象,后期就可以使用this.$store.state直接获取状态
- //store为实例化生成的
- import store from './store'
-
- new Vue({
- el: '#app',
- store,
- render: h => h(App)
- })
这个store可以理解为一个容器,包含着应用中的state等。实例化生成store的过程是:
- const mutations = {...};
- const actions = {...};
- const state = {...};
-
- Vuex.Store({
- state,
- actions,
- mutation
- });
后续在组件中使用的过程中,如果想要获取对应的状态你就可以直接使用this.$store.state获取,当然,也可以利用vuex提供的mapState辅助函数将state映射到计算属性中去(当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组),如
- //我是组件
- import {mapState} from 'vuex'
- export default {
- computed: mapState({
- count: state => state.count
- })
- }
Mutations的中文意思是“变化”,利用它可以更改状态,本质就是用来处理数据的函数,其接收唯一参数值state。store.commit(mutationName)是用来触发一个mutation的方法。需要记住的是,定义的mutation必须是同步函数,否则devtool中的数据将可能出现问题,使状态改变变得难以跟踪。
const mutations = { mutationName(state) { //在这里改变state中的数据 } } 在组件中触发: //我是一个组件 export default { methods: { handleClick() { this.$store.commit('mutationName') } } } 或者使用辅助函数mapMutations直接将触发函数映射到methods上,这样就能在元素事件绑定上直接使用了。如: import {mapMutations} from 'vuex' //我是一个组件 export default { methods: mapMutations([ 'mutationName' ]) }
Actions也可以用于改变状态,不过是通过触发mutation实现的,重要的是可以包含异步操作。其辅助函数是mapActions与mapMutations类似,也是绑定在组件的methods上的。如果选择直接触发的话,使用this.$store.dispatch(actionName)方法。
//定义Actions const actions = { actionName({ commit }) { //dosomething commit('mutationName') } } 在组件中使用 import {mapActions} from 'vuex' //我是一个组件 export default { methods: mapActions([ 'actionName', ]) }
有些状态需要做二次处理,就可以使用getters。通过this.$store.getters.valueName对派生出来的状态进行访问。或者直接使用辅助函数mapGetters将其映射到本地计算属性中去。
- const getters = {
- strLength: state => state.aString.length
- }
- //上面的代码根据aString状态派生出了一个strLength状态
- 在组件中使用
-
- import {mapGetters} from 'vuex'
-
- //我是一个组件
- export default {
- computed: mapGetters([
- 'strLength'
- ])
- }
插件就是一个钩子函数,在初始化store的时候引入即可。比较常用的是内置的logger插件,用于作为调试使用。
- import createLogger from 'vuex/dist/logger'
- const store = Vuex.Store({
- ...
- plugins: [createLogger()]
- })
三.mapGetters, mapMutations, mapActions, mapState 的使用
1. store 文件下
store/index.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- import VuexPersist from 'vuex-persist'
- import user from './modules/user'
- import getters from './getters'
-
- Vue.use(Vuex)
-
- const vuexLocal = new VuexPersist({
- storage: window.sessionStorage //可选,sessionStorage/indexDB/localStorage
- });
- export default new Vuex.Store({
- state: {
- token:"1833737"
- },
- modules: {
- user
- },
- mutations: {
- },
- actions: {
- },
- getters,
- plugins: [vuexLocal.plugin]
- })
store/getters.js
- const getters = {
- name: state => state.user.name
- }
-
- export default getters
store/modules/user.js
- const user = {
- state: {
- name:"王一涵"
- },
-
- mutations: {
- SET_NAME: (state, name) => {
- state.name = name
- }
- },
-
- actions: {
- setName({ commit },data) {
- return new Promise((resolve, reject) => {
- commit('SET_NAME', data)
- })
- },
- }
- }
-
- export default user
2. 组件
- <template>
- <div id="app">
- <button @click="fn">按钮</button>
- </div>
- </template>
- <script>
- import { mapGetters, mapMutations, mapActions, mapState } from "vuex";
- export default {
- name: "App",
- components: {
- },
- data() {
- return {
-
- };
- },
- created() {},
- mounted() {
- console.log("开始:", this.$store.getters.name);
- },
- computed: {
- // ...mapGetters(["name"]),
- ...mapState({
- token: "token",
- name:state=> state.user.name,// 指定modules里的
- }),
- },
- created: function () {},
- methods: {
- // ...mapMutations(["SET_NAME"]),
- ...mapActions(["setName"]),
- fn() {
- console.log("token:", this.token);
- // this.SET_NAME("张翰");// mapMutations的方法
-
- this.setName("迪丽热巴");// mapActions的方法
-
- console.log("点击", this.name);//mapState mapGetters 访问
- },
- },
- };
- </script>
- <style lang="scss">
-
- </style>
四.demo
1.简单触发mutation
store.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex)
-
- // 引入actions, mutations, getters
- import mutations from "./mutations.js"
- //state:是容器
- const state = {
- count:10,
- name:"jack"
- }
- export default new Vuex.Store({
- state,
- mutations
- })
index.vue
- <template>
- <div>
- <h1>Vuex小demo</h1>
- <div>测试1:Count is {{count}}</div>
- <div>用户名:{{name}}</div>
- <button @click="add">+</button>
- <button @click="dec">-</button>
- <button @click="updata">改变用户名</button>
- </div>
- </template>
- <script>
- export default {
- computed:{
- count(){
- //通过 store.state 来获取状态对象
- return this.$store.state.count;
- },
- name(){
- return this.$store.state.name;
- }
- },
- methods: {
- add(){
- //通过 store.commit 方法触发状态变更(mutation的方法)
- this.$store.commit('increment');
- },
- dec(){
- this.$store.commit('decrement');
- },
- updata(){
- //传参数
- this.$store.commit('updataName','修小龙');
- }
-
- }
- }
- </script>
mutations.js模块
- /*
- *mutations:状态改变操作方法。是vuex修改state的唯一推荐方法,
- */
- export default {
- //对state进行操作
- increment:(state) =>{
- return state.count ++;
- },
- decrement:(state) =>{
- return state.count--;
- },
- updataName:(state,userName) =>{
- state.name = userName;
- }
- }
从上面可以简单案例一般组件改变的事件 直接触发mutation方法 进行修改state。
2.加上action
store.js:引入action.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex)
-
- // 引入actions, mutations, getters
- import actions from "./actions.js"
- import mutations from "./mutations.js"
-
- //state:是容器
- const state = {
- count:10,
- name:"jack"
- }
-
- export default new Vuex.Store({
- state,
- actions,
- mutations
- })
在index.vue:改变add方法
- add(){
- //通过 store.dispatch方法触发状态变更(action创建函数的方法)
- this.$store.dispatch('incrementAction');
- },
action.js
- //action 模块
- /*action:操作行为处理模块。负责处理vue 组件接受到所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。
- 向后台api请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了,promise的封装,以支持action的链式触发
- *通过commit提交
- commit:状态改变提交方法。对mutetion进行提交,是唯一能执行mutation的方法
- *dispatch:操作行触发方法,是唯一能执行action的方法
- *action不能直接操作state
- */
-
- export default {
- incrementAction:(context) =>{
- context.commit('increment');
- }
- }
效果也是跟上面一样。加上action后,组件改变事情 触发action函数(通过dispatch触发action),action函数里面触发mutation(还是用commit来触发)
action简单的操作是可以不用,具体情况具体分析。
3.加上getters(辅助性,在基层上进行延伸的操作)
store.js
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex)
-
-
- // 引入actions, mutations, getters
- import actions from "./actions.js"
- import mutations from "./mutations.js"
- import getters from "./getters.js"
-
- //state:是容器
- const state = {
- count:10,
- name:"jack"
- }
-
- export default new Vuex.Store({
- state,
- actions,
- getters,
- mutations
- })
count:10,
name:"jack"
}
export default new Vuex.Store({
state,
actions,
getters,
mutations
})
index.vue
- <template>
- <div>
- <h1>Vuex小demo</h1>
- <div>测试1:Count is {{count}}</div>
- <div>用户名:{{name}}</div>
- <div>通过getters改变用户名:{{userName}}</div><button @click="add">+</button>
- <button @click="dec">-</button>
- <button @click="updata">改变用户名</button>
- </div>
- </template>
- <script>
- export default {
- computed:{
- count(){
- //通过 store.state 来获取状态对象
- return this.$store.state.count;
- },
- name(){
- return this.$store.state.name;
- },
- userName(){
- return this.$store.getters.userName;
- }
- },
- methods: {
- add(){
- //通过 store.dispatch方法触发状态变更(action创建函数的方法)
- this.$store.dispatch('incrementAction');
- },
- dec(){
- this.$store.commit('decrement');
- },
- updata(){
- //传参数
- this.$store.commit('updataName','修小龙');
- }
-
- }
- }
- </script>
getters.js
- //getters 模块
- /*
- *getters:state对象读取方法。图中没有单独列出该模块,应该被包含在render中,组件通过该方法this.$store.getters.userName 直接读取全局state对象
- 而不需要去触发mutation函数
- */
- export default {
- userName:(state) =>{
- return state.name + ',Hello';
- }
- }
在之前的基层store中name上加上Hello,getters跟其他都没有关系。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。