• 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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

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

    组件传值—子传父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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述
    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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

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

    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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    Box.vue

    <template>
    	<div class="box">
    	  <h2>box--{{value}}h2>
    	  <button @click="change1">chaneg1button>
    	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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    v-model 不仅可以input的双向传值绑定,也可以组件的双向传值绑定

    但是要注意这里要改为input,因为本质还是input和value
    this.$emit("input","12354")

  • 相关阅读:
    使用 Go 和 Wails 构建跨平台桌面应用程序
    [windows][操作系统]复制文件夹到桌面经常到跑左上角导致桌面图标位置错乱
    《Get your hands dirty on clean architecture》读书笔记
    ES-初识ES
    selenium--获取页面信息和截图
    20_ue4进阶末日生存游戏开发[AI基础框架搭建]
    人工智能导论笔记(持续更新)
    安卓讲课笔记1.4 安卓平台架构
    《网络安全笔记》第十五章:交换机的基本配置
    我把一个json格式的数据读到dataframe里面了 怎么解析出自己需要的字段呢?
  • 原文地址:https://blog.csdn.net/chuxialia/article/details/126755640