vue 组件通信
一、组件通信 父传子
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
<ul>
<li v-for="item in cmovies"> {{item}}</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 父传子 props
const cpn ={
template:'#cpn',
// props:['cmovies','cmessage']
props:{
//1.类型的限制
// cmovies:Array,
// cmessage:String,
// 2.提供一些默认值
cmessage:{
type:String,
default:'aaaaaaa',
required:true,// 用组件的时候必须传
},
//类型是数组时,默认值必须是一个函数
cmovies:{
type:Array,
// default:[],
default(){
return []
}
}
},
data(){
return{}
}
}
const app = new Vue({
el:"#app",
data:{
message:"你好了",
movies:['海王','海贼王','sss','ddd']
},
components:{
'cpn':cpn
}
})
</script>
1.父传子 props
2.在父组件中 :子组件接收数据的名称 =" 父组件传递数据的名称"
<cpn :cmovies="movies" :cmessage="message"></cpn>
3.在子组件 中通过 props来接收 父传递 过来的属性 类型要加上限制 以及默认值
props:{
//1.类型的限制
// cmovies:Array,
// cmessage:String,
// 2.提供一些默认值
cmessage:{
type:String,
default:'aaaaaaa',
required:true,// 用组件的时候必须传
},
//类型是数组时,默认值必须是一个函数
cmovies:{
type:Array,
// default:[],
default(){
return []
}
}
},
4.在子组件的 template中 用 v-for遍历 传递来的数据(前提是已经接收好了)
<template id="cpn">
<div>
<ul>
<li v-for="item in cmovies"> {{item}}</li>
</ul>
<h2>{{cmessage}}</h2>
</div>
</template>
5.注意:template 必须有一个 根
二、父传子的练习
<div id="app">
<cpn :c-info="info" :child-my-message="message"></cpn>
</div>
<template id="cpn">
<div>
<h2>{{cInfo}}</h2>
<h2>{{childMyMessage }}</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 父传子 props
const cpn = {
template: "#cpn",
props: {
cInfo: {
type: Object,
default() {
return {};
},
},
childMyMessage: {
type: String,
default: "",
},
},
};
const app = new Vue({
el: "#app",
data: {
message: 'aaa',
info: {
name: "fen",
age: 18,
height: 1.88,
},
},
components: {
cpn,
},
});
</script>
1.父传子
2.在父组件 中使用 props给子组件 传递
:子组件接收数据的名称 =" 父组件传递数据的名称"
<cpn :c-info="info" :child-my-message="message"></cpn>
3.子组件中用props接收 父传递过来的 加上 类型 默认值
props: {
cInfo: {
type: Object,
default() {
return {};
},
},
childMyMessage: {
type: String,
default: "",
},
},
4.在子组件的模板中 使用插值 展示
<template id="cpn">
<div>
<h2>{{cInfo}}</h2>
<h2>{{childMyMessage }}</h2>
</div>
</template>
三、子传父
<!-- 父组件 -->
<div id="app">
<!-- 2.监听发射的事件(@item-click) ="定义的父组件的方法" -->
<cpn @item-click="cpnClick"></cpn>
</div>
<!-- 子组件 -->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
// 子组件 props
const cpn = {
template: "#cpn",
data() {
return {
categories: [
{ id: "aaa", name: "热门推荐" },
{ id: "bbb", name: "手机数码" },
{ id: "ccc", name: "家用家电" },
{ id: "ddd", name: "电脑办公" },
],
};
},
methods: {
btnClick(item){
// console.log(item);
//子传父 :1.发射事件(('item-click'),参数(item))
this.$emit('item-click',item)
}
},
};
// 父组件
const app = new Vue({
el: "#app",
data: {
message: "aaa",
},
components: {
cpn,
},
methods:{
// 3.在父组件中使用这个方法
cpnClick(item){
console.log('cpnClick',item);
}
}
});
</script>
1.在子组件的data中定义数据
data() {
return {
categories: [
{ id: "aaa", name: "热门推荐" },
{ id: "bbb", name: "手机数码" },
{ id: "ccc", name: "家用家电" },
{ id: "ddd", name: "电脑办公" },
],
};
},
2.在子组件中绑定一个函数,把循环遍历的 item 传递过去
<button v-for="item in categories" @click="btnClick(item)">
{{item.name}}
</button>
3.在子组件的methods 中实现这个函数 用$emit 发射事件((‘item-click’),参数(item))
btnClick(item){
// console.log(item);
//子传父 :1.发射事件(('item-click'),参数(item))
this.$emit('item-click',item)
}
4.父组件监听 子组件发射的事件 定义一个函数
监听发射的事件(@item-click) =“定义的父组件的方法”
<cpn @item-click="cpnClick"></cpn>
5.在父组件中实现这个方法
// 3.在父组件中使用这个方法
cpnClick(item){
console.log('cpnClick',item);
}
四、父子组件通信的案例
<!-- 父 -->
<div id="app">
<!-- 父传子 -->
<!-- :子接收的数据="父传递的数据" -->
<!-- 子传父 -->
<!-- @子发射的事件 ="父实现接收的函数" -->
<cpn
:number1="num1"
:number2="num2"
@num1change="num1change"
@num2change="num2change"
></cpn>
</div>
<!-- 子 -->
<template id="cpn">
<div>
<h2>子组件:props:{{number1}}</h2>
<h2>子组件:初始化 data:{{dnumber1}}</h2>
<!-- <input type="text" v-model="dnumber1"> -->
<input type="text" :value="dnumber1" @input="num1Input" />
<hr />
<h2>子组件:props:{{number2}}</h2>
<h2>子组件:初始化 data:{{dnumber2}}</h2>
<!-- <input type="text" v-model="dnumber2"> -->
<input type="text" :value="dnumber2" @input="num2Input" />
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
num1: 1,
num2: 2,
},
//父的函数
methods: {
num1change(value) {
this.num1 = parseInt(value * 1);
},
num2change(value) {
this.num2 = parseInt(value * 2);
},
},
//局部注册子组件
components: {
cpn: {
template: "#cpn",
props: {
number1: Number,
number2: Number,
},
// 如果修改 父组件传递给子组件的值
// 需要在data中重新初始化一下
// 然后进行 绑定 修改data中的数据
data() {
return {
dnumber1: this.number1,
dnumber2: this.number2,
};
},
methods: {
num1Input(event) {
// 将input中的value 赋值到dnumber中
this.dnumber1 = event.target.value;
// 子传父:发射事件 num1change ,传递值 this.dnumber1 给父
this.$emit("num1change", this.dnumber1);
// 同时 修改 dnumber2的值 (修改后 props中没有改 )
this.dnumber2 = this.dnumber1 * 100;
// 子传父 修改 props中的值
this.$emit("num2change", this.dnumber2);
},
num2Input(event) {
this.dnumber2 = event.target.value;
this.$emit("num2change", this.dnumber2);
this.dnumber1 = this.dnumber2 * 1/100;
this.$emit("num1change", this.dnumber1);
},
},
},
},
});
</script>
要求:
1.通过父传子 子传父 实现 双向数据绑定
并且下面的数据是上面的 100倍 上面的是下面的1/100
步骤:
1.创建 子组件cpn 、父组件app
2.在父组件data中定义num1 、num2
3. 在app中使用子组件标签
4. 把父组件的num1、num2 传递给子组件(:子组件定义的数据=“父组件定义的数据”)
:number1="num1"
:number2="num2"
5.在子组件中 通过props接收父组件传递过来的值
props: {
//子组件定义数据变量:类型是Number
number1: Number,
number2: Number,
},
6.把props中的 值放在data中 初始化(需要改变的值得初始化)
(重新定义 dnumber1:this.【props的值】)
data() {
// 把props中的 值放在data中初始化
return {
dnumber1: this.number1,
dnumber2: this.number2,
};
},
7.把props 、data中的值在子组件的 template 中展示
<h2>props:{{number1}}</h2>
<h2>data:{{dnumber1}}</h2>
<h2>props:{{number2}}</h2>
<h2>data:{{dnumber2}}</h2>
8.把data中的数据 动态绑定在input中 并监听input的变化
<!-- 把data中的数值 动态绑定在input中 用函数num1Input监听input的变化 -->
<input type="text" v-bind:value="dnumber1" @input="num1Input" />
<input type="text" v-bind:value="dnumber2" @input="num2Input" />
9.在子组件中的 methods 中实现这2个监听的方法
num1Input(event) {
//1.将input 的value 赋值到 dnumber中
this.dnumber1 = event.target.value;
//2.为了让父组件修改值,发出一个事件
this.$emit("num1change",this.dnumber1);
//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 * 1/100
this.$emit('num1change',this.dnumber1)
},
10.父组件修改num1 使用 $emit(“发射的事件”,传世的参数)
//2.为了让父组件修改值,发出一个事件
this.$emit("num1change",this.dnumber1);
11.在的app的子组件中 监听 发射的事件赋值一个函数
@num1change="num1change"
@num2change="num2change"
12.在父组件中的methods实现这个函数(value 接收传递来的参数)
(把接收来的的参数 取整赋值给父组件的num1)
num1change(value) {
// this.num1 = value *1;
this.num1 = parseInt(value);
},
num2change(value) {
// this.num2 = value *1;
this.num2 = parseInt(value);
},
13.实现下面 dnumber2是 dnumber1的100倍
// 同时 修改 dnumber2的值 (修改后 props中没有改 )
this.dnumber2 = this.dnumber1 * 100
// 把修改后的值发射给num2change 方法
// 子传父 修改 app中num1的值(也就是props的值)
this.$emit('num2change',this.dnumber2)
14.实现上面 dnumber1是dnumber2的1/100
this.dnumber1= this.dnumber2 * 1/100
this.$emit('num1change',this.dnumber1)