当前位置:网站首页 > 后端开发 > 正文

封装组件系列-(二)-父子组件传值

一,单向数据流props传值

父组件:

<biu-button plain round type="primary">主要按钮</biu-button> 

子组件:

<template> <button class="biu-button" :class="[ `biu--button--${type}`, { 'is-plain': plain, 'is-disabled': disabled, 'is-round': round, 'is-circle': circle, }, ]" @click="handleClick" :disabled="disabled" > <i v-if="icon" :class="`biu-icon-${icon}`"></i> <!-- 如果没传入文本插槽,则不显示span内容 --> <span v-if="$slots.default"><slot></slot></span> </button> </template> <script> export default { 
      name: "BiuButton", props: { 
      type: { 
      type: String, default() { 
      return "default"; }, }, plain: { 
      type: Boolean, default: false, }, round: { 
      type: Boolean, default: false, }, circle: { 
      type: Boolean, default: false, }, disabled: { 
      type: Boolean, default: false, }, icon: { 
      type: String, default: "", }, }, }; </script> 

主要使用下面方式接收:

props: { 
    type: { 
    type: String, default() { 
    return "default"; }, }, } 

二,子组件事件绑定修改父组件的值

父组件:

<template> <div id="app"> <biu-dialog title="温馨提示" :visible="visible" v-on:handleClose="handleClose" > </biu-dialog> </div> </template> <script> export default { 
      name: "App", data() { 
      return { 
      visible: true, }; }, methods: { 
      handleClose() { 
      this.visible = false; }, }, }; </script> 

子组件:

<template> <div class="biu-dialog_wrapper" v-show="visible"> <div class="biu-dialog"> <div class="biu-dialog_header"> <button class="biu-dialog_headerbtn"> <i class="biu-icon-basic_refresh1" @click="handleClose"></i> </button> </div> </div> </div> </template> <script> export default { 
      name: "biu-dialog", props: { 
      visible: { 
      type: Boolean, default() { 
      return false; }, }, }, methods: { 
      handleClose() { 
      this.$emit("handleClose", false); }, }, }; </script> 

子组件通过@click="handleClose"调用子组件的

this.$emit(“handleClose”, false);从而调用 父组件的handleClose函数,修改父组件的visible值。然后visible单向传递给子组件。

三,子组件事件绑定修改父组件值简化.sync修饰符

vue提供了一个.sync 修饰符来简化第二节中的代码:

父组件:

<template> <div id="app"> <div> <biu-dialog title="温馨提示" :visible.sync="visible"> </biu-dialog> </div> </template> <script> export default { 
      name: "App", components: { 
     }, data() { 
      return { 
      visible: true, }; }, methods: { 
     }, }; </script> 

子组件:

<template> <div class="biu-dialog_wrapper" v-show="visible"> <div class="biu-dialog"> <div class="biu-dialog_header"> <button class="biu-dialog_headerbtn"> <i class="biu-icon-basic_refresh1" @click="handleClose"></i> </button> </div> </div> </div> </template> <script> export default { name: "biu-dialog", props: { visible: { type: Boolean, default() { return false; }, }, }, methods: { handleClose() { -- this.$emit("handleClose", false); ++ this.$emit("update:visible", false); }, }, }; </script> 

也就是父组件不需要再绑定子组件需要触发的事件了。

四,v-model配合事件绑定

在直接使用input的时候,可以直接使用v-mode进行数据的双向绑定,而当我们使用自定义组件的时候。也可以利用这一点。

一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,

这时候就可以在父组件中:

<template> <div id="app"> <!-- input组件 --> <biu-input v-model="username" ></biu-input> </div> </template> <script> export default { 
      name: "App", data() { 
      return { 
      username: "", }; } }; </script> 

也就是使用了v-model的组件biu-input,该子组件内部默认会生成名为value的prop,和绑定名为input的事件。(而该input事件,就是更新父组件的v-model绑定的属性)

于是可以在这个子组件中进行接收使用名为value的prop:

<template> <div class="biu-input"> <input + :value="value" + @input="handleInput" /> </div> </template> <script> export default { name: "biuInput", props: { + value: { + type: String, + default: "", + } } methods: { + handleInput(e) { + this.$emit("input", e.target.value); + }, }, }; </script> 

子组件先接收value,子组件触发input修改事件handleInput后触发父组件的input事件,从而修改了父组件的username值。

自定义组件的v-model 和 .sync修饰符其实本质上都是vue的语法糖,用于实现父子组件的“数据”双向绑定,vue3中已经不再有.sync修饰符了,新的v-model取代了vue2中的v-model和.sync修饰符。

相比较之下,.sync 更加灵活,它可以给多个 prop 使用,而 v-model 在一个组件中只能有一个。(Vue3中v-model已经可以给多个prop使用了)
从语义上来看,v-model 绑定的值是指这个组件的绑定值,比如 input 组件,select 组件,日期时间选择组件,颜色选择器组件,这些组件所绑定的值使用 v-model 比较合适。其他情况,没有这种语义,个人认为使用 .sync 更好。

五,v-model配合子组件computed

在第四节中,v-model是配合@input方法,让子组件调用父组件的input方法。

实际上,还可以在子组件使用compute的set和get方法实现这一功能。

父组件:

<biu-radio v-model="gender" label="0"></biu-radio> data() { 
    return { 
    gender: "", }; } 

子组件:

 <input type="radio" class="one-radio_original" :value="label" v-model="model" /> //计算属性 computed: { 
    model: { 
    get() { 
    return this.value; }, set(value) { 
    // 触发父组件的input事件 this.$emit("input", value); }, }, }, 

input的值是label定义的。当选中时,input的绑定值变成label,触发computed的set,就会调用父组件的input函数,从而修改父组件的gender值。

(上文说过,自定义组件的v-model会给子组件内部默认生成名为value的prop,和绑定名为input的事件)

六,provide配和inject

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

祖先组件:

<script> export default { name: "biuRadioGroup", provide() { return { RadioGroup: this, }; } }; </script> 

子孙组件:

export default { 
    inject: { 
    RadioGroup: { 
    default: "", }, }, } 

这样,RadioGroup默认是是空字符串,如果有传入,则是组件RadioGroup。子组件中就可以直接使用了。

到此这篇封装组件系列-(二)-父子组件传值的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 无法重新声明块范围变量“a”2024-12-03 14:00:06
  • 《第一行代码》 第五章:详解广播机制2024-12-03 14:00:06
  • nginx的下载和安装2024-12-03 14:00:06
  • 使用uni-app创建扫码连接wifi小程序2024-12-03 14:00:06
  • 解决谷歌浏览器打开后是毒霸浏览器的问题2024-12-03 14:00:06
  • 浏览器打印2024-12-03 14:00:06
  • 控制文本保留几行,末尾省略2024-12-03 14:00:06
  • base64和blob对图片的压缩2024-12-03 14:00:06
  • 封装组件系列-(一)-插槽及动态组件2024-12-03 14:00:06
  • flex:1不等分的问题2024-12-03 14:00:06
  • 全屏图片