vuex状态管理(运行机制及实例)
背景:
vue2.x项目组件工程化数据的层层传递太麻烦。如下图:内层的在家呢需要父组件的数据需要一层一层地传递,组件加载数据到父组件的时候需要一层一层回递,这样加重页面的负担。所以推出vuex状态管理来统一分发和部署。把组件中的状态抽取出来,放入Vuex进行统一管理。
这样他们就变成一级关系:
vuex其实是一种套路(学会运行机制就ok)
官网:
网址:
https://vuex.vuejs.org/zh/installation.html
手画图解:
需求:
取数据:
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: ''});
**实际应用:**现在有一段数据,不属于如何的组件,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插件
链接:https://chrome.google.com/webstore/search/vue.js%20devtools
更新数据:
输入框中输入数据添加:
vuex和localstorage存储数据有什么区别
- 完全就是两个东西,vuex是vue中的状态管理机制,是方便组件之间通信的;而localstorage是本地存储,是将数据存储到浏览器的方法,一般是在跨页面传递数据时使用。
- 压根他俩就是两码事。vuex是状态管理用的,就是组件数据共享的那种,一个组件的数据变化会映射到使用这个数据的其他组件。再说localstorage,那个是H5提供的一个更简单的数据存储的方式,之前是用cookie存放,但是cookie存放的数据量太小,而且接口麻烦。localstorage的数据可以有5M的限制,相当大了已经,而且api相当简单好记,方便使用,在以后相信会成为主流的。
- vuex存的是状态,表示与view对应的数据,存的位置是内存中;localstorage是浏览器提供的接口让你存的是文件、存在你电脑的磁盘,当然也可以把状态存到本地!
- localStorage会持久化存储,而且在多页面可以共享
localStorage无法和Vue很好的结合,修改之后不会触发View的响应式变化
localStorage修改没有记录,不利于调试和回溯 - xsf——1991已经说的比较到位了,我补充下,如果你dispatch触发vuex不是写在当前路由,刷新页面的话,之前存在vuex里的数据会被初始化掉,vuex里面的数据会丢失掉。
总结:
一开始学vuex是有点绕,但是认识清其的运行机制,多多运用到实例中。