vue之组件传值---父传子(属性)---子传父(emit,sync,v-model)

组件传值—父传子

父组件通过属性给子组件传值: 子组件的props接受数据

在页面模板中 使用变量名:属性 data 计算属性(重点)

注意:属性传值是单向的,只能父到子
App.vue

<template>
  <div>
    <Box
      v-for="(item, index) in arr"
      :title="item.title"
      :price="item.price"
      :count="item.count"
      :key="item.id"
    >
    </Box>
    <button>总价:{{ total }}</button>
  </div>
</template>

<script>
import Box from "./Box.vue";
export default {
  data() {
    return {
      arr: [
        {
          title: "肉丝1",
          price: 14,
          count: 5,
        },
        {
          title: "肉丝2",
          price: 15,
          count: 9,
        },
        {
          title: "肉丝3",
          price: 13,
          count: 1,
        },
        {
          title: "肉丝4",
          price: 19,
          count: 3,
        },
        {
          title: "肉丝5",
          price: 20,
          count: 2,
        },
      ],
    };
  },
  components: {
    Box,
  },
  computed: {
    total() {
      return this.arr.reduce((n1, n2) => {
        return n1 + n2.price * n2.count;
      }, 0);
    },
  },
};
</script>

<style scoped="scoped" lang="scss">
</style>

Box.vue

<template>
	<div>
		<div>{{title}}----{{price}}元
			数量:
			<button>-</button>
			<span>{{count}} </span>
			<button @click="add">+</button>
		</div>
	</div>
</template>

<script>
	export default {
		props: ["title", "price", "count"],
		methods:{
			add(){
				console.log(this.count)
				this.count++
			}
		}
	}
</script>

<style>
</style>

在这里插入图片描述
这就是单向传值

组件传值—子传父emit

组件通过调用父组件的方法给父组件传值:子组件的自定义事件中,用$emit触发事件调用父组件方法给父组件传值

因为通过属性传值是单向的,但有时候我们需要子组件的data 数据需要交给父组件使用通过在子组件上定义自定义事件,在子组件中通过$emit 来触发事件;子组件的事件被触并传参,事件处理函数可以接收到子组件的数据;事件绑定的事件处理函数在父节点上,故可在事件处理函数中用到子组件的数据值来修改父节点的数据

App.vue

<template>
	<div>
		<Box @mycountincrement="countin" v-for="(item,i) in arr" 
		:title="item.title" 
		:price="item.price" 
		:count="item.count" 
		:key="item.id"
		:index="i"
		>		
		</Box>
		<button>总价:{{total}}</button>
		<button @click="change1">父组件修改数据</button>
	</div>
</template>
<script>
	import Box from "./Box.vue"
	export default {
		data() {
			return {
				 arr: [
				       {
				          title: "肉丝1",
				          price: 14,
				          count: 5,
				        },
				        {
				          title: "肉丝2",
				          price: 15,
				          count: 9,
				        },
				        {
				          title: "肉丝3",
				          price: 13,
				          count: 1,
				        },
				        {
				          title: "肉丝4",
				          price: 19,
				          count: 3,
				        },
				        {
				          title: "肉丝5",
				          price: 20,
				          count: 2,
				        },
		    	 ],
			}
		},
		methods:{
			countin(arg,index){
				console.log(arg,1234,index)
				this.arr[index].count=arg
				this.$set(this.arr,index,this.arr[index])
			},
			change1(){
				this.arr[0].count=100
				this.$set(this.arr,0,this.arr[0])
			}
		},
		components:{
			Box
		},
		computed:{
			total(){
				return  this.arr.reduce((n1,n2)=>{
					return n1+n2.price*n2.count
				},0)
			}
		}
	}
</script>

<style scoped="scoped" lang="scss">

</style>

Box.vue

<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(){
				//触发事件 并传值
				let n=this.count+1
				this.$emit("mycountincrement",n,this.index)
			}
		}
	}
</script>

<style>
</style>

在这里插入图片描述
Box组件循环遍历,有多少个数据就循环多少次出来,给自定义事件mycountincrement变得一个方法countin,一旦触发方法就会通过点击的元素下标改变父元素里面的值
父元素通过属性将值传给了子元素,子元素通过button的点击事件触发来增加值并且触发mycountincrement事件,这个事件触发就会调用countin函数执行,就能够该值,实现双向传值了

组件传值—子传父sync

App.vue

<template>
	<div class="app">
		<h1>app组件--msg-{{msg}}--{{msg2}}</h1>
		<Box :a1.sync="msg"></Box>
		<Box :a1.sync="msg" :a2.sync="msg2"></Box>
		<Box :a1.sync="msg" :a2.sync="msg2"></Box>
	</div>
</template>
<script>
	import Box from "./Box.vue"
	export default {
		data() {
			return {
				msg: "app的数据",
				msg2:"app的数据2"
			}
		},
		components: {
			Box
		},
	}
</script>

<style scoped="scoped" lang="scss">
	.app {
		width: 600px;
		height: 400px;
		background-color: darkgray;
		margin: 20px;
	}
</style>

Box.vue

<template>
	<div class="box">
		<h2>box组件---a1-{{a1}}--{{a2}}</h2>
		<button @click="change1">修改a1中的数据</button>
		<button @click="change2">修改a2中的数据</button>
	</div>
</template>

<script>
	export default {
		props:["a1","a2"],
		methods:{
			change1(){
				this.$emit("update:a1","box修改了a1的值")
			},
			change2(){
				this.$emit("update:a2","66666")
			}
		}
		
	}
</script>

<style scoped="scoped" lang="scss">
	.box{
		width: 400px;
		height: 200px;
		background-color: cornflowerblue;
		margin: 20px;
	}
</style>

比上面简便的写法,就是改为下面这两行,分别是两个.vue文件的

<Box :a1.sync="msg" :a2.sync="msg2"></Box>

this.$emit("update:a2","66666")

本质都是一样的

组件传值—子传父v-model

App.vue

<template>
	<div class="app">
		<p>app--{{msg}}</p>
		<Box v-model="msg"></Box>
	</div>
</template>
<script>
	import Box from "./Box.vue"
	export default {
		data() {
			return {
				msg:"app666"
			}
		},
		components: {
			Box
		},
		methods:{
		}
	}
</script>

<style scoped="scoped" lang="scss">
	.app {
		width: 600px;
		height: 400px;
		background-color: darkgray;
		margin: 20px;
	}
</style>

Box.vue

<template>
	<div class="box">
	  <h2>box--{{value}}</h2>
	  <button @click="change1">chaneg1</button>
	</div>
</template>

<script>
	export default {
		props:["value"],
		methods:{
			change1(){
				this.$emit("input","1235454375687")
			}
		}
		
	}
</script>

<style scoped="scoped" lang="scss">
	.box{
		width: 400px;
		height: 200px;
		background-color: cornflowerblue;
		margin: 20px;
	}
</style>

v-model 不仅可以input的双向传值绑定,也可以组件的双向传值绑定
<Box v-model="msg"></Box>
但是要注意这里要改为input,因为本质还是input和value
this.$emit("input","12354")

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值