组件内的状态管理
状态管理流程
状态管理
- state:驱动应用的数据源
- view:声明方式将state映射到视图
- actions:响应在view上的用户输入,导致的状态变化
单向数据流
组件之间通信方式
父组件给子组件传值
- 子组件中通过声明props来接收数据
- 父组件通过相应属性给子组件传值
子组件给父组件传值
- 父组件监听自定义事件
- 子组件使用
$emit()
触发自定义事件,抛出值(内联代码可以用$event
拿到该值)
不相关的组件传值
- 使用自定义事件传值
- 不相关的组件没有父子关系,所以需要一个事件总线,作为发布-订阅模式的中心,中心是一个Vue实例,使用
$emit
发布事件和$on
订阅事件 - A组件给B组件传值,则A组件内使用
$emit
发布事件,在B组件内使用$on
来监听事件
通过ref来传值(不推荐使用,数据管理混乱)
- 在HTML普通标签上使用ref,可以获取DOM元素
- 在组件标签上使用ref,可以获取组件实例
简易的状态管理方案
- 使用全局变量store作为状态管理的中心
- 在store中,state属性用来存储状态,并且是响应式数据
- 在store中,定义更改state的方法,组件通过调用这些方法来更新state
Vuex
- 集中式存储共享状态
- 状态管理,数据共享
- devtools,time-travel功能
使用场景
- 非必要的情况不要使用Vuex
- 大型单页应用适用,如购物车
核心概念
- Store:状态容器,全局唯一
- State:保存状态
- Getter:类似Vuex中的计算属性,对结果进行缓存,只有依赖的状态变化才会重新计算
- Mutation:提交Mutation才能更改状态
- Action:派发Action来进行更改状态,该过程中可能会有异步操作,所以Action并不一定会更改状态
- Module:每个module拥有自己的state
基本使用结构
import Vue from 'Vue'
import Vuex from 'vuex'
Vue.useE(Vuex)
export default new Vuex.store({
strict: process.env.NODE_ENV !== 'production',
state: {},
getters: {},
mutations: {},
actions: {},
modules: {}
})
import store from './store'
new Vue({
router,
store,
render: (h) => h(App)
}).$mount('#app')
模拟Vuex
const _Vue = null
class Store {
constructor(options) {
const {
state = {},
getters = {},
mutations = {},
actions = {}
} = options
this.state = _Vue.observable(state)
this.getters = Object.create(null)
Object.keys(getters).forEach(key => {
Object.defineProperty(this.getters, key, {
get () {
return getters[key](state)
}
})
})
this._mutations = mutations
this._actions = actions
}
commit (type, payload) {
this._mutations[type](this.state, payload)
}
dispatch(type, payload) {
this._actions[type](this, payload)
}
}
function install(Vue) {
_Vue = Vue
_Vue.mixin({
beforeCreate () {
if(this.$options.store) {
_Vue.prototype.$tore = this.$options.store
}
}
})
}
export default {
Store,
install
}