目录
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>
- 结果