您好,我是沧沧凉凉,是一名前端开发者,目前在掘金、知乎以及个人博客上同步发表一些学习前端时遇到的趣事和知识,欢迎关注。
在面试中,Vue值传递问题一直是各大面试官最喜欢问到的问题之一,了解了各种值传递后,遇到一些比较复杂的界面,需要大量运用值传递时,你就可以从众多的值传递方式中找到一种最能简化代码逻辑的传值方式。
1. Prop/$emit
1.1 Prop
在Vue中最为常用的传值方式和变更值的方式,也是最重要的值传递方式,在Vue中起码有百分之80的值都是通过Prop进行传递。
对于Prop,官方文档的介绍也是相当的详细,所以这里就不过多去介绍细节,对Prop不了的朋友可以直接参考官方的Prop文档。
Prop的使用方式就是对子组件使用v-bind绑定一个属性,例如:
<template>
<div>
<!-- 给子组件绑定一个message -->
<Son :message="message" />
</div>
</template>
<script>
import Son from "@/views/Son";
export default {
name: "Parents",
components: { Son },
data() {
return {
message: "Hello World!",
};
},
};
</script>
<style scoped></style>
在子组件中就这样进行调用:
<template>
<div>
<label>
{{ message }}
</label>
</div>
</template>
<script>
export default {
name: "Son",
props: {
// 我通常习惯这样写,因为可以对Prop类型进行验证
// 甚至可以让父组件必传该值
message: {
type: String,
},
},
};
</script>
<style scoped></style>
注意:HTML中的attribute名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用DOM中的模板时,camelCase (驼峰命名法) 的Prop名需要使用其等价的kebab-case(短横线分隔命名) 命名。
**但是!如果你使用字符串模板,那么这个限制就不存在了。**现在Vue应用的HTML代码都使用了字符串模板。
1.2 $emit
通过v-on的方式向子组件中传递事件,然后通过this.$emit("事件名")的方式进行调用,其主要目的是修改Prop的值,因为Vue中推崇单向数据流,所谓的单向数据流就是通过Prop向子组件中传递的值,只有传递该值的组件才能对其修改,如果你对Prop的值进行修改,那么Vue会给你一个错误警告。
// 父组件
<Son :message="message" @set-message="setMessage" />
// 子组件
this.$emit("set-message", "改变");
注意:不同于组件和Prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。
并且v-on事件监听器在DOM模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent导致 myEvent 不可能被监听到。
所以推荐始终使用 kebab-case 的事件名。