Vue3手册译稿 - 深入组件 - 非prop属性

本章节需要要有组件基础

组件的非prop属性是一个属性或事件传递给组件,但不需要在propsemits中进行定义。通常使用的属性包括class,styleid属性。你可以通过$attrs来访问它们。

属性继承

如果组件只有一个根节点,非prop属性自动添加到根节点上。例如date-picker组件实例:

app.component('date-picker', {
  template: `
    <div class="date-picker">
      <input type="datetime-local" />
    </div>
  `
})

这个事件中我们通过data-status属性定义一个组件的状态,它会自动加到组件的根节点上(div.date-picker

<!-- Date-picker 组件含有非prop属性 -->
<date-picker data-status="activated"></date-picker>

<!-- date-picker组件渲染结果 -->
<div class="date-picker" data-status="activated">
  <input type="datetime-local" />
</div>

事件监听规则也是一样:

<date-picker @change="submitChange"></date-picker>
app.component('date-picker', {
  created() {
    console.log(this.$attrs) // { onChange: () => {}  }
  }
})

当有一个HTML标签含有change事件时当作date-picker组件根点的属性时,非常有用

app.component('date-picker', {
  template: `
    <select>
      <option value="1">Yesterday</option>
      <option value="2">Today</option>
      <option value="3">Tomorrow</option>
    </select>
  `
})

在这个例子中,change事件监听将会从父组件传递到子组件,而且会触发原生<select>change事件。我们不需要再从子件内部将事件监听发射(emit)出来了:

<div id="date-picker" class="demo">
  <date-picker @change="showChange"></date-picker>
</div>
const app = Vue.createApp({
  methods: {
    showChange(event) {
      console.log(event.target.value) // 会将选择的值打印到日志中
    }
  }
})

禁用属性继承

如果你不想让组件属性继承,你可以设置inheritAttrs:false选项来禁用它。通用禁用属性继承的场景是除根节点以外的其他元素需要使用该属性。
设置inheritAttrsfalse后,你可以使用组件的$attrs属性控制应用到别的元素,包括所有未包含在组件的props,emits属性中(如class,style,v-on监听等)。
还是使用前面章节提到的date-picker组件为例,在这个事件中,我们需要应用所有非prop属性到input标签,而不是根节点root,可以很熟练的使用v-on快捷方式:

app.component('date-picker', {
  inheritAttrs: false,
  template: `
    <div class="date-picker">
      <input type="datetime-local" v-bind="$attrs" />
    </div>
  `
})

通过这个配置项,data-status将会被应用到input标签:

<!-- Date-picker 组件含有非prop属性 -->
<date-picker data-status="activated"></date-picker>

<!-- 渲染 date-picker 组件 -->
<div class="date-picker">
  <input type="datetime-local" data-status="activated" />
</div>

多根节点属性继承

不像单根节点组件,多节点组件不能自动将属性挂载,如果$attrs 没有正确配置,运行时当成问题警告:

<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
// 收到告警
app.component('custom-layout', {
  template: `
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  `
})

// 不会告警, $attrs 应用到 <main> 标签
app.component('custom-layout', {
  template: `
    <header>...</header>
    <main v-bind="$attrs">...</main>
    <footer>...</footer>
  `
})

posted on 2021-03-13 21:35  zhouyu  阅读(134)  评论(3编辑  收藏  举报

导航