vue3组件数据实时联动,纯干货!

398 阅读2分钟

使用vue的小伙伴在项目开发中经常会遇到的一种场景,一个功能需要在项目的多处进行使用,这种我们基本的操作就是对这个功能进行组件的封装。

一些组件会接收父组件传递的数据进行展示和设置,当我们父组件中的响应式数据需要和子组件中的数据保持一致的时候我一般会采用以下几种方式:

1.emit自定义事件

这种方式是我们常用的方式,也是vue官网主推的方式。

比如实现一个自定义的输入框:

自定义组件.gif

流程:等待3s给父组件的text变量赋值,然后子组件数据会跟着进行变化,然后子组件的值变动父组件的值也会跟着变动。

CustomizeInput.vue

<template>
  <div class="custom_input">
    <h2>自定义组件</h2>
    <p>自定义功能</p>
    <a-input v-model:value="inputValue" placeholder="Basic usage" />
    <p>自定义功能</p>
  </div>
</template>

<script setup lang="ts">
import { ref, defineProps, watch, defineEmits } from 'vue'

const props = defineProps<{
  modelValue: string
}>()

const emits = defineEmits(['update:modelValue'])

const inputValue = ref(props.modelValue)

// 同步父组件数据
watch(
  () => props.modelValue,
  () => {
    inputValue.value = props.modelValue
  }
)

// 自定义事件向父组件同步数据
watch(
  () => inputValue.value,
  () => {
    emits('update:modelValue', inputValue.value)
  }
)
</script>
<style scoped lang="less">
.custom_input {
  border: 1px solid #ccc;
  padding: 20px;
  p{
    color: aqua;
  }
}
</style>


home.vue

<template>
  <div class="custom_input">
    <h2>父组件</h2>
    <div>当前组件数据:{{ text }}</div>
    <CustomizeInput v-model:modelValue="text" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import CustomizeInput from '@/components/CustomizeInput/CustomizeInput.vue'

const text = ref('')

setTimeout(() => {
  text.value = 'Hello World'
}, 3000)
</script>
<style scoped lang="less">
.custom_input {
  border: 1px solid #ccc;
  padding: 20px;
}
</style>

2.computed计算属性

这种方式很少见,但是真的很好用,推荐!

参考:vue官网

image.png

修改后的CustomizeInput.vue

<template>
  <div class="custom_input">
    <h2>自定义组件</h2>
    <p>自定义功能</p>
    <a-input v-model:value="inputValue" placeholder="Basic usage" />
    <p>自定义功能</p>
  </div>
</template>

<script setup lang="ts">
import { ref, defineProps, watch, defineEmits, computed } from 'vue'

const props = defineProps<{
  modelValue: string
}>()

const emits = defineEmits(['update:modelValue'])

// const inputValue = ref(props.modelValue)

// // 同步父组件数据
// watch(
//   () => props.modelValue,
//   () => {
//     inputValue.value = props.modelValue
//   }
// )

// // 自定义事件向父组件同步数据
// watch(
//   () => inputValue.value,
//   () => {
//     emits('update:modelValue', inputValue.value)
//   }
// )
// 上面注释代码修改为:
const inputValue = computed({
  // getter
  get: () => props.modelValue,
  // setter
  set: (newValue) => {
    emits('update:modelValue', newValue)
  },
})
</script>
<style scoped lang="less">
.custom_input {
  border: 1px solid #ccc;
  padding: 20px;
  p {
    color: aqua;
  }
}
</style>

上面两种实现的效果是一样的 还有其他的实现方式这里就不补充的了,感兴趣的话可以自己去试试!

019BFC14.jpg

在最后祝贺jym身体健康,工作顺利,恭喜发财!

019D7A67.jpg