$attrs的使用
当我们传递给一个组件某个属性,但是该属性并没有定义对应的props或者emits时,就称之为 非Prop的
Attribute。 例如class,style,id。
当组件有单个根节点时,非Prop的Attribute将自动添加到根节点的Attribute中。如果不希望组件的根元素继承attribute,可以在组件中设置 inheritAttrs: false。并且通过$attrs来访问非Props的Attribute属性。
定义一个子组件ShowMessage.vue。可见我们想要为h2提供非props的属性。
<template>
<div>
<!-- 将父组件传递的非props的attribute属性给h2 -->
<h2 v-bind="$attrs">{{ title }}</h2>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
// props: ['title', 'content']
// 不希望组件的根元素继承attribute,可以在组件中设置 inheritAttrs: false:
inheritAttrs: false,
props: {
title: String,
content: {
type: String,
required: true,
default: "123",
},
counter: {
type: Number,
},
info: {
// 对象类型的prop,默认值必须写成函数形式
type: Object,
default() {
return { name: "why" };
},
},
messageInfo: {
type: String,
},
},
};
</script>
<style scoped>
</style>
接着在App.vue中调用该子组件,并传入id,class等属性。其余注册过程略过。
<show-message
id="abc"
class="why"
title="哈哈哈"
content="我是哈哈哈哈"
message-info=""
></show-message>
可见,我们传递了id和class属性,并且在子组件中通过$attrs的方式进行了使用。
自定义组件使用v-model
v-model 可以在自定义组件上使用以实现双向绑定。例如对于在自定义的组件中,下面两种方式是等价的。
<hy-input v-model="message"></hy-input>
<hy-input :modelValue="message" @update:model-value="message = $event"></hy-input>
对于子组件HyInput.vue,可以通过多种方式实现双向绑定。但如果要在组件内也使用v-model的话,需要借助计算属性的get与set方法。get 方法需返回 modelValue prop,而 set 方法需触发相应的事件。
<template>
<div>
<!-- 1.默认绑定和事件处理 -->
<!-- <button @click="btnClick">hyinput按钮</button>
<h2>HyInput的message: {{modelValue}}</h2> -->
<!-- 2.通过input -->
<!-- <input :value="modelValue" @input="btnClick"> -->
<!-- 4. 利用计算属性来实现,-->
<input v-model="value">
</div>
</template>
<script>
export default {
props: {
modelValue: String
},
emits: ["update:modelValue"],
computed: {
value: {
set(value) {
this.$emit("update:modelValue", value);
},
get() {
return this.modelValue;
}
}
},
methods: {
btnClick(event) {
this.$emit("update:modelValue", event.target.value);
}
}
}
</script>
此外在组件上使用v-model时,v-model 在组件上都是默认使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。我们可以通过给 v-model 指定一个参数来更改这些名字。
<hy-input v-model="message" v-model:title="title"></hy-input>
可以看到为v-model指定名字后,prop默认名称不再是modelValue,而是指定的名字。
<template>
<div>
<!-- v-model里面的名称,是和计算属性里的属性名对应的 -->
<input v-model="value">
<input v-model="why">
</div>
</template>
<script>
export default {
props: {
modelValue: String,
title: String
},
emits: ["update:modelValue", "update:title"],
computed: {
value: {
set(value) {
this.$emit("update:modelValue", value);
},
get() {
return this.modelValue;
}
},
why: {
set(why) {
this.$emit("update:title", why);
},
get() {
return this.title;
}
}
}
}
</script>
<style scoped>
</style>