vuex状态管理(运行机制及实例)

93 阅读3分钟

在这里插入图片描述

背景:

vue2.x项目组件工程化数据的层层传递太麻烦。如下图:内层的在家呢需要父组件的数据需要一层一层地传递,组件加载数据到父组件的时候需要一层一层回递,这样加重页面的负担。所以推出vuex状态管理来统一分发和部署。把组件中的状态抽取出来,放入Vuex进行统一管理。
在这里插入图片描述这样他们就变成一级关系:
在这里插入图片描述

vuex其实是一种套路(学会运行机制就ok)

官网:

网址:
vuex.vuejs.org/zh/installa…

手画图解:在这里插入图片描述

需求:

取数据:
1.components(组件)把数据取出来渲染到界面上、改变里面的数据。
2.全局注册后,  $state.state直接取数据或者放到map里面再去取。

改数据:
1.dispath()方法触发actions,叫action改数据,但是action没有权限改,只能向上级(mutations)汇报,通过commit()提交。并且actions里面的行为和mutamutions的行为要一至。
2. 为了防止出错,统一常量(mutation-types)约束,用到方法就调用相对应的常量。
3. actions提交过来,通过commit()触发mutamutions,然后更新状态。
数据的单独处理getters:
例如state里面有价格的处理,过滤器过滤后变成单独的功能放到getters里面封装成一个get方法,然后组件上$state.getters直接调用。

准备工作:

vue项目中新建相对应的文件。如下图:
在这里插入图片描述
安装vuex:cmd

npm install vuex --save

引入使用:store/index.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue use(Vuex);

对外暴露vuex和引入相对应的文件:store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';
import state from './state';

Vue.use(Vuex);

export default new Vuex.Store({
  state,
  mutations,
  getters,
  actions
})

这里的Store的s要大写
要不会报错:TypeError: WEBPACK_IMPORTED_MODULE_1_vuex.a.store is not a constructor
这个报错的是_vuex2.default.store 不是一个构造函数因为在我们用vuex的时候需要将用到的actions,mutations模块最终导出,在导出的时候new Vuex.Store中的Store小写了,这里的一定要大写,就相当于我们在使用构造函数(类)的时候首字母要大写

全局使用vuex

全局注册:main.js

import store from './store';

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,      //挂载
  render: h => h(App)
  // components: { App },
  // template: '<App/>'
});

**实际应用:**现在有一段数据,不属于如何的组件,vuex进行状态管理,数据谁要谁一级直接拿,不用组件的一级一级的传递。vuex实现数据的添加功能。

数据的存放(任何类型):store/state.js

// 存放所有的状态,唯一的数据源
export default {
      todos: [
        {title:'坐下来好好聊聊天', finished: false},
        {title:'和你一起的旅游', finished: false},
        {title:'回家熬夜敲代码', finished: true},
      ]
}

App.vue:

<template>
  <div class="">
  </div>
</template>

<script>
  import Header from './components/xxx/xxx'

  export default {
    name: "App",
    data(){
      return {
        //store/state.js
      }
    },
    components:{
      xxx
    },
    methods:{
      // 插入一条记录
      addTodo(todo){
        this.todos.unshift(todo);
      },
      //清空所有
      delFinishedTodos(){
        //filter方法
          this.todos = this.todos.filter(todo => !todo.finished)
      }
    }
  }
</script>
<style scoped>
</style>

components/xxx.vue:

<template>
  <div>
    <input type="text"
	         placeholder="请输入今天的任务清单,按回车键确认"
	         v-model="title"
		       @keyup.enter="addItem" />
  </div>
</template>
<script>
  export default{
    name:"xxx",
    props:{
      addTodo:Function
    },
	data(){
		return{
			title:''
		}
	},
	methods:{
		 addItem(){
			 //判断是否合理
       const title = this.title.trim();     //清空所有的输入空格
       if(!title){
         alert('请输入内容不能为空');
         return;
       }
       //生成todo对象
       const todo = {title,finshed: false};
       //调用方法
       // this.addTodo(todo);
       this.$store.dispatch('addTodo',todo);
       //清空输入
       this.title = ''
		 }
	}
  }
</script>
<style scoped>
</style>

组件的调用数据的方法:components/xxx.vue

this.$store.dispatch('addTodo',todo);

实现方法:store/actions.js

// 行为更新所有的状态
import {ADD_TODO
} from './mutations-types'
export default {
      //添加一条记录到mutations
      addTodo({commit},todo){
          commit(ADD_TODO, {todo} )
      }
}

action调用mutations的方法一定 要保证两者的函数名一致,需要第三方来保证:mutation-types来暴露出去。

store/mutation-types.js:

// 存放一些常量
export const ADD_TODO = 'add_todo';//添加一条记录

store/mutations.js:

// 存放一些常量
import {
  ADD_TODO
   } from './mutations-types'
export default{
//转字符串为变量,更新数据。
  [ADD_TODO](state, {todo}){
      state.todos.unshift(todo);
  }
}

查看数据状态:

谷歌浏览器:需要安装devtools插件
链接: chrome.google.com/webstore/se…
在这里插入图片描述

更新数据:

输入框中输入数据添加:
在这里插入图片描述

总结:

一开始学vuex是有点绕,但是认识清其的运行机制,多多运用到实例中。