Vue 组件之间通信以及状态管理模式(Vuex)

发布于 2023-05-12 08:51:11 字数 3326 浏览 50 评论 0

一、使用 props

props 用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值。这种方式,不能在子组件更改父组件的对应的属性值

<!-- 父组件 -->
<template>
  <child message="这是父组件给子组件的信息"></child>
</template>

<script>
import Child from '../xxx/xxx'
export default {
  components: { Child }
}
</script>
<!-- 子组件 -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: ['message']
}
</script>

props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态。

若一定要改,只能通过子组件 $emit(),父组件 $on() 进行响应更改,如在更复杂的情况下,建议使用状态管理模式,即 Vuex。下面会讲述这两种方式的具体使用方式。

二、$emit()、$on() 非父子组件间的通信(简单场景)

$emit()$on()和的事件必须是在一个公共的实例上,才能触发。官方文档里这个主要用于非父子组件之间的通信。

下面对这个例子简单修改一下:

// 新建一个公共示例
// bus.js
import Vue from 'vue'
export const bus = new Vue()
<!-- 父组件 -->
<template>
  <child :message="message"></child>
</template>

<script>
import Child from '../xxx/xxx'
// 引入公共实例
import { bus } = from 'xxx/bus.js'
export default {
    components: {Child},
    data() {
      return {
         message: '这是父组件给子组件的信息'
      }
    },
  mounted() {
    // $on() 响应
    bus.$on('change', (msg) => {
      console.log(msg)
    })
  }
}
</script>
<!-- 子组件 -->
<template>
  <div>{{ message }}</div>
</template>

<script>
import { bus } from 'xxx/bus.js'
export default {
  props: ['message'],
  watch: {
    message(newVal, oldVal) {
      // 通过 $emit() 去触发
      bus.$emit('change', '要改变的值')
    }
  }
}
</script>

三、使用 Vuex 进行状态管理(主要用于较为复杂场景),划重点

1、安装 Vuex

npm install vuex --save

2、新建 store.js ,将 Vuex 放在里面,我就不放 main.js 里了

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

/**
 * 说明:
 *
 * 一、Mutations
 * 1. 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
 * 2. 一条重要的原则就是要记住 mutation 必须是同步函数
 *
 * 二、Action
 * 1. action 提交的是 mutation,而不是直接变更状态
 * 2. action 可以包含任意异步操作
 * 3. 所以我更喜欢使用 action 去提交 mutation,例如下面这个异步操作
 *
 */

const store = new Vuex.Store({
  // 定义状态
  state: {
    message: ''
  },
  mutations: {
    changeMessage(state, payload) {
      // 状态变更
      state.message = payload
    }
  },
  actions: {
    changeMessage(context, args) {
      context.commit('changeMessage', args)
      setTimeout(() => {
        // 1.5s 后置空
        context.commit('changeMessage', '')
      }, 1500)
    }
  }
})

export default store

3、main.js 引入

import Vue from 'vue'
import App from './App.vue'
import store from './store.js'

new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

4、提交载荷、分发 Action、获取状态

// 以下 this 指向 vue 实例

// 提交 Payload,仅支持同步操作
this.$store.commit('changeMessage', 'any')

// 分发 Action,支持异步操作
this.$store.dispatch('changeMessage', 'any')

// 获取 state
const var1 = this.$store.state.message

写得有点啰嗦了,更具体或者细节的地方,麻烦移步官方文档: Vuex 是什么?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

滥情稳全场

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

亽野灬性zι浪

文章 0 评论 0

少年亿悲伤

文章 0 评论 0

南七夏

文章 0 评论 0

qq_EJoXxu

文章 0 评论 0

17780639550

文章 0 评论 0

萌逼全场

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文