Vue(七):组件的自定义事件和插槽

3、组件自定义事件

  1)、大小写的问题
  vue官网很是强调这个问题呀,基本能说一次的都要说一次。中心思想就是要你使用kebab-case的命名方式。当然,希望大家注意,指的是事件名,而不是方法名。举一个简单的栗子吧

<base-span @my-event="fun1"></base-span>  //父级调用代码,调用fun1方法,当然,也可以写一些简单的js表达式
fun1(){alert("help");}  //fun1方法

this.$emit('my-event');  //子级触发方式,如果父级调用的fun1有参数,可在事件名后面添加要传入的参数

  2)、v-model
  v-model主要利用的是组件中的value属性和input事件,但是有时候,value值和input事件有其他的作用,比如单选框和复选框,这个时候我们就需要自定义v-model。主要引用的就是model属性,设置默认绑定的值和事件。上个官网的栗子:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean  //这个是必须要声明的
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})  //v-model绑定的值就是bool值了

  3)、将原生事件绑定到组件
  当我们调用一个组件时,比如说我想监控它原生的事件怎么办呢?在原生的事件后面加上.native,比如@focus.native=""。但是如果该组件的根元素没有focus事件,但是其他元素里面有,我们想监听那个元素的focus事件怎么办呢?使用$listeners属性,它和我们上篇谈到的$attrs差不多,只不过$attrs是包含了父级的所有属性,而$listeners是包含了父级所有的事件。使用方法也一样,直接绑定到你想绑定的元素上面,就可以调用对应的事件了。

<div><input v-on="$listeners"></div>  //这是template中的代码,div代表根元素

 4、组件的插槽
  官网写了一大堆栗子,赶脚好重视的样子。但是我不重视,因为平常确实用的挺少。进入正题:
  1)、概念和作用
  官网说的额,有点笼统吧。顾名思义,插槽的作用就是在组件中插一个槽,也就是在组件中使用slot标签选择一个位置当作槽,在调用组件的时候,组件的开闭标签中间的位置就是槽口,在这个位置填上你想要写的代码,这段代码会出现slot标签标记的地方。插槽中间也能放组件啥的

<base-button>提交</base-button> //父级调用
<template><button><slot></slot></button></template>  //子级组件,‘提交’会代替slot标签出现在button中

  2)、后备内容和具名插槽
  后备内容就是给slot标签中设置一个默认值,如果插槽中没有数据,该默认值就会出现。具名插槽就是给slot设置一个name属性,这样就能调不同的插槽了。没有设置name属性的默认name值是dafault。看下代码,效果是出现红色的数字1、黄色的数字2和蓝色的文字“蓝”。

<my-component><one>1</one><two>2</two></my-component>  //父级调用
<template>
    <span style="color:red"><slot name="one">红</slot></span>
    <span style="color:yellow"><slot name="two">黄</slot></span>
    <span style="color:blue"><slot name="three">蓝</slot></span>
</template>

  3)、插槽的作用域
  默认插槽中的代码,只能访问父级的变量和属性,是无法访问组件中的变量和属性的。但是,通过一些骚操作,是可以让插槽中的代码访问组件中的变量和属性的,由于太骚了,我就不说了,兴趣不大。

  4)、动态插槽名,具名插槽缩写、插槽模板
  记住记住有这个东西就行了,用到的地方应该比较少。插槽的意义是非常大且有用的,但是用到最多的是1)和2),还是以实用为主吧,以后如果用到了,再回来更新吧。
  

原文地址:https://www.cnblogs.com/liangshibo/p/12966378.html