vue-父子组件通信

父组件向子组件传值-props

定义父组件app,定义子组件product-com,当子组件需要使用父组件的值—子组件中使用props接收父组件传递的值

  • 只接收使用数组接收多个值 props:[‘name’]
  • 可以定义需要的格式props:{name:String}
  • 可以限制类型、限制必要性、指定默认值
props:{
	name:{
        type:String, //类型
        required:true, //必要性
        default:'老王' //默认值
	}
}

备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。

案例

 <div id="app">
        <ul>
            <!--item传值给子组件product属性传值  -->
            <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:`<li>
                <h3>产品名称:{{product.title}}</h3>
                <p>产品描述:{{product.des}}</p>
                <h2>产品价格:{{product.price}}</h2>
            </li>`,
    })
 
    //定义父组件---拥有产品数据
    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:`<li>
               <h3>{{index+1}}---学校名称:{{schoolName}}</h3>
               <button @click="choose(schoolName)">点击选择学校</button>
           </li>`,
        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

  • 被用来给元素或子组件注册引用信息(id的替代者)
  • 应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)

在父组件中使用ref给子组件标识xxx

<h1 ref="xxx">.....</h1><School ref="xxx"></School>

在父组件中使用this.$refs.xxx获取组件

父组件中绑定自定义事件到子组件,使用 this.$refs.xxx.$on() 这样写起来更灵活,比如可以加定时器。和中自定义事件是一样的用法,只是定义自定义事件时,不是在组件上直接写。触发子组件中atguigu事件事件,就是触发父组件中getStudentName事件

案例

Student子组件

<template>
	<div class="student">
		<button @click="sendStudentlName">把学生名给App</button>
	</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">
		<!-- 通过父组件给子组件绑定一个自定义事件实现(第二种写法,使用ref) -->
		<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

  • 解绑一个自定义事件 this.$off(‘事件名称’)//字符串形式
  • 解绑多个自定义事件 this .$off([ ’ 事件1’, ‘事件2’]) //数组形式
  • 解绑所有自定义事件 this.$off() //无参
mounted() {   
      console.log(this.$refs.student.$on('atguigu',this.getStudentName));  
  },
 
beforeDestroy() {     
     this.$off("atguigu"); 
}

子组件向父组件传值-$parent(不利于维护)

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: `<li>
               <h3>{{index+1}}--学校名称:{{schoolName}}</h3>
               <button @click="choose(schoolName)">点击选择学校</button>
           </li>`,

        // 这里可以看出是通过点击子组件来触发方法用来调用父组件的方法
        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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值