vue3+vite+ts--组件使用v-model实现双向绑定(vue2&vue3+ts的详细讲解)

目录

一、vue2中的sync修饰符在vue3+ts中如何呈现?

1.vue2中sync修饰符的用法

2.sync 的语法糖功能在vue3+ts中的使用

二、v-model实现父子组件的双向数据绑定

1.vue2通过实现父子组件v-model的双向数据绑定

 2.vue3+ts通过实现父子组件v-model的双向数据绑定


一、vue2中的sync修饰符在vue3+ts中如何呈现?

1.vue2中sync修饰符的用法

- vue 规则:props 是单向向下绑定的,子组件不能修改 props 接收过来的外部数据。

- 在子组件绑定属性的时候属性后面紧跟.sync

- 子组件使用props接收属性

- 子组件通过$emit(update:属性名,数据)

- 父组件:

<!--  -->
<template>
  <div class="father">
    <div class="context">
      <h1>这是父组件fatherNum:{{ fatherNum }}</h1>
      <son :sonNum.sync="fatherNum"></son>
    </div>
  </div>
</template>

<script>
import son from '../components/HelloWorld.vue';
export default {
  components: { son },
  data() {
    return {
      fatherNum: 0
    };
  }
};
</script>
<style lang="scss" scoped>
.father {
  width: 100vw;
  height: 100vh;
}
.context {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
</style>

- 子组件:

<template>
  <div class="">
    <h1>子组件:sonNum:{{ sonNum }}</h1>
    <button @click="add">sonNum++</button>
  </div>
</template>
<script>
export default {
  props: ['sonNum'],
  methods: {
    add() {
      //注意:xxx.sync所以update:xxx
      this.$emit('update:sonNum', this.sonNum + 1);
    }
  }
};
</script>
<style lang="scss" scoped></style>

- 结果:

2.sync 的语法糖功能在vue3+ts中的使用

- 在子组件上通过“v-model:绑定的属性名” 传递数据属性,支持绑定多个属性

- 子组件里面通过defineProps来接收属性

- 子组件里面defindEmits,通过 “update:属性名” 的格式定义更新事件

- 父组件:

<template>
  <h1>父组件fatherNum:{{ fatherNum }}</h1>
  <son v-model:sonNum="fatherNum"></son>
</template>
<script setup lang="ts">
import son from './components/son.vue';
import { ref } from 'vue';
let fatherNum = ref<number>(0);
</script>
<style scoped></style>

 - 子组件:

<template>
  <h1>子组件sonNum:{{ sonNumData }}</h1>
  <button @click="add">sonNum++</button>
</template>
<script lang="ts" setup>
import { withDefaults, defineProps, defineEmits, ref } from 'vue';
const props = withDefaults(
  defineProps<{
    sonNum: number;
  }>(),
  {}
);
//注意不可以直接修改props里面的值
const sonNumData = ref<number>(props.sonNum);
const emits = defineEmits<{
  (e: 'update:sonNum', val: number): void;
}>();
const add = () => {
  emits('update:sonNum', ++sonNumData.value);
};
</script>
<style lang="scss" scoped></style>

- 结果:

二、v-model实现父子组件的双向数据绑定

1.vue2通过实现父子组件v-model的双向数据绑定

- 父组件对子组件进行v-model的进行绑定

- 子组件通过model选项来修改event和prop

- 子组件通过 this.$emit(‘事件名’,=数据),将修改的事件emit出去

- 父组件:

<!--  -->
<template>
  <div class="father">
    <div class="context">
      <h1>这是父组件fatherNum:{{ fatherNum }}</h1>
      <son v-model="fatherNum"></son>
    </div>
  </div>
</template>
<script>
import son from '../components/HelloWorld.vue';
export default {
  components: { son },
  data() {
    return {
      fatherNum: 0
    };
  }
};
</script>
<style lang="scss" scoped>
.father {
  width: 100vw;
  height: 100vh;
}
.context {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
</style>

- 子组件:

<template>
  <div>
    子组件:<input type="text" v-model="sonNum" @input="sonNumChange" />
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  model: {
    // 定义model
    // 父组件v-model绑定的值传递给props中的fatherNum
    prop: 'fatherNum',
    // 通过emit触发sonNumChange将内部值传递给父组件v-model绑定的值
    event: 'sonNumChange'
  },
  props: {
    fatherNum: {
      // 接受父组件传递的值
      type: Number
    }
  },
  data() {
    return {
      sonNum: this.fatherNum // 关联值
    };
  },
  watch: {
    fatherNum(val) {
      //这一步重新赋值 是因为props里面的fatherNum改变了 但是data里面的sonNum不会改变 从而视图不会更新
      this.sonNum = val;
    }
  },
  methods: {
    sonNumChange() {
      // 通过$emit触发sonNumChange(model内定义)事件,将内部值传递给给父组件
      this.$emit('sonNumChange', Number(this.sonNum));
    }
  }
};
</script>

- 结果

 2.vue3+ts通过实现父子组件v-model的双向数据绑定

- 父组件通过v-model对子组件绑定

- 子组件defineProps内定义 modelValue

- 通过变量接收 modelValue

- 如果父组件传过来的数据是异步获取的,则需要watch来进行监听修改

- 最后通过defineEmits指定时间把数据发送出去

- 父组件

<template>
  <h1>父组件fatherNum:{{ fatherNum }}</h1>
  <son v-model="fatherNum"></son>
</template>
<script setup lang="ts">
import son from './components/HelloWorld.vue';
import { ref } from 'vue';
let fatherNum = ref<number>(0);
</script>
<style scoped></style>

- 子组件

<template>
  <h1>子组件sonNum:{{ sonNumData }}</h1>
  <button @click="add">sonNum++</button>
</template>
<script lang="ts" setup>
import { withDefaults, defineProps, defineEmits, ref, watch } from 'vue';
const props = withDefaults(
  defineProps<{
    //父组件 v-model 没有指定参数名,则默认是 modelValue
    modelValue: number;
  }>(),
  {}
);
watch(
  // 如果父组件传过来的数据是异步获取的,则需要进行监听
  () => props.modelValue,
  () => {
    sonNumData.value = props.modelValue;
  }
);
//注意不可以直接修改props里面的值
const sonNumData = ref<number>(props.modelValue);
//指定发送事件update:xxxx
const emits = defineEmits<{
  (e: 'update:modelValue', val: number): void;
}>();
//把事件发送出去
const add = () => {
  emits('update:modelValue', ++sonNumData.value);
};
</script>
<style lang="scss" scoped></style>

- 结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值