Vue之Vuex状态管理模式
Vuex
Vuex是一个专门为Vue.js应用程序开发的状态管理模式,它采用几种式存储管理应用的所有的组件状态,并以相应的规则保证状态以一种可预测的方式变化。Vuex也集成到了Vue官方调式工具devtool extension,提供了诸如零配置的time-travel调式,状态快照导入导出等高级调试功能。
虽然Vuex可以帮助我们进行管理共享状态,但也附带了更多的概念和框架,这需要对短期和长期效益进行权衡。
如果你不打算开发大型单页应用,使用Vuex可能是繁琐冗余的,一个简单的应用使用global event bus就足够需求了,
安装
npm install vuex --save
在src文件夹下新建一个vuex的文件夹,新建一个index.js
在main.js中引入组件
import store from './vuex';//可以省略/index.js new Vue({ el: '#app', router,//引入Vue的路由 store,//引入Vuex状态管理文件 components: { App }, template: '<App/>', })
1.state:单一状态数,每个应用将仅仅包含一个store实例。
this.$store.state.状态名字
...mapState(['title'])
2.getters:可以从store中的state中派生出一些状态
1.可以认为是store的计算属性
2.this.$store.getters.计算属性名字
3. ...mapGetters(['getFilms'])
3.mutations:更改Vuex的store中的状态的唯一方法是提交
常量的涉及风格
[SOME_MUTATION](state){
// mutate state
}
必须是同步函数
this.$store.commit('type','payload')
4.actions
1.Action 提交的是mutation,而不是直接变更状态,
2.Action 可以包含任意异步操作
3.this.$store.dispatch('type','payload')
5. 样式
const store = new Vuex.Store({
state:{
count:0
},
mutations:{
increment(state,payLoad){
}
},
actions:{
}
})
主要文件app.vue的代码
<template> <div id="app"> <!-- vuex验证模块 这里给keyup事件添加一个修饰后缀符.enter当点击回车才能触发--> <input type="text" autofocus="autofocus" autocomplete="off" placeholder="打算做什么" class="txt" @keyup.enter="handleEnter"><br/> <router-link to="/all">所有</router-link> <router-link to="/computed">完成</router-link> <router-link to="/active">未完成</router-link> <router-view></router-view>
<!-- 显示计算属性中由getters传过来的sum值,计算属性依赖于值,当值变化的时候,计算属性也跟着变化--> <p>未完成总数{{sum}}</p> </div> </template> <script> import {mapGetters} from 'vuex';//引入mapGetters export default { name: 'App', methods: { handleEnter(ev){ console.log(ev.target.value) this.$store.commit('add',{name:ev.target.value,isChecked:false})//用来提交数据给store,提交类型是add和vuex.js中mutations中的方法名字一样,提交的数据就是ev.target.value,用v-model来实现双向数据绑定,子组件all中checkbox的来进行通信 } }, computed: { ...mapGetters(['sum'])//引入vuex状态管理getters中的一个方法sum,它返回一个值 }, } </script> <style> /* vuex验证模块 */ .txt{outline: none;height: 60px;width: 120px;border-bottom: 1px solid #333} </style>
vuex文件夹下的index.js的文件代码
import Vuex from 'vuex'; import Vue from 'vue'; Vue.use(Vuex); const store = new Vuex.Store({ state:{ list:[]//设置一个空数组,用来存放添加进去的所有的状态。 }, mutations:{ add:(state,payLoad)=>{//这时它会传过来状态state这个对象,还会传过来真实的payLoad //console.log(payLoad) state.list.push(payLoad); } }, getters:{ activelist(state){//state代表状态属性,isChecked是true 或者 false,用filter方法进行过滤,遍历当中的属性值是true或者false,如果是false,则筛选出了未完成的 return state.list.filter(item => item.isChecked == false) }, completelist(state){//返回一个代表已完成的数组 return state.list.filter(item => item.isChecked == true) }, sum(state){//返回一个未完成总数 return state.list.filter(item => item.isChecked == false).length }, }, }) export default store;
并且需要添加几个组件来练习Vuex状态管理,router文件夹下的index.js代码
import Vue from 'vue' import Router from 'vue-router' import All from '@/components/all' import Active from '@/components/active' import Computed from '@/components/computed' Vue.use(Router) export default new Router({ routes: [ { path: '/all', component: All }, { path: '/active', component: Active }, { path: '/computed', component: Computed }, ] })
在components文件夹下添加相应的vue组件,active.vue all.vue computed.vue三个组件
active.vue
<template> <div>我是未完成组件 <ul> <li v-for="data in activelist"><input type="checkbox" v-model="data.isChecked">{{data.name}}</li> </ul> </div> </template> <script> import {mapGetters} from 'vuex'; export default { name:'active', data() { return { } }, computed: { ...mapGetters(['activelist'])//用简写方式,mapGetters的方法将数据引用出来,将vuex中的index.js的方法名引用进来,因此在当前的页面就可以获取到activelist这个实例 }, } </script> <style> </style>
all.vue
<template> <div> all组件 <ul>
<!--返回了list实例后,可以遍历其中的元素来显示在这个组件中,list里面包含了对象name 和 isChecked的属性 --> <li v-for = "data in list"><input type="checkbox" v-model="data.isChecked"> <!-- 当data.isChecked是true的时候,delTxt这个类样式就会生效 --> <span :class="{delTxt:data.isChecked}">{{data.name}}</span> </li> </ul> </div> </template> <script> import {mapState} from 'vuex';//引入mapState export default { name:'all', data() { return { } }, computed: { ...mapState(['list'])//包含一个命名为list的实例 }, } </script> <style lang="scss" scoped> .delTxt{text-decoration: line-through} </style>
computed.vue
<template> <div>我是已完成组件 <ul> <li v-for="data in completelist"> <input type="checkbox" v-model="data.isChecked"> <span :class="{delTxt:data.isChecked}">{{data.name}}</span></li> </ul> </div> </template> <script> import {mapGetters} from 'vuex'; export default { name:'computed', data() { return { } }, computed: { ...mapGetters(['completelist']) }, } </script> <style scoped> .delTxt{text-decoration: line-through} </style>