Vue-子组件向父组件传值

子组件

<template>
    <div>
		<h2>商品名称:{{title}},商品个数{{count}},	 操作:<button @click="countins" >+1</button></h2> 
    </div>
</template>

<script>
    export default {
        name:'Fruit',
        data() {
            return {
                count:0
            }
        },
        methods:{
            countins(){
			this.$emit('count-change')		
 			this.count++;
            }
        },
        // 简单声明接收
		 props:['title']

        // 接收的同时对数据进行类型限制
		/* props:{
			name:String,
			age:Number,
			sex:String
		} */

        // 接收的同时对数据进行类型限制 + 指定默认值 + 限制必要性
		// props:{
		// 	name:{
		// 		type:String,
		// 		required:true,
		// 	},
		// 	age:{
		// 		type:Number,
		// 		default:99
		// 	},
		// 	sex:{
		// 		type:String,
		// 		required:true
		// 	}
		// }
    }
</script>

父组件

<template>
    <div>
                <Fruit  
                v-for="product in products" :key="product.id"
                        :title="product.title"
                  @count-change="totalCount++"     
                ></Fruit>
                <h2>总数为:{{totalCount}}</h2>
    </div>
</template>

<script>
    import Fruit from './Fruit.vue'
    export default {
        name:'Shop',
        components: { Fruit },
        data(){
            return{
                products:[
                    {
                    id:"1",
                    title:"苹果一斤"
                    },
                   {
                    id:"2",
                    title:"橘子两斤"
                    },{
                    id:"3",
                    title:"香蕉三斤"
                    },
                ],
                totalCount:0
            }
        }
    }
</script>

     router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Shop from '@/components/Shop'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/Shop',
      name: 'Shop',
      component: Shop
    },
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    }
  ]
})

页面效果

 

当前问题:

1子组件只提供了+1操作,+10或者+5操作不支持即还未实现通过$emit()实现传递参数

2.父组件中监听函数写在了标签内,如果有逻辑操作那么不利于维护 

 优化后如下

子组件

<template>
    <div>
		<h2>商品名称:{{title}},商品个数{{count}},	
			操作:<button @click="countins1" >+1</button><button @click="countins5" >+5</button></h2> 
    </div>
</template>

<script>
    export default {
        name:'Fruit',
        data() {
            return {
                count:0
            }
        },
        methods:{
            countins1(){
			this.$emit('count-change',1)		
 			this.count++;
            },
			countins5(){
			this.$emit('count-change',5)		
 			this.count+=5;
            }
        },
        // 简单声明接收
		 props:['title']

        // 接收的同时对数据进行类型限制
		/* props:{
			name:String,
			age:Number,
			sex:String
		} */

        // 接收的同时对数据进行类型限制 + 指定默认值 + 限制必要性
		// props:{
		// 	name:{
		// 		type:String,
		// 		required:true,
		// 	},
		// 	age:{
		// 		type:Number,
		// 		default:99
		// 	},
		// 	sex:{
		// 		type:String,
		// 		required:true
		// 	}
		// }
    }
</script>

父组件

 

<template>
    <div>
                <!-- <Fruit  
                v-for="product in products" :key="product.id"
                        :title="product.title"
                  @count-change="totalCount+=$event"   在标签内部监听子组件中的自定义事件,可以通过$event获取子组件传递的数据  
                ></Fruit> -->
                 <Fruit  
                v-for="product in products" :key="product.id"
                        :title="product.title"
                  @count-change="onCountChange"     
                ></Fruit>
                <h2>总数为:{{totalCount}}</h2>
    </div>
</template>

<script>
    import Fruit from './Fruit.vue'
    export default {
        name:'Shop',
        components: { Fruit },
        data(){
            return{
                products:[
                    {
                    id:"1",
                    title:"苹果一斤"
                    },
                   {
                    id:"2",
                    title:"橘子两斤"
                    },{
                    id:"3",
                    title:"香蕉三斤"
                    },
                ],
                totalCount:0
            }
        },
        methods:{
            onCountChange(productCount){
                // 在方法内部执行就可以使用$event了,因为不在标签内部,页面不会为我们转化标签,
                //因此需要通过参数的方式接受event(子组件传递的参数)
                this.totalCount+=productCount
            }
        }
    }
</script>

通过v-model实现子组件向父组件传值

子组件

<template>
    <div>
        <!-- <input type="text" :value="value" @input="$emit('input',$event.target.value)"> 
        标签书写方式 其中@input是指的input输入框事件,'input'是事件名称,$event.target是指定获取当前事件元素即input标签 -->
        <input type="text" :value="value" @input="onInput">
    </div>
</template>

<script>
    export default {
        name:'IpvalueChild',
        // 简单声明接收
		 props:['value']
        ,methods:{
            onInput(event){//在代码中需要自己接受event事件
               this.$emit('input',event.target.value)     
            }
        }
        // 接收的同时对数据进行类型限制
		/* props:{
			name:String,
			age:Number,
			sex:String
		} */

        // 接收的同时对数据进行类型限制 + 指定默认值 + 限制必要性
		// props:{
		// 	name:{
		// 		type:String,
		// 		required:true,
		// 	},
		// 	age:{
		// 		type:Number,
		// 		default:99
		// 	},
		// 	sex:{
		// 		type:String,
		// 		required:true
		// 	}
		// }
    }
</script>

父组件 

<template>
    <div>
                <p>输入的内容是:{{ipvalue}}</p>
                <ipvalue-child v-model="ipvalue"></ipvalue-child>
    </div>
</template>

<script>
    import IpvalueChild from './IpvalueChild.vue'
    export default {
        name:'Ipvalue',
        components: { IpvalueChild },
        data(){
            return{
                ipvalue:''
            }
        }
    }
</script>

页面效果


知识补充:
1.当子组件数据变化时,通过$emit('事件名','传递的数据')触发自定义事件用于注册事件,
  父组件使用@自定义事件 获取子组件传递的数据
2.v-model用于组件时,仍然需要通过props与自定义事件实现,但是绑定参数v-model帮我们实现了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值