定义父组件app,定义子组件product-com,当子组件需要使用父组件的值—子组件中使用props接收父组件传递的值
props:{
name:{
type:String, //类型
required:true, //必要性
default:'老王' //默认值
}
}
备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
<div id="app">
<ul>
<product-com v-for="(item,index) in protList" :product="item">product-com>
ul>
div>
<script>
// 定义子组件---产品组件
Vue.component('product-com',{
// 接收从父组件传递过来的变量
// product就相当于父元素中数据对象item,所以item.title对应product.title
props:['product'],
template:`
产品名称:{{product.title}}
产品描述:{{product.des}}
产品价格:{{product.price}}
`,
})
//定义父组件---拥有产品数据
let app=new Vue({
el:"#app",
data:{
// 假设有三个产品,将要显示在产品列表中
protList:[
{
title:"产品一",
price:"10",
des:"产品描述一"
},
{
title:"产品二",
price:"20",
des:"产品描述二"
},
{
title:"产品三",
price:"30",
des:"产品描述三"
}
]
}
})
script>
定义父组件app,定义子组件school-com,在子组件列表中选择一个学校,在父组件中显示选中的学校,将子元素的数据传递给父元素—需要自定义触发事件实现数据传递。案例中使用@chiden-parent=schoolChange,change-parent为自定义事件,在子组件中使用this.$emit(‘chiden-parent’,schoolName)触发。当chiden-parent被触发时,会调用定义在父组件中的schoolChange事件。
<div id="app">
<ul>
<school-com @chiden-parent="schoolChange" v-for="(item,index) in schoolList" :school-name="item" :index="index" :key="index">school-com>
ul>
<h2>选中的学校是{{school}}h2>
div>
<script>
//子组件
Vue.component('school-com',{
props:['index','schoolName'],
template:`
{{index+1}}---学校名称:{{schoolName}}
`,
methods:{
choose:function(schoolName){
// $emit传入事件名称,触发事件名称叫chiden-parent
this.$emit('chiden-parent',schoolName)
}
}
})
//父组件
let app=new Vue({
el:"#app",
data:{
schoolList:["北大","清华","浙大","川大"],
school:''
},
methods:{
// 触发父组件---school改变事件
schoolChange:function(data){
// 可以理解为因为$emit为自定义事件,第二个参数就会作为这个方法的第一个参数
this.school=data;
}
}
})
script>
在父组件中使用ref给子组件标识xxx
父组件中绑定自定义事件到子组件,使用 this.$refs.xxx.$on()
这样写起来更灵活,比如可以加定时器。和中自定义事件是一样的用法,只是定义自定义事件时,不是在组件上直接写。触发子组件中atguigu事件事件,就是触发父组件中getStudentName事件
Student子组件
<template>
<div class="student">
<button @click="sendStudentlName">把学生名给Appbutton>
div>
template>
<script>
export default {
name:'Student',
data() {
return {
name:'张三',
}
},
methods: {
sendStudentlName(){
//触发Student组件实例身上的atguigu事件
this.$emit('atguigu',this.name,666,888,900)
}
},
}
script>
App父组件
<template>
<div class="app">
<Student ref="student"/>
div>
template>
<script>
import Student from './components/Student'
export default {
name:'App',
components:{Student},
data() {
return {
studentName:''
}
},
methods: {
getStudentName(name,...params){
console.log('App收到了学生名:',name,params)
this.studentName = name
},
},
mounted() {
this.$refs.student.$on('atguigu',this.getStudentName) //绑定自定义事件
// this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
},
}
script>
若想让自定义事件只能触发一次,可以使用
once
修饰符,或$once
方法。
触发自定义事件:this.$emit('atguigu',数据)
绑定自定义事件使用this. r e f s . x x x . refs.xxx. refs.xxx.on()
解绑自定义事件使用this.$off
mounted() {
console.log(this.$refs.student.$on('atguigu',this.getStudentName));
},
beforeDestroy() {
this.$off("atguigu");
}
vue中有定义的$parent可以拿到子组件中的父组件,父组件要获取到子组件的数据,可以在子组件中获取到父组件,在调用父组件的函数,用函数传递参数
<div id="app">
<ul>
<school-com v-for="(item,index) in schoolList" :school-name="item" :index="index" :key="index">school-com>
ul>
<h2>选中的学校是{{school}}h2>
div>
<script>
// 子组件
Vue.component('school-com', {
props: ['index', 'schoolName', 'action'],
template: `
{{index+1}}--学校名称:{{schoolName}}
`,
// 这里可以看出是通过点击子组件来触发方法用来调用父组件的方法
methods: {
choose: function (schoolName) {
console.log(this.$parent)
this.$parent.schoolChange(schoolName);
}
}
})
//父组件
let app = new Vue({
el: "#app",
data: {
schoolList: ["北大", "清华", "浙大", "川大"],
school: ''
},
methods: {
schoolChange: function (data) {
this.school = data;
}
}
})
script>