微信小程序时期_详解vue组件之间的通信

日期:2021-01-05 类型:行业动态 

关键词:如何制作微信小程序,微信小程序源码,小程序码生成,凡科网微信小程序,微信公众号小程序

详解vue组件之间的通信       这篇文章主要介绍了vue组件之间的通信,帮助大家更好的理解和学习前端的相关知识,感兴趣的朋友可以了解下

说明:下面我总结了比较常用的vue组件之前通信的方式,最近准备面试,所以有些总结贴上来分享

pro凡科抠图和$emit

只有父子关系才可以用这种方式,父组件向子组件传递参数用pro凡科抠图,子向父传递使用触发$emit自定义事件

1.pro凡科抠图

 !-- parent.vue, 可以传递`静态`的pro凡科抠图和`动态`的pro凡科抠图, 静态的参数只能是个String类型的,如果是其他类型的一定要记得加`:`来表示这是一个 js 表达式而不是一个字符串 -- 
 Child :name="name" :age="18" address="xxxxx" /Child 
data () {
 return {
 name: 'marry'
 !-- 传一个参数所有pro凡科抠图, 虽然目前我没有这个需求,使用不带参数的 v-bind -- 
 blog-post v-bind="post" /blog-post 
post: {
 id: 1,
 title: 'My Journey with Vue'
//等价于下面
 blog-post
 v-bind:id="post.id"
 v-bind:title="post.title"
 /blog-post 

//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告 //注意:以下类型不能写成'String'这种带引号的形式 pro凡科抠图: { // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证) propA: Number, // 多个可能的类型 propB: [String, Number], // 必填的字符串 propC: { type: String, required: true // 带有默认值的数字 propD: { type: Number, default: 100 // 带有默认值的对象 propE: { type: Object, // 对象或数组默认值必须从一个工厂函数获取 default: function () { return { message: 'hello' } // 自定义验证函数 propF: { validator: function (value) { // 这个值必须匹配下列字符串中的一个 return ['success', 'warning', 'danger'].indexOf(value) !== -1 //注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (puted 等) 在 default 或 validator 函数中是不可用的。

2.$emit

 !-- parent.vue -- 
 Child @my-event="myEvent" /Child 
methods: {
 myEvent(name){
 this.name = name
 !-- child.vue -- 
 div 
 button @click="$emit('my-event', name)" /button 
 /div 
//使用自定义事件将子组件的值抛给父组件

中央事件总线 bus

用于解决跨级和兄弟组件通信问题,巧妙的使用一个公共的vue实例,利用$on, $emit, $off(移除自定义事件监听器)

方法一:

可以在main.js中,在Vue的原型上挂载一个公共的Vue实例 $bus,这样全局任何一个地方都可以使用

Vue.prototype.$bus = new Vue()

然后在需要的地方注册自定义事件和接收参数的回调函数

this.$bus.$on('changeName', name = {
 this.name = name
})

在需要改变的时候触发事件并抛出参数

this.$bus.$emit('changeName', 'wzj')

方法二:

定义一个util.js文件

import Vue from 'vue'
const bus = new Vue()
export default bus

在需要用到bus的文件中引入

import bus from '../util' //文件路径不一定
//在一个文件定义事件
bus.$on('changeName', name = {
 this.name = name
//另一个文件抛出参数
bus.$emit('changeName', 'wzj')

vuex

对于项目比较复杂,多组件共享状态,不同层级需要通信

核心概念:

state, getter, mutation, action, module

//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export dafault new Vuex.Store({
 state: {
 name: '',
 age: 0
 getters: {
 tranName(state){
 return 'name: ' + state.name
 mutations: {
 changeName(state, name){
 state.name = name
 /*Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,mit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */
 actions: { //mit触发mutations函数操作state
 changeName(context, name){
 mit('changeName', name)
 modules: {}
})

在组件中使用

方法一:

//访问state属性
this.$store.state.name
//访问getters属性
this.$store.getters.tranName
//访问mutations
this.$mit('changeName', 'wzj')
//访问actions
this.$store.dispatch('changeName', 'wzj')

方法二:使用辅助函数映射到本地,这里只列举了简便的方式,更多查阅官网吧

import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
//state 和 puted属性中,作为计算属性使用
computed: {
 ...mapState(['name', 'age']),
 ...mapGetters(['tranName'])
//mutations 和 actions
methods: {
 // 将 `this.changeName()` 映射为 `this.$mit('changeName')`
 ...mapMutations(['changeName']) 
 // 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')`
 ...mapActions(['changeName'])
}

$attrs 和 $listeners

父组件与后代组件,用以上方法有点大材小用或者第一种有些不方便

$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 ( class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。 $listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

理解:其实祖先组件的属性和事件还是一层层往下传,不过用$attrs 和 $listeners优化和简便了传递过程中书写,而且在传递的过程中,任何一个声明了 $listeners的组件都可以触发里面的所有事件,而声明了$attrs的组件只能使用之前未用pro凡科抠图声明的剩下的属性。

以上就是vue组件之间的通信的详细内容,更多关于vue 组件通信的资料请关注凡科其它