任务一:Vuex 状态管理
1、课程目标
Vue 组件间通信方式回顾
Vuex 核心概念和基本使用回顾
购物车案例
模拟实现 Vuex
2、组件内的状态管理流程
状态管理:
state:驱动应用的数据源
view:以声明方式将 state 映射到视图
actions:响应在 view 上的用户输入导致的状态变化
3、组件间通信方式回顾
四种通信方式:
父组件给子组件传值
子组件通过 props 接收数据
父组件中给子组件通过相应属性传值
子组件给父组件传值
子组件通过 this.$emit(fn, data)
父组件中给子组件通过 v-on:子组件emit的函数名=父组件函数名
不相关组件传值
import Vue from 'vue'
export default new Vue ( )
< template>
< div>
< h1> Event Bus Sibling01< / h1>
< div class = "number" @click= "sub" > - < / div>
< input type= "text" style= "width: 30px; text-align: center" : value= "value" >
< div class = "number" @click= "add" > + < / div>
< / div>
< / template>
< script>
import bus from './eventbus'
export default {
props: {
num: Number
} ,
created ( ) {
this . value = this . num
} ,
data ( ) {
return {
value: - 1
}
} ,
methods: {
sub ( ) {
if ( this . value > 1 ) {
this . value--
bus. $emit ( 'numchange' , this . value)
}
} ,
add ( ) {
this . value++
bus. $emit ( 'numchange' , this . value)
}
}
}
< / script>
< style>
. number {
display: inline- block;
cursor: pointer;
width: 20 px;
text- align: center;
}
< / style>
< template>
< div>
< h1> Event Bus Sibling02< / h1>
< div> {
{
msg } } < / div>
< / div>
< / template>
< script>
import bus from './eventbus'
export default {
data ( ) {
return {
msg: ''
}
} ,
created ( ) {
bus. $on ( 'numchange' , ( value) => {
this . msg = `您选择了 ${
value} 件商品`
} )
}
}
< / script>
< style>
< / style>
通过 ref 获取子组件
ref 两个作用
在普通 HTML 标签上使用 ref,获取到的是 DOM
< template>
< div>
< h1> ref Child< / h1>
< input ref= "input" type= "text" v- model= "value" >
< / div>
< / template>
< script>
export default {
data ( ) {
return {
value: ''
}
} ,
methods: {
focus ( ) {
this . $refs. input. focus ( )
}
}
}
< / script>
< template>
< div>
< h1> ref Parent< / h1>
< child ref= "c" > < / child>
< / div>
< / template>
< script>
import child from './04-Child'
export default {
components: {
child
} ,
mounted ( ) {
this . $refs. c. focus ( )
this . $refs. c. value = 'hello input'
}
}
< / script>
4、Vuex 回顾
什么是 Vuex:
Vuex 专门为 Vue.js 设计的状态管理库
Vuex 采用集中式的方式存储需要共享的状态
Vuex 的作用是进行状态管理,解决复杂组件通信,数据共享
Vuex 集成到了 devtools 中,提供了 time-travel 时光旅行历史回滚功能
什么情况下使用 Vuex
非必要的情况下不要使用 Vuex
大型的单页应用程序
多个视图依赖于同一状态
来自不同视图的行为需要变更同一状态
5、Vuex 核心概念回顾
Store: 是一个容器,包含着应用中的大部分状态,不能直接改变 store 中的状态,要通过 mutation 的方式改变状态。
State:是状态,保存在 Store 中,因为 Store 是唯一的,所以 State 也是唯一的,也称为单一状态树。这里的状态是响应式的。
Getter:是 Vuex 中的计算属性,方便从一个属性派生出其他的值。它内部会对计算的属性进行缓存,只有当依赖改变的时候,才会重新进行计算。
Mutation:状态的变换必须要通过提交 Mutation 来完成。
Action:和 MuTation 类似,不同的是 Action 可以进行异步的操作,内部改变状态的时候,都需要提交 Mutation。
Module:当 Store 太过臃肿时,可以将 Store 分成多个模块,每个模块里有 State、Mutation、Action、Getter,甚至是子模块。
6、State
export default new Vuex. Store ( {
state: {
count: 0 ,
msg: 'Hello Vuex'
} ,
mutations: {
} ,
actions: {
} ,
modules: {
}
} )
< template>
< div id= "app" >
< h1> Vuex - Demo< / h1>
< ! -- count:{
{
count } } < br>
msg: {
{
msg } } -- >
< ! -- count:{
{
$store. state. count } } < br>
msg: {
{
$store. state. msg } } -- >
count: {
{
num } } < br>
msg: {
{
message } }
< / div>
< / template>
< script>
import {
mapState } from 'vuex'
export default {
computed: {
... mapState ( {
num: 'count' , message: 'msg' } )
}
}
< / script>
7、Getter
export default new Vuex. Store ( {
state: {
count: 0 ,
msg: 'Hello Vuex'
} ,
getters: {
reverseMsg ( state) {
return state. msg. split ( '' ) . reverse ( ) . join ( '' )
}
} ,
mutations: {
} ,
actions: {
} ,
modules: {
}
} )
< template>
< div id= "app" >
< h1> Vuex - Demo< / h1>
reverseMsg: {
{
reverseMsg } }
< / div>
< / template>
< script>
import {
mapState, mapGetters } from 'vuex'
export default {
computed: {
... mapGetters ( [ 'reverseMsg' ] )
}
}
< / script>
8、Mutation
< template>
< div id= "app" >
< h1> Vuex - Demo< / h1>
< ! -- count:{
{
count } } < br>
msg: {
{
msg } } -- >
< ! -- count:{
{
$store. state. count } } < br