Vue学习笔记之父子组件通信以及经典案例
父组件、子组件直接的访问方式:1、父组件访问子组件可以用$childern 或者$refs$childern 的用法:当父组件引用多个子组件的时候,就会生成多个对应的对象:$childern可以访问子组件中的方法、data等数据但$childern一般在开发中比较少用,用$refs比较常用,因为$refs是可以通过key来绝对定位到对应的子组件,这种方法在实际开发中比较常用。$refs是一个对象类
父组件、子组件直接的访问方式:
1、父组件访问子组件可以用$childern 或者$refs
$childern 的用法:
当父组件引用多个子组件的时候,就会生成多个对应的对象:
$childern可以访问子组件中的方法、data等数据
但$childern一般在开发中比较少用,用$refs比较常用,因为$refs是可以通过key来绝对定位到对应的子组件,这种方法在实际开发中比较常用。$refs是一个对象类型,默认是一个空对象,在引用的时候通过ref = key 值来生成一个实例对象:
2、子组件访问父组件用$parent
但是在实际开发是不会这样使用的,因为如果这样嵌套组件的话,里面的子组件就不够独立了,导致子组件的复用性不强,与父组件的耦合度高。
如果需要访问跟组件里面的方法或数据,则可以用$root进行访问:
经典小案例:
- 功能需求:通过组件,有两个数据输入,由子组件输入的数字,改变父组件的数字,反之亦然,并且两个数字成倍数相互影响。
1、在我们实现这个需求的时候,我们第一想到的就是通过v-model进行输入框与data数据的绑定,由于子组件只能访问自己的数据,所以我们一开始想到的最简单的办法是:
但是这样编译器会反馈一个错误信息给我们:
大概的意思是:避免直接修改prop里的值,应该要通过父组件进行值的修改。代替方案:通过修改子组件的Data函数进行值修改,或者通过计算的方法,替代方案如下:
此时不再报错,但是我们发现当改变输入框的值时,props里面的值时没有发生变化的。原因是Input输入框里面绑定的是data()函数中的字段。所以要改变子组件里面的数据,需要通过data函数或计算方法进行修改,不要直接绑定props里面的字段!但是展示是可以直接用props里面的字段。
2、为了实现修改props里面数据,我们将v-modle进行拆分:v-bind、v-on进行处理:
子组件:
父组件:
3、第一个数字是第二个数字的倍数关系,而且给变任何一个值,就会影响另外一个值
为了实现此功能,在num1Input(event)事件中进一步修改另外一个数字的值:
改变data1的值,相应的data2的值也跟着变化:
改变data2的值,相应的data1的值也跟着变化:
4、完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<cpn :number1="num1" :number2="num2"
@num1change="num1change"
@num2change="num2change"></cpn>
</div>
<template id="cpn">
<div>
<h2>props1: {{number1}}</h2>
<h2>data1: {{dnumber1}}</h2>
<!-- <input type="text" v-model="dnumber1">-->
<input type="text" v-bind:value="dnumber1" @input="num1Input">
<h2>props2: {{number2}}</h2>
<h2>data2: {{dnumber2}}</h2>
<input type="text" :value="dnumber2" @input="num2Input">
<!-- <input type="text" v-model="dnumber2">-->
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
num1: 1,
num2: 0
},
methods: {
num1change(value) {
this.num1 = parseFloat(value)
},
num2change(value) {
this.num2 = parseInt(value)
}
},
components: {
cpn: {
template: '#cpn',
props: {
number1: Number,
number2: Number
},
data() {
return {
dnumber1: this.number1,
dnumber2: this.number2
}
},
methods: {
num1Input(event) {
// 1、将Input输入框的值复制到dnumber1中
this.dnumber1 = event.target.value;
// 2、通过$emit发出事件改变父组件的值
this.$emit('num1change', this.dnumber1) // 通过$emit改变父组件的值
// 3、同时修改dnumber2的值
this.dnumber2 = this.dnumber1 * 100; // 改变值
this.$emit('num2change', this.dnumber2) // 再次传出去
},
num2Input(event) {
this.dnumber2 = event.target.value;
this.$emit('num2change', this.dnumber2)
this.dnumber1 = this.dnumber2 / 100; // 改变值
this.$emit('num1change', this.dnumber1) // 再次传出去
}
}
}
}
})
</script>
</body>
</html>
更多推荐
所有评论(0)