1. 父子组件传值
父组件通过prop向子组件传递数据,HTML attribute 名不区分大小写,因此浏览器将所有大写字符解释为小写,所以这里的prop使用kebab-case命名法。
传递到子组件,因为不是html attr,可以正常使用camelCased命名法,比如子组件的:props: ["childName", "fontSize"],?{{ childName }}
不过如果是单文件组件,是可以用camelCased命名法命名HTML attribute的
父组件监听子组件事件,@enlarge-size="enlargeSize(child, $event)"
同样是html attr的时候使用kebab-case命名
$event接受的是子组件传递过来的值(@click="$emit('enlargeSize', 16)")这里为16
如果只有子组件的参数,可以简写为@enlarge-size="enlargeSize",这样默认的一个参数就是子组件传递过来的值
<template>
<child
v-for="(child, index) of children"
:key="index"
:child-name="child.name"
:font-size="child.size"
@enlarge-size="enlargeSize(child, $event)"
></child>
</template>
components: {
child,
},
data() {
return {
children: [
{ name: "a", size: 16 },
{ name: "b", size: 16 },
{ name: "c", size: 16 },
],
};
},
methods: {
enlargeSize(child, size) {
child.size = size ? size : child.size + 1;
},
},
<template>
<div @click="$emit('enlargeSize')" :style="{ 'font-size': fontSize + 'px' }">
childName: {{ childName }}
<button @click="$emit('enlargeSize', 16)">重置</button>
</div>
</template>
props: ["childName", "fontSize"],
emits: ["enlargeSize"],
2.组件上使用v-model
<input v-model="searchText" /> 等价于 <input :value="searchText" @input="searchText = $event.target.value" />
<custom-input v-model="searchText"></custom-input>
v-model放组件中则是等价于
<custom-input ? :model-value="searchText" ? @update:model-value="searchText = $event" ></custom-input>
理解为父组件传递了个model-value的attr,接受一个update:model-value的事件
?所以为了让<custom-input v-model="searchText"></custom-input>生效,这个组件的input必须
- 将其 value attribute 绑定到一个名叫 modelValue 的 prop 上(:value="modelValue")
- 在其 input 事件被触发时,将新的值通过自定义的 update:modelValue 事件抛出(@input="$emit('update:modelValue', $event.target.value)")
app.component('custom-input', { ? props: ['modelValue'], ? emits: ['update:modelValue'], ? template: ` ? ? <input ? ? ? :value="modelValue" ? ? ? @input="$emit('update:modelValue', $event.target.value)" ? ? > ? ` })?
?
也可以通过get set实现
app.component('custom-input', { ? props: ['modelValue'], ? emits: ['update:modelValue'], ? template: ` ? ? <input v-model="value"> ? `, ? computed: { ? ? value: { ? ? ? get() { ? ? ? ? return this.modelValue ? ? ? }, ? ? ? set(value) {? ? ? ? ? this.$emit('update:modelValue', value) ? ? ? } ? ? } ? } })
3.通过插槽分发内容
父组件写在子组件标签中间的内容会被插入的子组件<slot></slot>的位置
<slot-child>
<h3>插入的内容</h3>
</slot-child>
<div>slot: <slot></slot></div>
4.动态组件
可以用is让组件改变。例如下面就是<h1>内容<h1>。也适用于自定义组件
<component :is="componentName">内容</component>
return {
componentName: "h1",
};
?
当它用于原生 HTML 元素时,is 的值必须以 vue: 开头,才可以被解释为 Vue 组件。这是避免和原生自定义元素混淆。
<table>
<tr is="vue:blog-post-row"></tr>
</table>
|