前言
之前自学vue的时候,真的是看到类似于$这种符号就头大,组件通信在面试的时候就是大概看了下并理解了,但是并没有深入的去了解它是如何传值,如何起作用的。现在决定认真的去研究一下,写在这里力求将自己所理解消化的想法用尽量最通俗易懂的语言写出来,希望能够帮助到有需要的人。
1.父组件向子组件进行传值
父组件APP.vue
父组件就直接使用APP.vue即可,接下来放上代码:
<template>
<div id="app">
<Users :users="user1"/>
</div>
</template>
<script>
import Users from "./components/Users.vue";
export default {
name: "App",
components: {
Users,
},
data() {
return {
user1: ["kobe", "Jordan", "Iverson"],
};
},
};
</script>
然后我来详细解释一下这段代码
代码很简单,首先看<template>里的内容,Users就是我们的子组件,子组件的代码我会在下方贴出,然后看到我用了v-bind(用了简写)绑定了users并将它的值赋为user1,其实我完全可以也将user1写成users,因为这样感觉会比较美观,但是为了区分,不让大家混淆我改成了user1。其中,users是我们自定义的名字,想叫什么都可以,而且这个自定义的名字会在子组件中使用到。
父组件会做的操作是,将data中的数组通过之前<template>中引用的<Users>子组件标签中绑定的users传递给子组件,并在子组件中通过props来接收。
子组件Users.vue
<template>
<div class="hello">
<ul>
<li v-for="user in users" :key="user">{
{ user }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props:{
users:{
type:String,
required:true
}
}
};
</script>
代码详解:
首先可以看到,我在<template>中,在li里遍历了一下users这个数组,那么这个users是哪里来的呢?就是从下方的props获得,而这里的props就是用于接受父组件传递过来的user1数组。props中的users和父组件中自定义的users还有子组件li中遍历的users都是一个东西,希望大家理解这一点,自己敲一下代码就清楚了,最忌讳只看不敲,这样我可以向大家保证,什么也记不住的。
值得注意的是,直接v-for有可能会报如下错误:
error Elements in iteration expect to have 'v-bind:key' directives vue/require-v-for-key
这是在提示你,你的v-for没有加上key,像上面的代码一样加上key即可。至于为什么是这样,大家自己去百度咯,我只知道每次写v-for的时候,都要带上key,我的理解是可以保证遍历出来的每个项目的唯一性,如果有理解的不对,希望大佬在评论区指正,非常感谢。
最终呈现在页面上的效果就是:
我再用一张图总结一下父组件传值给子组件的过程:
2.子组件向父组件进行传值
父组件APP.vue
<template>
<div id="app">
<Child @wordChanged="updateWord" />
<h2>{
{ parentWords }}</h2>
</div>
</template>
<script>
import Child from "./components/Child.vue";
export default {
name: "App",
components: {
Child,
},
data() {
return {
parentWords: "这个值是父组件中的值",
};
},
methods: {
updateWord(event) {
console.log(event)
this.parentWords = event;
},
},
};
</script>
<style>
</style>
代码详解:
首先,引入了子组件<Child>,为子组件绑定了一个wordChanged事件,它被赋值为下方声明的函数updateWord,h2用来先显示data中的parentWords。
值得注意的是,这里的wordChanged要与子组件中$emit方法中的第一个参数保持一致。
再来看一下updateWord函数,它有一个参数,这里的作用是用来接受子组件传过来的值,第一行就是将传入的值在控制台打出来(等一下看效果图),同时将data中的parentWords赋值为传进来的值event。
updataWord中的参数event是值得注意的,如果我像下方这样写的话,会发生什么呢:
<template>
<div id="app">
<button @click="updateWord($event)" value="this is a button">click me</button>
<h2>{
{ parentWords }}</h2>
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
parentWords: "这个值是父组件中的值",
};
},
methods: {
updateWord(event) {
console.log(event)
console.log(event.target)
console.log(event.target.value)
this.parentWords = event;
},
},
};
</script>
<style>
</style>
我们看一下页面的效果:
点击了右侧的按钮之后:
可以看到,我们依次得到了一个事件,然后是按钮的本体,最后是按钮的value值,大家可以对照着代码看一下。
于是我们了解到了$event的两种用法;
1.获得事件或者操作当前事件的对象(这里是按钮),同时可以获得这个对象的属性(比如value)
2.可以用来传值(比如文本)
好的,拓展到这里告一段落,我们继续来看子组件。
子组件Child.vue
<template>
<div>
<button @click="changeWords">click here</button>
</div>
</template>
<script>
export default {
methods: {
changeWords() {
this.$emit("wordChanged", "这个值是子组件向父组件传的值");
},
},
};
</script>
<style type="text/css" scoped>
button {
width: 80px;
height: 80px;
padding: 10px;
background-color: green;
color: aliceblue;
}
</style>
代码详解:
首先在<template>中,只有一个按钮,绑定了一个点击事件changeWords,这个点击事件里面是一个emit方法。emit v.发射,发出。这个方法的第一个参数就是父组件中自定义的名字wordChanged,然后将第二个参数的文本“发射”给父组件的wordChanged,被父组件中给wordChanged的updateWord接收,具体来说应该是被updateWord的参数event接收。
最后页面的效果:
点击按钮之前:
点击按钮之后:
我再用一张图总结一下父组件传值给子组件的过程:
更新中。。。。。。