vue2 与 vue3 v-model 实现组件传值的写法

6,963 阅读1分钟

首先是我们的vue2中的两种写法

父子组件通信,都是单项的,很多时候需要双向通信。方法如下:

  1、父组件使用:msg.sync="aa"  子组件使用$emit('update:msg', 'msg改变后的值xxx') 

  2、父组件传值直接传对象,子组件收到对象后可随意改变对象的属性,但不能改变对象本身。

  3、父组件使用: v-model 

  第一种曾经被废除过,由于维护成本的原因被删掉,但经过证实,确实有存在的意义,又被加上。

v-model写法一:

父组件:
 <template>
  <div>
    <aa class="abc" v-model="test" ></aa>  // 组件中使用v-model
      {{'外面的值:' + test}} // 这儿试验test与内部msg值为双向绑定关系
    <button @click="fn">
      外面改变里面
    </button>
    
  </div>
</template>

<script>
import aa from './test.vue'
  export default {
    data () {
      return {
        test: ''
      }
    },
    methods: {
      fn () {
        this.test += 1 
      }
    },
    components:{
      aa
    }
  }
</script>
子组件
<template>
  <div>
    <ul>
      <li>{{'里面的值:'+ msg}}</li>
      <button @click="fn2">里面改变外面</button>
    </ul>
  </div>
</template>

<script>
  export default {
    model: {    // 使用model, 这儿2个属性,prop属性说,我要将msg作为该组件被使用时(此处为aa组件被父组件调用)v-model能取到的值,event说,我emit ‘cc’ 的时候,参数的值就是父组件v-model收到的值。
      prop: 'msg',
      event: 'cc'
    },
    props: {
      msg: ''
    },
    methods: {
      fn2 () {
        this.$emit('cc', this.msg+2)
      }
    }
  }
</script>

v-model写法二


  父组件 <aa class="abc" v-model='test' ></aa> 。
子组件
<template>
 <div>
    <ul>
      <li>{{'里面的值:'+ value}}</li> // 组件使用时有v-model属性,value初始传的‘what’ 不会被渲染,而是v-model绑定的test值被渲染,这儿value会被重新赋值为v-model绑定的test的值。
      <button @click="fn2">里面改变外面</button>
    </ul>
  </div>
</template>

<script>
  export default {
    props: {
      value: { // 必须要使用value
     default: '',
    },
    },

    methods: {
      fn2 () {
        this.$emit('input', this.value+2) // 这儿必须用input 发送数据,发送的数据会被父级v-model=“test”接受到,再被value=test传回来。
      }
    }
  }

下面来介绍vue3中的用法

一、v-model:双向绑定

Vue3:v-model规定:

  • 属性名任意(假设为xxx),事件名必须为update:xxx
  • 效果:未用v-model
<Switch :value="value" @update:value="value=$event"/>
  • 使用v-model
<Switch v-model:value="value"/>

详情可查看官网

二、emit

新增emit用法,与this.$emit作用相同
注意:新增emit没有 ''多乐'' 符

**

setup(props, context) {
      context.emit('update:value', newValue); //事件名 ,事件参数
    };
=======
method(){
    this.$emit('update:value', newValue)
}

$event的值是emit的第二个参数

知识点

  • props:由外部传值

  • emit:通过 $event接受由内部传出的值

  • 两者结合实现了子父组件之间通信,该方法较为常用,于是尤雨溪设计了v-model将两者结合

1、用于自定义组件时,v-model的prop和默认事件名更改了,并且移除了model选项

//父组件
<template>
  <div>
    <Child v-model="message" />
    <div>绑定的值:{{message}}</div>
  </div>
</template>

//子组件
<template>
  <div>
    <input 
      type="text" 
      :value="modelValue" 
      @input="$emit('update:modelValue', $event.target.value)"
    >
  </div>
</template>
<script>
export default {
  //2.x用法,可以修改prop和触发的事件名称,model以废弃
  // model: {
  //   prop: 'value', //3.x默认值改为了modelValue
  //   event: 'input' //3.x默认值改为了update:modelValue
  // },
  props:['modelValue']
}
</script>

2.x移除了model配置,3.x那又该怎么配置其他prop呢?

//父组件
<template>
  <div>
    <Child v-model:text="message" />
    <div>绑定的值:{{message}}</div>
  </div>
</template>

//子组件
<template>
  <div>
    <input 
      type="text" 
      :value="text" 
      @input="$emit('update:text', $event.target.value)"
    >
  </div>
</template>
<script>
export default {
  //3.x 接收v-model冒号后面的值,相应的触发的方法改为update:text
  props:['text']
}
</script>

2、3.x新增,可以定义多个v-model

//父组件
<template>
  <div>
    <Child 
      v-model="message1"
      v-model:text="message2" 
    />
    <div>绑定的值1:{{message1}}</div>
    <div>绑定的值2:{{message2}}</div>
  </div>
</template>

//子组件
<template>
  <div>
    <input 
      type="text" 
      :value="modelValue" 
      @input="$emit('update:modelValue', $event.target.value)"
    >
    <input 
      type="text" 
      :value="text" 
      @input="$emit('update:text', $event.target.value)"
    >
  </div>
</template>
<script>
export default {
  //v-model冒号后面不写值,默认就是modelValue
  props:['modelValue','text']
}
</script>

以上就是vue2、vue3v-model的基本用法。更多用法正在探索,祝大家码途一片光明。