面试题答案
一键面试Vue中.sync修饰符的工作原理
- 原理:
.sync
修饰符是一种语法糖。当在子组件的props上使用.sync
修饰符时,它会自动在子组件触发一个更新事件,事件名是update:propName
,其中propName
是props的名称。父组件监听这个事件,并在事件触发时更新props的值。例如:
// 父组件
<template>
<ChildComponent :title.sync="parentTitle"></ChildComponent>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
parentTitle: '初始标题'
};
}
};
</script>
// 子组件
<template>
<button @click="updateTitle">更新标题</button>
</template>
<script>
export default {
props: ['title'],
methods: {
updateTitle() {
this.$emit('update:title', '新标题');
}
}
};
</script>
在子组件中通过$emit('update:title', newTitleValue)
触发事件,父组件监听到该事件后会自动更新parentTitle
的值。
与v - model的异同点
- 相同点
- 两者都用于实现双向数据绑定,使得数据在父子组件之间能够相互影响。
- 不同点
- v - model:它是一个语法糖,默认情况下,
v - model
在组件上使用时,会自动在组件上创建一个名为value
的prop,并监听名为input
的事件。例如:
- v - model:它是一个语法糖,默认情况下,
// 父组件
<template>
<CustomInput v - model="parentValue"></CustomInput>
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: { CustomInput },
data() {
return {
parentValue: ''
};
}
};
</script>
// 子组件
<template>
<input :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: ['value']
};
</script>
- .sync:
.sync
修饰符可以作用于任何props,并且触发的事件名是update:propName
,更加灵活。可以有多个.sync
修饰的props在一个组件上,而v - model
在一个组件上通常只用于一个数据双向绑定。
在父子组件通信中灵活运用.sync和v - model实现双向数据绑定
- 使用v - model
- 适用于表单输入等场景,例如自定义的输入框组件。
// 父组件
<template>
<div>
<MyInput v - model="inputValue"></MyInput>
<p>父组件值: {{ inputValue }}</p>
</div>
</template>
<script>
import MyInput from './MyInput.vue';
export default {
components: { MyInput },
data() {
return {
inputValue: ''
};
}
};
</script>
// 子组件MyInput.vue
<template>
<input :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: ['value']
};
</script>
- 使用.sync
- 适用于需要对多个props进行双向数据绑定的场景。例如一个可配置的弹窗组件,弹窗的标题和是否显示都需要双向绑定。
// 父组件
<template>
<Popup :title.sync="popupTitle" :visible.sync="isPopupVisible"></Popup>
</template>
<script>
import Popup from './Popup.vue';
export default {
components: { Popup },
data() {
return {
popupTitle: '弹窗标题',
isPopupVisible: false
};
}
};
</script>
// 子组件Popup.vue
<template>
<div v - if="visible">
<h2>{{ title }}</h2>
<button @click="updateTitle">更新标题</button>
<button @click="closePopup">关闭弹窗</button>
</div>
</template>
<script>
export default {
props: ['title', 'visible'],
methods: {
updateTitle() {
this.$emit('update:title', '新弹窗标题');
},
closePopup() {
this.$emit('update:visible', false);
}
}
};
</script>
通过上述代码示例,可以清晰看到.sync
和v - model
在父子组件双向数据绑定中的使用方式和区别。