什么是 非 Prop 的 Attribute 呢?就比如我们的 DOM 元素自带的属性 class
,style
,id
,href
等等。
当组件返回单个根节点时,非 prop attribute 将自动添加到根节点的 attribute 中。例如,在 <date-picker>
组件的实例中,就是用我们上节课 TestCom.vue
的代码
<template>
<div class="template-m-wrap">
<test-com
title="这个是组件"
></test-com>
</div>
</template>
<script>
import TestCom from "./TestCom";
export default {
name: "TemplateM",
components: {
TestCom,
},
data() {
return {
};
},
};
</script>
TemplateM.vue
如下:
<template>
<div class="template-m-wrap">
<test-com
title="这个是组件"
data-status="active"
></test-com>
</div>
</template>
<script>
import TestCom from "./TestCom";
export default {
name: "TemplateM",
components: {
TestCom,
},
data() {
return {
};
},
};
</script>
浏览效果如下:
同样的规则适用于事件监听器:
<template>
<div class="test-com-wrap">
{{ title }}
</div>
</template>
<script>
export default {
name: "TestCom",
props: {
title: {
type: String,
default: "",
},
},
created() {
console.log(this.$attrs)
}
};
</script>
在 test-com
组件添加事件监听器:
<template>
<div class="template-m-wrap">
<test-com
title="这个是组件"
data-status="active"
@change="change"
></test-com>
</div>
</template>
<script>
import TestCom from "./TestCom";
export default {
name: "TemplateM",
components: {
TestCom,
},
data() {
return {
};
},
methods: {
change() {}
}
};
</script>
我们来浏览下效果:
当有一个 HTML 元素将 change
事件作为 date-picker
的根元素时,这可能会有帮助。
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import App from './App.vue'
import router from './router'
import store from './store'
let app = createApp(App)
app.use(store).use(router).mount('#app')
app.component('date-picker', {
template: `
<select>
<option value="1">Yesterday</option>
<option value="2">Today</option>
<option value="3">Tomorrow</option>
</select>
`
})
在 TemplateM.vue
代码如下:
<template>
<div class="template-m-wrap">
<test-com
title="这个是组件"
data-status="active"
@change="change"
></test-com>
<date-picker @change="showChange"></date-picker>
</div>
</template>
<script>
import TestCom from "./TestCom";
export default {
name: "TemplateM",
components: {
TestCom,
},
data() {
return {
};
},
methods: {
showChange(event) {
console.log(event.target.value) // 将记录所选选项的值
}
}
};
</script>
效果如下:
如果你「不」希望组件的根元素继承 attribute,你可以在组件的选项中设置 inheritAttrs: false
。例如:
禁用 attribute 继承的常见情况是需要将 attribute 应用于根节点之外的其他元素。
通过将 inheritAttrs
选项设置为 false
,你可以访问组件的 $attrs
property,该 property 包括组件 props
和 emits
property 中未包含的所有属性 (例如,class
、style
、v-on
监听器等)。
使用 previous section 中的 date-picker 组件示例,如果需要将所有非 prop attribute 应用于 input
元素而不是根 div
元素,则可以使用 v-bind
缩写来完成。
import { createApp } from 'vue/dist/vue.esm-bundler.js'
import App from './App.vue'
import router from './router'
import store from './store'
let app = createApp(App)
app.use(store).use(router).mount('#app')
app.component('date-picker', {
inheritAttrs: false,
template: `
<select v-bind="$attrs">
<option value="1">Yesterday</option>
<option value="2">Today</option>
<option value="3">Tomorrow</option>
</select>
`
})
与单个根节点组件不同,具有多个根节点的组件不具有自动 attribute 回退行为。如果未显式绑定 $attrs
,将发出运行时警告。
app.component('custom-layout', {
template: `
<header>这是头部组件</header>
<main v-bind="$attrs">这是 main</main>
<footer>这是脚跟</footer>
`
})
在 TemplateM.vue
使用 custom-layout
组件如下:
<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
效果如下: