vue组件之间的传值

父组件向子组件传值

子组件接受父组件传递的值,需要使用 props 参数,也就是在子组件定义时,引入 props 数组。如下数组所示:

props: ['title', 'str'],

如果在一个子组件定义是添加了上面代码,意味着该组件可以接受两个参数:title 、str ,可以通过属性的形式将参数传递过来。在 template 中可以使用这两个参数。

如下组件中接受了一个父级组件传递来的 title 参数:

let div_inner = {
  data: function () {
    return {
      text: '子级组件自有内容'
    }
  },
  // 使用 props 数组接受父组件中传递的参数
  props: ['title'],
  template: `<div >{{ text + '===' + title }}</div>`,
}

HTML

<div class="container">
  <!-- 设置 title 属性,向组件传递内容 -->
  <div-inner title="父组件传递的内容"></div-inner>
</div>

Vue

let vm = new Vue({
  el: '.container',
  components: {
    // 将自定义标签名和组件对象注册
    'div-inner': div_inner,
  },
})

结果:

在这里插入图片描述

还可以使用 v-bind 指令来进行动态的传递参数,使用 v-bind 为组件绑定属性,属性值为 data 所设置,如下代码所示:

组件:

let div_inner = {
  data: function () {
    return {
      text: '子级组件自有内容'
    }
  },
  // 使用 props 数组接受父组件中传递的参数
  props: ['title', 'str'],
  template: `<div >{{ text + '===' + title + '********' + str}}</div>`,
}

HTML

<div class="container">
  <!-- 设置 title 属性,向组件传递内容 -->
  <div-inner title="父组件传递的内容"></div-inner>
  <!-- 使用 v-bind: 动态绑定数据,可以使用 vue 实例的 data 属性动态传递参数 -->
  <div-inner :str='str'></div-inner>
</div>

Vue

let vm = new Vue({
  el: '.container',
  components: {
    'div-inner': div_inner,
  },
  data: {
    str: '这是通过data参数动态设置的数据'
  }
})

结果:
在这里插入图片描述

props 参数注意事项

子组件使用属性接受父组件传来的参数时,由于 HTML 会将大写字母解析为小写字母,所以在 HTML 的写法中不允许使用大驼峰命名法,如下所示:

<inner-div TitleParam="这是传递的参数"></inner-div>

上面代码片段中使用了子组件 <inner-div> 但是传递参数时,属性名为大驼峰命名法,在浏览器中会发生警告,并且不会解析该参数:
在这里插入图片描述

完整代码:

<div class="container">
  <!-- 
    在 html 中书写时,如果属性名有大驼峰命名法,需要改为脊柱命名法
    如果不改为脊柱命名法,子组件中不会接受到内容,浏览器控制台中产生警告
  -->
  <inner-div title-param="这是传递的参数"></inner-div>
  <!-- <inner-div TitleParam="这是传递的参数"></inner-div> -->
</div>
let inner_div = {
  // 定义组件时使用 props 参数接受的数据,命名方式不限
  props: ['TitleParam'],
  data: function () {
    return {
      text: '子组件中自带内容'
    }
  },
  // template 参数渲染时命名方式不限
  template: "<div>{{ text + '---' + TitleParam }}</div>"
}
let vm = new Vue({
  el: '.container',
  components: {
    'inner-div': inner_div
  }
})

如上面注释所说:在定义组件时,使用 props 参数接受的数据,命名方式不受限制;在使用 template 定义组件显示内容是,命名方式同样不受限制。唯一需要注意的是,书写在 HTML 中时,不可使用大驼峰。

传递值的类型

当使用 v-bind 动态绑定属性时,原来的内容是什么就会显示响应的内容。如果将属性写死,那么为字符串形式。

<div class="container">
  <!-- 第一个参数通过 v-bind 绑定,第二个参数为普通的属性 -->
  <inner-div v-bind:param1="12" param2="12"></inner-div>
</div>
let inner_div = {
  props: ['param1', 'param2'],
  template: `<div>{{ typeof param1 + "***** " + typeof param2 }}</div>`
}
let vm = new Vue({
  el: '.container',
  components: {
    'inner-div': inner_div
  }
})

结果:
在这里插入图片描述

子组件向父组件传值

使用子组件向父组件中传值时,需要使用 $emit() 绑定自定义事件,在括号中写入要绑定的自定义事件。如下代码:

<button @click='$emit("change_big")'>点击放大</button>

然后使父组件监听子组件的事件:

<fun-div :style="{fontSize: size + 'px'}" @change_big="func"></fun-div>

上面代码使用监听了子组件的 change_big 事件,该事件调用了 func 函数,完整代码如下:

组件:

let fun_div = {
  // 在模板中定义了 click 事件,事件中使用 $emit() 进行绑定
  template: `
    <div>
      测试文本
      <button @click='$emit("change_big")'>点击放大</button>
    </div>
  `
}

JS

let vm = new Vue({
  el: '.container',
  data: {
    size: 10
  },
  components: {
    'fun-div': fun_div
  },
  methods: {
    func: function () {
      this.size++
    }
  },
})

HTML

<div class="container">
  <fun-div :style="{fontSize: size + 'px'}" @change_big="func"></fun-div>
</div>

上面代码实现了使用子组件操作父组件中的内容,如果想要将子组件中的值传递给父组件,需要在模板的事件函数中传递参数,在 HTML 标签中的事件函数中传递 $event 参数,就可以在事件处理函数中接收到。如下代码:

子组件:

let fun_div = {
  // 模板中 $emit("send", "hello world") 表示事件为 send ,传递的参数为 hello world
  template: `<button @click='$emit("send", "hello world")''> 这是子组件,点击传值 </button>`
}

如注释中所说,使用 $emit() 设置了 send 事件,传递的参数为 hello world

上面代码将触发单击事件的代码写到了一起,还可以写成下面这样

let fun_div = {
  template: `
    <button @click='send("hello world")'> 这是子组件,点击传值 </button>
  `,
  methods: {
    send: function (msg) {
      // 通过调用 this.$emit() 触发
      this.$emit("send", msg)
    }
  },
}

Vue 代码:

let vm = new Vue({
  el: '.container',
  data: {
    msg: ''
  },
  components: {
    'fun-div': fun_div
  },
  methods: {
    func: function (val) {
      console.log(val);
      this.msg = val
      console.log(event);
    }
  },
})

HTML:

<div class="container">
  <!-- 父组件监听 send 事件,事件函数中接受 $event 参数,该参数为子组件传递的参数 -->
  <div>
    {{msg}}
    <fun-div @send='func($event)'></fun-div>
  </div>
</div>

代码中的第 5 行极为关键,该自定义标签监听了 send 事件(上面子组件自定义的事件),在 func 事件处理函数中传递了 $event 参数,可以获取子组件中传递 hello world 参数。

兄弟组件之间的传值

兄弟组件之间的传值需要借助组件中心实现,所谓组件中心就是 new 一个 Vue 实例,Vue 实例中 $on 用来监听事件, $off 用来销毁事件,$emit() 用来触发事件。

详见 Vue 官方 $on

下面例子中完成了两个兄弟组件之间的通信过程:

tom 组件:

Vue.component('tom-div', {
  data: function () {
    return {
      text: '向jerry发送数据',
      msg: ''
    }
  },
  template: `
    <div>
      <div>tom收到:{{msg}}</div>
      <button @click="send">{{text}}</button>
    </div>
  `,
  methods: {
    // 按钮被点击时,由事件中心触发对方的事件,
    send: function () {
      // 通过 $emit 触发对方的事件
      eventHub.$emit('jerry-event', '你好 jerry')
    }
  },
  // 当模板加载完成时
  mounted() {
    // 通过事件中心监听一个自定义事件,当相应按钮触发时,通过事件中心触发事件
    // val 可以接受事件中传递的参数
    eventHub.$on('tom-event', (val) => {
      this.msg += val
    })
  },
})

jerry 组件:

Vue.component('jerry-div', {
  data: function () {
    return {
      text: '向tom发送数据',
      msg: ""
    }
  },
  template: `
    <div>
      <div>jerry收到:{{msg}}</div>
      <button @click="send">{{text}}</button>
    </div>
  `,
  methods: {
    send: function () {
      eventHub.$emit('tom-event', '你好 tom')
    }
  },
  // 当模板加载完成时
  mounted() {
    // 通过事件中心监听一个自定义事件,当相应按钮触发时,通过事件中心触发事件
    eventHub.$on('jerry-event', (val) => {
      this.msg += val
    })
  }
})

上述两个组件中,结构是相同的,这里拿 jerry 组件来说明。

首先看第 8 - 12 行,创建了 html 模板,模板中有一个按钮,当点击按钮时触发 send 事件函数。

再看 20 - 24 行,使用生命周期钩子(生命周期函数),mountend 当模板加载完毕时开始执行,也就是说当模板加载完成时监听 jerry-event 事件,该事件中接受一个参数。

再看 14 - 18 行,当 11 行的按钮被点击时,触发 send 事件函数,该函数中,使用 $emit() 触发了另一个兄弟中的 tom-jerry 事件。

HTML

<div class="container">
  <tom-div></tom-div>
  <br>
  <jerry-div></jerry-div>
</div>

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值