2.子向父传值使用“$emit”;
由于是子组件传值给父组件,我们可以回忆上一次的子组件==>父组件的通信方式就是组件的自定义事件。
事件的三要素:
事件源target、事件类型type、监听器hander
组件的自定义事件:
就是自己创建的事件,包含事件名,事件回调等,定义好之后去给组件使用。也是一种组件间的通信方式,适用于子组件==>父组件。这里我们通过传值去讲述自定义事件如何使用。
- 在根组件中给子组件标签绑定自定义事件(
<Box1 v-on:myevent="fn1"></Box1>),创建一个方法(监听器:fn1),在自定义事件触发后调用这个函数。 - 在子组件内部定义事件类型,当满足事件触发的条件(条件是自己定义的)后,就去触发组件内的事件(
this.$emit("自定义事件名",传值给根组件内定义的方法)),然后监听器就会去做处理。
使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:
- 使用
$on(eventName)监听事件 - 使用
$emit(eventName)触发事件
-
通过在子组件上定义自定义事件,在子组件中通过
$emit来触发事件; -
子组件的事件被触发并传参,事件处理函数可以接收到子组件的数据;
-
事件绑定的事件处理函数在父节点上,故可在事件处理函数中用到子组件的数据值来修改父节点的数据。
补充:
页面刷新:this.$set(修改的值,数据的下标,修改的值)
案例:算商品总价:
前端:
父组件:
<template>
<div>
<!-- 父向子传值 :使用props属性进行传值title,price,count,index-->
<!-- 子向父传值:使用组件的自定义事件传值给父组件 在子组件中this.$emit()触发父组件中的自定义事件,将子组件中值传给父组件 -->
<Box v-for="(el,i) in arr" :key="i"
:title="el.title"
:price="el.price"
:count="el.count"
@ment="change2"
:index="i"></Box>
<div>总价:{{total}}</div>
<button @click="change">修改父组件的值</button>
</div>
</template>
<script>
import Box from './components/Box.vue';
export default {
data(){
return {
msg:"hello",
arr:[]
}
},
async mounted() {
//做网络请求
let res=await this.$axios("/good")
console.log(res)
//将请求的数据赋值给数组arr
this.arr=res.data
},
methods:{
//方法
change(){
this.arr[0].count=100
// 更改数据后,刷新页面
this.$set(this.arr,0,this.arr[0])
},
change2(arg,arg2){
// 接收子组件传来的值
// 实参arg就是子组件传过来的值n
console.log(arg);
// 实参arg2就是子组件传来的每个组件相对应的下标
// 用于区分每个子组件
console.log(arg2)
this.arr[arg2].count=arg
// 刷新页面
this.$set(this.arr,arg2,this.arr[arg2])
}
},
components:{
//注册组件
Box
},
computed:{
//计算属性
total(){
return this.arr.reduce((n1,n2)=>{
return n1+n2.price*n2.count
},0)
}
}
}
</script>
子组件:
<template>
<div>
<div>{{title}}----{{price}}元
数量:
<button>-</button>
<span>{{count}}</span>
<button @click="add">+</button>
</div>
</div>
</template>
<script>
export default {
props:["title","price","count","index"],
methods:{
add(){
// console.log(this.count)
// this.count++
let n=this.count+1
// 为什么要传一个下标给父组件呢?
// 是因为子组件循环,不易区分每一个组件,不易明确改变哪个组件的count值,所以传一个下标,区分一下
// this.$emit()触发父组件中的事件
this.$emit("ment",n,this.index)
}
}
}
</script>