vue组件间的几种通信方式

本文介绍了Vue.js中组件间的通信方式,包括props和$emit的双向绑定,使用refs读取子组件属性,兄弟组件通过父组件传递消息,利用provide和inject进行祖先与后代通信,以及事件总线模式。此外,还讨论了自定义指令实现权限控制,以及插槽内容分发和渲染函数在构建组件时的应用。
摘要由CSDN通过智能技术生成

通信

props和$emit双向通信
{{closeDialog}}
<script>
export default {
  props: {
    shouldClose: Boolean
  },
  methods: {
    onClose() {
      <!--子组件不能修改closeDialog的值,而是需要发布一个事件 让父组件修改这个值-->
      this.$emit('shouldCloseEvent', true)
    }
  }
}
</script>
<div>
<!--将子之间的shouldClose和本地的shouldClose绑定,
监听到shouldCloseEvent事件触发后 更改shouldClose的值,从而更改子组件的值-->
<child :should-close="shouldClose"
              @shouldCloseEvent="() => this.shouldClose = !this.shouldClose"/>
</div>
refs

父读子的属性

<child ref="headInfo"></child>
this.$refs.headInfo.某个属性
兄弟组件通信
<!--bro1: 发布事件-->
this.$parent.$emit('handle')

<!--bro2: 监听事件并事件的处理逻辑绑定到doHandle方法上-->
this.$parent.$on('handle', doHandle)
provide和inject

后代访问祖先的属性(祖先要先把属性暴露出来)

<!--祖先暴露一个名字为“属性1”的属性-->
provide() {
  return {
    属性1: 属性值
  }
}

<!--childChild 后代取出这个属性-->
inject: [属性1]
事件总线
<script>
// main.js
Vue.prototype.$bus = new Bus();

// 任意两个组件通信
this.$bus.$on('event', doEvent);
this.$bus.$emit('event');


// 不用new Bus();
// vue实例本身就是个事件总线
</script>

自定义指令

<!--用户权限-->
const role = 'user';

<!--自定义指令-->
Vue.directive('permission', {
  inserted(el) {
    if ('admin' !== role) {
      <!-- 如果没有admin权限就把这个DOM移除了 -->
      <!-- 当前用户的权限从state中获取 -->
      <!--按钮的权限可以放进数据库中,用map维护。map的key为按钮的编号,value是一个数组对象-->
      el.parentElement.removeChild(el);
    }
  }
})

<!--使用指令-->
<!--按钮的权限可以放进数据库中,用map维护。map的key为按钮的编号,value是一个数组对象-->
<page v-permission="role">这个页面需要用户具有管理员权限才能访问</page>
<button v-permission="role">这个按钮需要用户具有管理员权限才能点击</button>

插槽内容分发

普通插槽:子组件中留出了一部分空间让父组件填充数据(填充一个页面、填充数据等等)
作用域插槽:子组件可以把属性通过插槽暴露出去,让父组件把属性重新渲染后放到插槽中
(重新渲染是指:把属性放到一个新的页面中。实现的效果是 都是一样的数据 但是样式不一样)

<child>
  <!-- 默认插槽 -->
  <slot></slot>
  
  <!-- 具名插槽 -->
  <slot name="名字1"></slot>
  
  <!-- 作用域插槽 -->
  <slot name="名字2" :属性="暴露一个属性"></slot>
</child>


<parent>
  <child>
    <!-- 默认插槽  -->
    <template v-slot:default>(内容)可以是一个页面,一些数据等等</template>
    
    <!--  使用具名插槽  -->
    <template v-slot:名字1>内容</template>
  
    <!-- 作用域插槽  -->
    <template v-slot:名字2="context">获取子组件的属性然后重新渲染{{context.属性}}</template>
  </child>
</parent>

渲染函数了解。

虚拟DOM(VNode)就是HTML标签的抽象,抽象为js对象。
需要借助解释器将VNode解析为浏览器可以识别的HTML文本。
diff算法的作用对象就是VNode,(VNode对象肯定在内存中处理速度快)
哪个VNode发生了改变动态更新对应的HTML文件就行了。
render函数的声明。

<!--这是render函数的声明,可以看出render函数的功能是借助createElement函数实现的-->
render: function(createElement) {
  return createElement();
}
<!--createElement函数返回的是VNode,VNode是原生的js对象(diff然后更新页面)-->
完整的render函数
render: function(createElement) {
  return createElement(tag, data, children);
}
<!--tag: 标签的名字,如 div -->
<!--data: 数据 -->
<!--children: 这是一个数组,子节点数组。即VNode数组 -->
使用render渲染一个H标签
使用render实现 <H标签 :title="title" style="color: #00afff">{{title}}</H标签>
tag: h1
属性:render会自动处理
子元素:一个插槽 this.$slots.default

Vue.component('RH', {
  props: {
    level: {type:String, required: true}  <!--level必填-->
  }
  <!-- snabbdom, h就是createElement -->
  render(h) {
    return h(
      'h' + this.level,
      this.$slots.default  <!--返回的是VNode数组-->
    )
  }
})
<!--使用-->
<RH level="1" stype="{color: #00afff}"></RH>

<!--一般不会使用render, 除非用现有的标签不好渲染(了解)-->
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值