美文网首页
组件状态管理

组件状态管理

作者: 翔子丶 | 来源:发表于2021-03-16 17:01 被阅读0次
组件内状态管理流程

Vue最核心的两个功能:数据驱动和组件化

组件化开发给我们带来了:

  • 更快的开发效率
  • 更好的可维护性

每个组件都有自己的状态、视图和行为等组成部分

new Vue ({
    // state
    data () {
        return {
            count: 0
        }
    },
    // view
    template: `
        <div>{{ count }}</div>
    `,
    // actions
    methods: {
        increment () {
            this.count++
        }
    }
})

状态管理包含一下几部分:

  • state:驱动应用的数据源

  • view:以声明方式将state映射到视图

  • actions:响应在view上的用户输入导致的状态变化

image-20210315195501466.png
组件间通信方式

大多数场景下的组件都并不是独立存在的,而是相互协作共同构成了一个复杂的业务功能。在 Vue 中为 不同的组件关系提供了不同的通信规则。


image-20210315195537146.png

组件通信方式主要有以下几种:

  • 父传子:Props Down

    这里的props是以字符串数组形式列出的 prop,还可以进行类型检查和其它 prop 验证

    // 父组件
    <blog-post title="My journey with Vue"></blog-post>
    // 子组件
    Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{ title }}</h3>'
    })
    
  • 子传父:Event up

    <!-- 子组件 在子组件中使用 $emit 发布一个自定义事件-->
    <button v-on:click="$emit('enlargeText', 0.1)">
        Enlarge text
    </button>
    
    <!-- 父组件 使用 v-on 监听这个自定义事件-->
    <blog-post v-on:enlargeText="hFontSize += $event"></blog-post>
    
  • 非父子组件:Event Bus

    // eventBus.js 使用 Event Bus 来解决非父子组件传值问题
    export default new Vue()
    
    // 通信两端 使用$on订阅 使用$emit发布
    // 有参数
    bus.$on('自定义事件名称', data => {
      // 执行操作
    })
    // 有自定义传参
    bus.$emit('自定义事件名称', 数据)
    
    // 没有参数
    bus.$on('自定义事件名称', () => {
    // 执行操作
    })
    // 没有自定义传参
    bus.$emit('自定义事件名称')
    
  • 父直接访问子组件:通过ref获取子组件实例

    ref有两个作用:

    • 如果作用在普通HTML标签上,则获取到的是DOM
    • 如果作用在组件标签上,则获取到的是组件实例
    // base-input组件
    <template>
      <input ref="input">
    </template>
    <script>
        export default {
            methods: {
                // 用来从父级组件聚焦输入框
                focus: function () {
                    this.$refs.input.focus()
                }
            }
        }
    </script>
    // 父组件中使用ref获取子组件实例
    <base-input ref="usernameInput"></base-input>
    // 然后在父组件等渲染完毕后使用 $refs 访问
    <script>
        mounted () {
            this.$refs.usernameInput.focus()
        }
    </script>
    
简易的状态管理方案

如果多个组件需要共享状态,使用上述方法可以实现,但是比较麻烦,而且多个组件之间互相传值很难追踪数据变化,问题难被定位。

当遇到多个组件需要共享状态时:典型场景如购物车,会遇到一下问题

  • 多个视图依赖于同一状态
  • 来自不同视图的行为需要变更同一状态

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对兄弟组件间的状态传递无能为力,不宜管理

对于问题二,经常会采用父子组件直接引用或通过事件来变更和同步状态的多份拷贝,会导致代码难以维护

因此,我们为什么不把组件的共享状态抽出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或触发行为

可以把多个组件的状态,或者整个程序的状态放到一个集中的位置存储,并且可以检测到数据的变更,可以以一种简单的方式实现

// 1.创建共享仓库store对象 全局唯一对象
// 所有的状态都在store中管理,任意组件都可以导入并使用其中的状态,更改状态在store中实现;通过特殊手段,记录每次状态变化
export default {
    debug: true, // 方便调试
    state: {
        user: {
            name: 'xiaoming',
            age: 12,
            sex: '男'
        }
    },
    setUserNameAction (name) {
        if (this.debug) {
            console.log('setUserNameACtion triggered:' + name)
        }
        this.state.user.name = name
    }
}
// 2.将store对象存储到需要共享状态的组件的data中
<template>
    <h1>{{ sharedState.user.name }}</h1>
</template>
import store from './store'
export default {
    data () {
        return {
            privateState: {}, // 特有状态
            sharedState: store.state // 共享状态
        }
    },
    methods: {
        // 点击按钮调用action修改状态
        change () {
            store.setUserNameAction('xiaoli')
        }
    }
}

接着继续延伸约定,组件不允许直接变更store对象的state,而应该通过触发action来分发(dispatch)事件通知store去改变,这样最终就会和Vuex结构类似。

约定的好处是:

  • 记录所有store中发生的state变更
  • 记录变更、保存状态快照、历史回滚/时光旅行等

相关文章

  • 学习笔记(十八)Vuex状态管理

    Vuex状态管理 组件状态管理及组件间通信回顾 状态管理 状态集中管理和分发,解决多个组件共享状态的问题 状态自管...

  • 轻松flutter之 组件状态管理

    管理状态的最常见的方法: 方法描述自身状态管理Widget管理自己的状态。父组件管理子组件状态父Widget管理子...

  • 五(2)、React之类组件 ------ 2019-11-01

    1、类组件 2、类组件的状态管理:

  • 组件状态管理

    组件内状态管理流程 Vue最核心的两个功能:数据驱动和组件化 组件化开发给我们带来了: 更快的开发效率 更好的可维...

  • vuex基础

    1.vuex是什么? 状态管理模式,集中式存储管理,多组件需要共享状态时使用vuex 1.1状态管理模式 单个组件...

  • InheritedWidget 共享数据组件

    Flutter中私有组件可以管理自身状态,当需要跨组件管理状态时可以用到InheritedWidget,Inher...

  • Flutter StatefullWidget 三种状态管理De

    在Flutter中,组件的状态管理还是非常重要的,组件要么是无状态的组件,要么是有状态的组件。无状态的组件使用起来...

  • Vuex状态管理

    简介 Vuex用作共享状态管理或者复杂跨组件通信(非父子组件)。共享状态管理如登录状态、用户信息、购物车等等。包含...

  • Flutter状态管理之路(一)

    背景 原生提供了StatefulWidget这个有状态组件来管理状态,对于多组件的状态交互可以选择由父组件进行统一...

  • 【Flutter】多组件共用状态,父组件状态传递给子组件

    场景:多个组件共用一个状态,子组件通过方法改变父组件状态思路:状态和管理方法定义在父组件,通过构造函数传递给子组件...

网友评论

      本文标题:组件状态管理

      本文链接:https://www.haomeiwen.com/subject/agvdcltx.html