@lizlalala
2017-01-10T09:20:13.000000Z
字数 3393
阅读 1702
vuex vue的坑
state
Vuex提供了机制,使得设置 store选项(启用Vue.use(Vuex))会将 store 从根组件『注入』到每一个子组件中。
const app = new Vue({el: '#app',// 使用 "store" 选项后,可以注册 store 对象。将会把 store 实例注入到所有子组件。store,components: { Counter },template: `<div class="app"><counter></counter></div>`})
子组件中可以通过this.$store.state.someprop访问
mapState:
computed: mapState({count: state => state.count,countAlias: 'count','count',countPlusLocalState (state) {return state.count + this.localCount}})或者用对象扩展方法将mapState作为computed的部分computed:{test1(){..},...mapState({})}
getters
类似于store的计算属性函数,接受state作为第一个参数
const store = new Vuex.Store({state: {},getters: {doneTodos: state => ...}})
组件中用this.$store.getters.blah访问
Mutations
actions
更新2
1. 需要注意的是,整个操作中只通过在store里面提交mutations来实现数据的更改,(便于用dev-统一tool去统一跟踪)。
2. 总的来说,vuex解决的是用纯数据交互的方式来处理原本属于组件间(sibling组件)的通信,有人会说那我用event也可以做到通信啊,但是当组件创建、销毁时,这些状态也随之变动,因此需要有一个独立于组件的状态树来进行维护。在知乎上看到一个回答,挺好的:
Vuex的主要作用是各组件间的状态同步(以及同一组件再次显示时的状态保持)。
特别是非数据库内容。比如网页右上角的搜索框,并不像日志列表那样对应数据库内容。
如果不希望每次进入有搜索框的模板页面,搜索框内容都被重置,那么就需要高于组件的架构
题外话:
以往的操作是:
- parentA
- childB
- childC
子组件(B,C)要调用A的回调,那么通过props传递到B,C即可。
A中要调用B.C的方法/属性,那么也可以通过props回调,然后把B,C的属性/方法作为参数 this.props.Afn(bVal,cVal,bFn,cFn)这样。(当然这是在B,C内部操作)。如果一定要在A中执行,可以this.ref.B.blah(以react为例)
在vue中,通信中props的部分跟react一样,当然也可以通过(特别是孙孙组件这种层级特别多的)事件,B,C中emit,A中on
而事件也适用于sibling之间的通信,如B,C。
栗子可以看react
以shopping-cart为例来分析vuex的goods
子组件为cart和products。购物车和商品列表。
[{input: 'tet', //不会改变外部select: ['test1','test2']//会作用于外部}]
这样就违背了数据单向传递的目的,那么所有引用这个wigetList的值都会相应的被变化。
应该是props传递进来的时候用的浅复制,类似于Object.assign.
对每个key遍历赋值,然后基本类型都赋值,但是引用赋的还是对象。
一种解决方案是传递immutable数据(蠢蠢的方法是JSON序列化掉然后传进来...)。
还有一种是虽然传引用,但是赋值(data用props初始化的时候)用深拷贝(这边用的lodash的深拷贝)。
import cloneDeep from 'lodash/cloneDeep'data() {return {showModal: this.show,wigets: cloneDeep(this.wigetList), //hereform: {...wigetTest}};},watch:{show(val){this.showModal = val;},wigetList(val){this.wigets = cloneDeep(val); //here ~}
//page1:watch: {'$route'(to,from) {//监听tab导致的路由变动if(to.query && to.query.tab){this.$store.dispatch('changeTab',to.query.tab).then(()=>{this.reset();})}}},//根storeconst actions = {changeTab({commit},tab){//返回一个promisereturn new Promise((resolve,reject)=>{commit(types.CHANGE_TAB,tab);resolve();})}}