vue3 中v-model语法糖(2024-06-21)


一、 vue2 中 v-model 语法糖

实现父子组件双向数据绑定,一个输入框或者组件指定绑定一个 v-model

1. 父组件写法

javascript 复制代码
<template>
  <div>
    <h1>App</h1>
    <h2>{{ count }}</h2>
    <input type="text" v-model="count" />
    <!-- 展开写法,@input中的 count 的值来自当前输入框事件 -->
    <input type="text" :value="count" @input="count = $event.target.value" />
    <hr />

    <Children v-model="count"></Children>
    <!-- 展开写法,@input中的 count 的值来自子组件输入框中的值 $event.target.value -->
    <Children :value="count" @input="count = $event"></Children>
  </div>
</template>

<script>
import Children from "@/components/Children.vue";
export default {
  components: {
    Children,
  },
  data() {
    return {
      count: "1",
    };
  },
};
</script>

2. 子组件写法

javascript 复制代码
<template>
  <div>
    <h1>main</h1>
    <div>{{ value }}</div>
    <input
      type="text"
      :value="value"
      @input="$emit('input', $event.target.value)"
    />
  </div>
</template>

<script>
export default {
  props: {
    value: {
      type: String,
    },
  },
};
</script>

二、 vue2 的 v-bind.sync 修饰符语法糖,实现父子组件双向数据绑定

注意:子组件标签中可以同时使用多个 .sync 修饰符

1. 在父组件中

javascript 复制代码
<template>
  <div>
    <h1>App</h1>
    <input v-model="count" type="text" />
    <hr />
    <Children :count.sync="count"></Children>
    <!-- 展开写法,@update:value中的 count 的值来自子组件输入框中的值 $event.target.value -->
    <Children :count="count" @update:count="count = $event"></Children>
  </div>
</template>

<script>
import Children from "@/components/Children.vue";
export default {
  components: {
    Children,
  },
  data() {
    return {
      count: "1",
    };
  },
};
</script>

2. 在子组件中

javascript 复制代码
<template>
  <div>
    <h1>main</h1>
    <h2>{{ count }}</h2>
    <input
      type="text"
      :value="count"
      @input="$emit('update:count', $event.target.value)"
    />
  </div>
</template>

<script>
export default {
  props: {
    count: {
      type: String,
    },
  },
};
</script>

三、 vue3 的 v-model 语法糖

  1. vue3 中的 v-model 相当于 vue2 中的 v-model 和 v-bind.sync 修饰符组合在一起的产物(择优整合)
  2. v-bind.sync 在 vue3 中被移除了
  3. 可以在组件标签上使用多个 v-model 绑定属性,使用参数区分

1. 在父组件中

javascript 复制代码
<template>
  <div>
    <h1>App</h1>
    <h2>{{ count }}</h2>
    <input type="text" v-model="count" />
    <!-- 此展开写法,仅限于输入框 -->
    <input type="text" :value="count" @input="count = $event.target.value" />
    <hr />
    <Children v-model:count="count"></Children>
    <!-- 此展开写法,仅限于组件 -->
    <Children :count="count" @update:count="count = $event"></Children>
  </div>
</template>

<script>
import Children from "@/components/Children.vue";
import { ref } from "vue";

export default {
  components: {
    Children,
  },
  setup() {
    const count = ref("1");

    return { count };
  },
};
</script>
2. 在子组件中
javascript 复制代码
<template>
  <div>
    <h1>main</h1>
    <div>{{ count }}</div>
    <label>
      count:<input
        type="text"
        :value="count"
        @input="emit('update:count', $event.target.value)"
      />
    </label>
  </div>
</template>

<script>
export default {
  props: {
    count: {
      type: String,
    },
  },
  setup(props, { emit }) {
    console.log(props);
    return { emit };
  },
};
</script>
相关推荐
Mike_jia8 小时前
uuWAF:开源Web应用防火墙新标杆——从工业级防护到智能防御实战解析
前端
掘金安东尼9 小时前
Chrome 17 岁了——我们的浏览器简史
前端·javascript·github
袁煦丞9 小时前
群晖NAS FTP远程文件仓库全球访问:cpolar内网穿透实验室第524个成功挑战
前端·程序员·远程工作
前端小巷子9 小时前
JS 打造动态表格
前端·javascript·面试
excel9 小时前
从卷积到全连接:用示例理解 CNN 的分层
前端
UNbuff_09 小时前
HTML 各种事件的使用说明书
前端·html
Mr. Cao code9 小时前
探索OpenResty:高性能Web开发利器
linux·运维·服务器·前端·nginx·ubuntu·openresty
百思可瑞教育9 小时前
ActiveMQ、RocketMQ、RabbitMQ、Kafka 的全面对比分析
vue.js·分布式·rabbitmq·rocketmq·activemq·北京百思可瑞教育·百思可瑞教育
li357417 小时前
将已有 Vue 项目通过 Electron 打包为桌面客户端的完整步骤
前端·vue.js·electron
Icoolkj17 小时前
VuePress 与 VitePress 深度对比:特性、差异与选型指南
前端·javascript·vue.js