• VUE-父子组件通信 及 v-model实现通信


    一、父组件向子组件传值

    1、首先创建父组件(parent)和子组件(child),并在父组件中注册子组件

    2、在父组件调用子组件标签中添加一个自定义属性(msg)

    // 父组件
    	<template>
            <div class="parent">
                <Child :msg="parentMsg"></Child>
            </div>
        </template>
        <script>
            import Child from './child.vue';
            export default {
                data() {
                    return {
                        parentMsg: "我是传给子组件的值"
                    };
                },
                components: {
                    Child
                },
            }
    	</script>
    

    3、在子组件的props中将父组件中自定义属性(msg)添加进去,则该属性在子组件中可以像data中定义的属性一样使用

    // 子组件
     	<template>
            <div class="child">
                <p>{{ msg }}</p>
            </div>
        </template>
        <script>
            export default {
                props: {
                    msg:{
                        type:String,
                        default:""
                    }
                }
            }
        </script>
    

    二、子组件向父组件传值

    1、在子组件中创建一个按钮,给按钮绑定一个点击事件

    2、在响应 点击事件的函数中使用$emit来发送一个自定义事件(listenChildEvent)给父组件,并传递一个参数

    	<template>
            <div class="child">
                <p>{{ msg }}</p>
                <button @click="sendMsg">向父组件传值</button>
            </div>
        </template>
        <script>
            export default {
                props: {
                    msg:{
                        type:String,
                        default:""
                    }
                },
                methods:{
                    sendMsg(){
                        this.$emit("listenChildEvent","this message is from child");
                    }
                }
            }
        </script>
    

    3、在父组件调用子组件标签中,监听该自定义事件(listenChildEvent)并添加一个响应该事件的处理方法,并接收子组件传过来的数据

    <template>
            <div class="parent">
                <Child :msg="parentMsg" @listenChildEvent="acceptMsgFromChild"></Child>
            </div>
        </template>
        <script>
            import Child from './child.vue';
            export default {
                data() {
                    return {
                        parentMsg: "我是传给子组件的值"
                    };
                },
                components: {
                    Child
                },
                methods:{
                    acceptMsgFromChild(data){
                        console.log(data);//或者将接受值处理
                    }
                }
            }
        </script>
    

    三、使用v-model实现父子组件通信

    1、v-model一般用于表单的双向数据绑定

    <template>
      <div>
        <input type="text"
               v-model="msg">
        <p>{{msg}}</p>
      </div>
    </template>
    <script>
    export default {
      data () {
        return {
          msg: ''
        }
      }
    }
    </script>
    

    2、v-model原理

    由此看出,v-model是v-bindv-on:input的结合,即监听了表单的input事件,然后修改value属性对应的值

    <template>
      <div>
        <input type="text"
               :value="msg"
               @input="bind">
        <p>{{msg}}</p>
      </div>
    </template>
    <script>
    export default {
      data () {
        return {
          msg: ''
        }
      },
      methods: {
        bind () {
          this.msg = event.target.value
        }
      }
    }
    </script>
    

    3、v-model除了在输入表单上可以使用之外,在组件上也可以使用,以实现父子组件的双向数据绑定

    // -------------------------------父组件
    <template>
      <div>
        <!-- 在父组件中用v-model相当于,v-bind绑定了value,以及执行了v-on:input事件 -->
        <child v-model="flag"></child>
        <div>{{flag}}</div>
      </div>
    </template>
    <script>
    export default {
      data () {
        return {
          flag: ''
        }
      },
      components: {
        child
      }
    }
    </script>
    
    // -------------------------------子组件
    <template>
      <div>
          <div class="btn" @click="confirm">确定</div>
      </div>
    </template>
    <script>
    export default {
    // 用props接收父组件传递的value值,从而实现双向数据绑定
      props: {
        value: {
          type: Boolean,
          default: true
        }
      },
      methods: {
        // 通过$emit触发父组件的input事件,并将第二个参数作为值传递给父组件
        confirm () {
          this.$emit('input', false)
        }
      }
    }
    </script>
    
    最后,父组件中的flag默认为true,点击了子组件中的“确定”后,子组件将false传递给了父组件的flag
    

    4、v-model添加model选项

    以上这种方式实现的父子组件的v-model通信,限制了popos接收的属性名必须为value和emit触发的必须为input,这样容易有冲突,特别是在表单里面。所以,为了更优雅的使用v-model通信,可以在子组件中使用model选项

    // 子组件
    <template>
      <div>
          <div class="btn" @click="confirm">确定</div>
      </div>
    </template>
    <script>
    export default {
    // model选项用来避免冲突,prop属性用来指定props属性中的哪个值用来接收父组件v-model传递的值,例如:这里用props中的flag1来接收父组件传递的v-model值;event属性可以理解为父组件@input的别名,从而避免冲突,即emit时要提交的事件名。
      model: {
    	prop: 'flag1',
    	event: 'changed'
      }
    // 用props接收父组件传递的value值,从而实现双向数据绑定
      props: {
        value: {
          type: Boolean,
          default: true
        }
      },
      methods: {
        // 通过$emit触发父组件的input事件,并将第二个参数作为值传递给父组件
        confirm () {
          this.$emit('input', false)
        }
      }
    }
    </script>
    

    5、v-model实现动态传值

    <template>
      <div>
        <new-input v-model="name"></new-input>{{name}}
      </div>
    </template>
    <script>
    import Vue from 'vue'
    Vue.component('new-input', {
      props: {
        value: {
          type: String
        }
      },
      template: '<label><input type="text" v-model="newValue" /> 你的名字:</label>',
      computed: {
        newValue: {
          get: function () {
            return this.value
          },
          set: function (value) {
            this.$emit('input', value)
          }
        }
      }
    })
    
    export default {
      data () {
        return {
          name: 'nick'
        }
      }
    }
    </script>
    
  • 相关阅读:
    0714买卖股票的最佳时机含手续费 Marathon
    0070爬楼梯 Marathon
    0045跳跃游戏II Marathon
    0343整数拆分 Marathon
    0406根据身高重建队列 Marathon
    0096不同的二叉搜索树 Marathon
    0763划分子母区间 Marathon
    0435无重叠区间 Marathon
    0452用最少数量的箭引爆气球 Marathon
    0509斐波那契数 Marathon
  • 原文地址:https://www.cnblogs.com/sunidol/p/13502205.html
Copyright © 2020-2023  润新知