vue2中.sync的使用和在vue3中.sync的移除后的替代使用

修饰符 .sync 的作用:

  • .sync 修饰符的作用就是实现父子组件数据的双向绑定,简化功能逻辑代码 。当然,v-model 也是可以实现数据的双向绑定,但是,一个组件只有一个 v-model,所以 , v-model 只能针对一个变量进行数据绑定,而 .sync 修饰符可以实现多个参数的数据双向绑定。
  • 在对一个 prop 进行“双向绑定,单向修改”的场景下,因为子组件不能直接修改父组件,.sync 在2.3版本引入,作为一个事件绑定语法糖,利用EventBus,当子组件触发事件时,父组件会响应事件并实现数据更新,避免了子组件直接修改父组件传过来的内容。

vue2中使用.sync

父组件数据传入子组件中后更新

在父组件中传入数据到子组件中后,然后在子组件中处理了后,需要改变父组件数组的时候,我们一般会使用 $emit传递一个事件更新给父组件,父组件再对原来传入的数据进行更新修改。
比如,我们在父组件中使用一个模态框组件,如下:

// 父组件
<template>
  <div id="app">
    <button @click="openModal">打开模态框</button>
    <!-- 以下三种方法都可,我一般用的第一种 -->
    <!-- 使用方法事件处理器 -->
    <MyModal :isShow="isShow" @closeModal="closeModal" />
    <!-- 使用$event变量 -->
    <MyModal :isShow="isShow" @closeModal="isShow = $event" />
    <!-- 使用内联事件处理器 -->
    <MyModal :isShow="isShow" @closeModal="(val) => isShow = val" />
  </div>
</template>

<script>
import MyModal from './components/MyModal.vue'

export default {
  name: 'App',
  components: {
    MyModal
  },
  data() {
    return {
      isShow: false
    }
  },
  methods: {
    openModal() {
      this.isShow = true
    },
    closeModal(val) {
      this.isShow = val
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

// 模态框组件
<template>
  <div v-if="isShow">
    <h1>我是模态框</h1>
    <button @click="closeModal">关闭模态框</button>
  </div>
</template>

<script>

export default {
  props: ['isShow'],
  methods: {
    closeModal() {
      this.$emit('closeModal', false)
    }
  }
}
</script>

在这里插入图片描述

优化1

我们对上述代码进行一些优化,将父组件的 @closeModal 改为 @update:isShow 同时,将 $emit 方法更新为 update:isShow
代码如下:

// 父组件
<template>
  <div id="app">
    <button @click="openModal">打开模态框</button>
    <!-- 使用方法事件处理器 -->
    <!-- <MyModal :isShow="isShow" @closeModal="closeModal" /> -->
    <!-- 使用$event变量 -->
    <!-- <MyModal :isShow="isShow" @closeModal="isShow = $event" /> -->
    <!-- 使用内联事件处理器 -->
    <!-- <MyModal :isShow="isShow" @closeModal="(val) => isShow = val" /> -->
    <MyModal :isShow="isShow" @update:isShow="(val) => isShow = val" />
    <MyModal :isShow="isShow" @update:isShow="isShow = $event" />
    <MyModal :isShow="isShow" @update:isShow="closeModal" />
  </div>
</template>

<script>
import MyModal from './components/MyModal.vue'

export default {
  name: 'App',
  components: {
    MyModal
  },
  data() {
    return {
      isShow: false
    }
  },
  methods: {
    openModal() {
      this.isShow = true
    },
    closeModal(val) {
      this.isShow = val
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

// 模态框组件
<template>
  <div v-if="isShow">
    <h1>我是模态框</h1>
    <button @click="closeModal">关闭模态框</button>
  </div>
</template>

<script>

export default {
  props: ['isShow'],
  methods: {
    closeModal() {
      // this.$emit('closeModal', false)
      this.$emit('update:isShow', false)
    }
  }
}
</script>

优化2

将父组件 :isShow="isShow" 加上 .sync ,变成 :isShow.sync="isShow".sync 如果用一句话来说就是同步更新了子组件的数据变化,而从实现的角度来说就是 .sync 就是@update:isShow="closeModal" 的语法糖,是一种简写的形式。
代码如下:

// 父组件
<template>
  <div id="app">
    <button @click="openModal">打开模态框</button>
    <!-- 使用方法事件处理器 -->
    <!-- <MyModal :isShow="isShow" @closeModal="closeModal" /> -->
    <!-- 使用$event变量 -->
    <!-- <MyModal :isShow="isShow" @closeModal="isShow = $event" /> -->
    <!-- 使用内联事件处理器 -->
    <!-- <MyModal :isShow="isShow" @closeModal="(val) => isShow = val" /> -->
    
    <!-- <MyModal :isShow="isShow" @update:isShow="(val) => isShow = val" />
    <MyModal :isShow="isShow" @update:isShow="isShow = $event" />
    <MyModal :isShow="isShow" @update:isShow="closeModal" /> -->

	// 改的就这一句,其他都一样,模态框组件代码不用变
    <MyModal :isShow.sync="isShow" />
  </div>
</template>
...

总结,对比优化1和优化2,你只需掌握优化2即可。


vue3中移除了.sync使用 v-mode:xxx代替了

  • 注意不写v-model后的xx属性是不生效的,毕竟这并不是真正的v-model
    代码如下:
// 父组件
<template>
  <!-- .sync修饰符在vue3.0版本已弃用,应该使用v-model:xxx -->
  <MyDemo v-model:msg="msg" />
</template>

<script setup name="App">
import { ref } from 'vue'
import MyDemo from './components/MyDemo'

const msg = ref('hello')
</script>

<style>
</style>

// 子组件
<script setup>
defineProps(['msg'])
defineEmits(['update:msg'])
</script>

<template>
  <h1>{{ msg }}</h1>
  <button @click="emit('update:msg', '数据改变了')">changeMsg</button>
</template>

<style></style>

欢迎评论区一起讨论呀~

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

King_960725

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值