Vuex文档通读感悟

Vuex文档通读感悟


1、为什么要用 Vuex 进行状态管理?定义一个全局对象,再去上层封装了一些数据存取的接口不也可以么?

  • Vuex 的状态存储是响应式的,当 Store 中状态发生改变时,对应的组件的视图能够得到高效的更新。
  • 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。可以方便地使用工具(vue-devtools)跟踪每一个状态的变化。

2、为什么mutation可以修改状态,还要存在一个action?mutation 和 action 有什么区别?
Vuex中的状态修改必须使用 commit(``mutation``) 修改状态,mutation 必须是同步函数,如果在 mutation 存在的异步函数中修改状态,会导致工具(vue-devtools)无法捕捉到前一状态和后一状态的快照,导致状态的改变无法追踪,用官网一句话叫: “实质上任何在(异步)回调函数中进行的状态的改变都是不可追踪的

Action 可以包含任意异步操作,Action 通过 store.dispatch 方法触发。dispatch 触发 action 去 commit mutation 进而修改 state

3、有哪些常读常新的体会?
**
原来:

computed: mapState({
    // ...
})

// 或

computed: {
	...mapState({
    // ...
	})
}

**
现在:

computed: {
  localComputed () { /* ... */ },
  // 使用对象展开运算符将此对象混入到外部对象中
  ...mapState({
    // ...
  })
}

可以将 …mapState 结构出来的 state 解构到一个对象中。


原来:
在 store 中写 getter 时只会傻傻的这么写

store.getters.doneTodos


现在:
可以在 getter 中定义一些逻辑,这样就避免了多个组件都需要处理某个状态都需要写一遍这个逻辑

getters: {
  // ...
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}


getter 还可以通过方法访问,但是,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
看看这个代码函数里面 return 函数,就是高阶函数了

getters: {
  // ...
  getTodoById: (state) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}

store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }


语法糖层面的书写:

computed: mapState({
  // 箭头函数可使代码更简练
  count: state => state.count,

  // 传字符串参数 'count' 等同于 `state => state.count`
  countAlias: 'count',

  // 为了能够使用 `this` 获取局部状态,必须使用常规函数
  countPlusLocalState (state) {
    return state.count + this.localCount
  }
})
computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
  ...mapGetters([
    'doneTodosCount',
    'anotherGetter',
    // ...
  ])
}
mapGetters({
  // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})


载荷提交

mutations: {
  increment (state, n) {
    state.count += n
  }
}

还可以使用对象形式的提交

store.commit({
  type: 'increment',
  amount: 10
})


 Vuex 的 store 中的状态是响应式的,意味着 Vuex 中的 mutation 也需要与使用 Vue 一样遵守一些注意事项:
  1. 最好提前在你的 store 中初始化好所有所需属性。
  2. 当需要在对象上添加新属性时,你应该
  • 使用 Vue.set(obj, 'newProp', 123), 或者
  • 以新对象替换老对象。例如,利用对象展开运算符我们可以这样写:原理就是替换对象在堆内存的指针地址
state.obj = { ...state.obj, newProp: 123 }


Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters

actions: {
  increment ({ commit, state, getter }) {
    commit('increment')
  }
}


模块化 Store 时,像这种并不是命名空间,而是将状态分模块挂在全局上,命名空间需要添加 namespaced: true

// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

const modulesFiles = require.context('./modules', true, /\.js$/)

const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})
// store/module/app.js
const state = {
  sidebar: true
}

const mutations = {
  CHANGE_SIDEBAR_STATE: (state) => {
    state.sidebar = !state.sidebar
  }
}

const actions = {
  changeSidebar: ({commit}) => {
    commit('CHANGE_SIDEBAR_STATE')
  }
}

export default {
  state,
  mutations,
  actions
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值