# 状态管理流程
- state,驱动应用的数据源
- view,以声明方式将 state 映射到视图
- actions,响应在 view 上的用户输入导致的状态变化
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `<div>{{count}}</div>`,
// actions
methods: {
increment () {
this.count++
}
}
})
# 组件间通信方式
# 父传子:props Down (opens new window)
<blog-post title="My journey with Vue"></blog-post>
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{title}}</h3>'
})
# 子传父:Event Up (opens new window)
子组件:
<button v-on:click="$emit('enlargeText', 0.1)">
enlarge text
</button>
<blog-post v-on:enlargeText="hFontSize += $enent"></blog-post>
# 非父子组件: Event Bus (opens new window)
eventbus.js
export default new Vue()
在需要通信的两端: 使用 $on 订阅:
// 没有参数
bus.$on('自定义事件名称', () => {
// 执行操作
})
// 有参数
bus.$on('自定义事件名称', data => {
// 执行操作
})
// 使用 $emit 发布:
// 没有自定义传参
bus.$emit('自定义事件名称')
// 有自定义传参
bus.$emit('自定义事件名称', 数据)
# 其他常见方式
- $root
- $parent
- $children
- $refs
- 在普通html标签使用ref,获取dom
- 在组件上使用ref,获取组件实例
# 简易的状态管理方案
问题:
- 多个视图依赖同一状态
- 来自不同视图的行为需要变更同一状态 store.js
export default { debug: true, state: { user: { name: 'xiaomao', age: 18, sex: '男' } }, setUserNameAction (name) { if (this.debug) { console.log('setUserNameAction triggered:', name) } this.state.user.name = name } }componentA
<template> <div class="page"> <h1>compentA</h1> user name: {{ sharedState.user.name}} <button @click="change">change info</button> </div> </template> <script type="text/ecmascript-6"> import store from './store' export default { data() { return { private: {}, sharedState: store.state } }, methods: { change () { store.setUserNameAction('componentA') } } } </script>componentB
<template> <div class="page"> <h1>compentA</h1> user name: {{ sharedState.user.name}} <button @click="change">change info</button> </div> </template> <script type="text/ecmascript-6"> import store from './store' export default { data() { return { private: {}, sharedState: store.state } }, methods: { change () { store.setUserNameAction('componentB') } } } </script>
# VueX
- Vuex 是专门为Vue.js设计的状态管理库
- Vuex 采用集中式的方式储存需要共享的状态
- Vuex 的作用是进行状态管理,解决了复杂组件通信,数据共享
- Vuex 集成到了 devtools中,提供了time-travel时光旅行历史回滚功能
# 什么情况下使用vuex
- 非必要情况不要使用Vuex
- 大型的单页应用程序
- 多个视图依赖于同一状态
- 来自不同视图的行为需要变更同一状态
# Vuex核心概念
Store
State
Getter
Mutation
Action
Module
<!-- count: {{ $store.state.count }}<br> msg: {{ $store.state.msg }} --> <!-- count: {{ count }}<br> msg: {{ msg }} --> count: {{ num }}<br> msg: {{ message }} <h2>Getters</h2> reverseMsg: {{ $store.getters.reverseMsg }} reverseMsg: {{ reverseMsg }} <h2>Mutation</h2> <!-- increate mutation的事件,要通过commit提交 第二个参数payload --> <button @click="$store.commit('increate', 2)">Mutation</button> <button @click="increate(3)">Mutation</button> <h2>Action</h2> <!-- action 调用要通过dispatch 等用于 mutation调用要通过commit一样 --> <!-- 调用actions中的increateAsync方法,在increateAsync中调用increate方法,去更改状态 --> <button @click="$store.dispatch('increateAsync', 5)">Action</button> <button @click="increateAsync(5)">Action</button> <h2>module</h2> <!-- products: {{ $store.state.products.products }} <button @click="$store.commit('setProducts', [])">Mutation</button> --> products: {{ products }} <button @click="setProducts([])">Mutation</button> <h2>strict</h2> <button @click="$store.state.msg = 'LaGou'">strict</button> </div>import { mapState, mapGetters, mapMutations, mapActions } from 'vuex' import store from './store' export default { data() { return { private: {}, sharedState: store.state } }, computed: { // 自动生成状态对应的计算属性 // 接受数组作为一个参数 也可以是对象 // count: state => state.count // ...mapState(['count', 'msg']) ...mapState({num: 'count', message: 'msg'}), // vuex中getter映射到组件中的计算属性,返回的是对象 ...mapGetters(['reverseMsg']), ...mapState('products', ['products']) }, methods: { change () { store.setUserNameAction('componentA') }, // map函数把mutation映射到当前的methods中 // 传入数组或者对象 ...mapMutations(['increate']), // 映射的方法 返回一个对象,对象中的方法封装了dispatch的调用 ...mapActions(['increateAsync']), ...mapMutations('products', ['setProducts']) } }
# Vuex 插件介绍
- Vuex的插件就是一个函数
- 这个函数接收一个 store 的参数
const myPlugin = store => { // 当 store 初始化后调用 store.subscribe((mutation, state) => { // 每次mutation 之后调用 // mutation 的格式为 { type, payload } type为命名空间 carts/addToCart }) } const store = new Vuex.Store({ // ... plugins: [myPlugin] })