• vue3的双向绑定 v-model实现原理和案例


    parent.vue

    <template>
        <span>v-model 默认传值span>
        <childVue v-model="value">
            <template #prefix>
                <span>子组件值:span>
            template>
            <template #suffix>
                <span>结果值:{{value}}span>
            template>
        childVue>
    
        <br><br>
        <span>单个组件中,绑定多个输入值span>
        <a-input type="text" v-model:value="value2" />
        <a-input type="text" v-model:value="value3" />
        <childVue2 v-model:Arg1="value2" v-model:Arg2="value3" v-model:Result="value4" />
        <span>结果值:{{ value4 }}span>
    
        <br><br>
        <span>带修饰符的 v-modelspan>
        <child3Vue v-model:title="value5" />
        <span>不传修饰符: {{ value5 }}span>
        <br><br>
        <child3Vue v-model:title.smile="value6" />
        <span>传入修饰符 smile: {{ value6 }}span>
        <br><br>
        <child3Vue v-model:title.cry="value7" />
        <span>传入修饰符 cry: {{ value7 }}span>
        <br><br>
    template>
    <script setup>
    import { ref } from 'vue';
    import childVue from './child.vue';
    import childVue2 from './child2.vue';
    import child3Vue from './child3.vue';
    // 默认传值
    const value = ref();
    
    // 传多个参数进行绑定;
    const value2 = ref();
    const value3 = ref();
    const value4 = ref();
    
    // 带修饰符的参数绑定
    const value5 = ref();
    const value6 = ref();
    const value7 = ref();
    script>
    <style lang="less" scoped>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    child.vue

    <template>
        <a-input type="text" v-model:value="inputModelValue">
            <template #prefix>
                <slot name="prefix">slot>
            template>
            <template #suffix>
                <slot name="suffix">slot>
            template>
        a-input>
    template>
    <script setup>
    import { ref, watch } from 'vue';
    
    // 默认值显示用参数
    const inputModelValue = ref();
    
    const props = defineProps({
        // 默认参数值 注意传参的默认值为 modelValue
        modelValue: [Number, String],
    });
    
    const emit = defineEmits([
        // 为更新事件命名
        'update:modelValue'
    ]);
    
    // 父级改变时,修改本组件中变量的值
    watch(() => props.modelValue, val => {
        inputModelValue.value = val;
        // 加上这个参数,在初始化的时候进行一次传参相应
    }, { immediate: true });
    
    // 本组件中变量改变时,通知父级组件进行更新
    watch(inputModelValue, (val) => {
        emit('update:modelValue', val);
    })
    
    
    script>
    <style lang="less" scoped>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    child2.vue

    <template>template>
    
    <script setup>
    import { ref, watch } from 'vue';
    const props = defineProps({
        Arg1: [Number, String],
        Arg2: [Number, String],
        Result: [Number, String],
    });
    
    const emit = defineEmits(['update:Result'])
    
    watch(() => [props.Arg1, props.Arg2], (newValue, oldValue) => {
        // Wacth 监听多个数据的返回值时, 是按照数组下标进行传递的
        emit('update:Result', (newValue[0] || '') + ' ' + (newValue[1] || ''));
    })
    
    
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    child3.vue

    <template>
        <a-input v-model:value="value" />
    template>
    <script setup>
    import { ref, watch } from 'vue';
    const props = defineProps({
        'title': {
            default: ''
        },
        // 对于又有参数又有修饰符的 v-model 绑定,生成的 prop 名将是 arg + "Modifiers"
        'titleModifiers': {
            default: () => { return {} }
        }
    });
    
    const emit = defineEmits([
        // 为更新事件命名
        'update:title'
    ]);
    const value = ref('');
    
    value.value = props.title;
    watch(value, val => {
        if (props.titleModifiers.smile) {
            emit('update:title', val + '😀');
        } else if (props.titleModifiers.cry) {
            emit('update:title', val + '😂');
        } else {
            emit('update:title', val);
        };
    }, { immediate: true });
    
    
    script>
    <style lang="less" scoped>
    
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
  • 相关阅读:
    PIE-engine 教程 ——map()映射函数和for循环函数的综合应用NDVI和NDWI计算北京市各区面积
    【JUC】CompletableFuture
    第十章 结构体
    安全计算环境技术测评要求项
    Py之PyGTK:PyGTK的简介、安装、使用方法之详细攻略
    干货 | 查资料利器:线上图书馆
    存储过程与触发器的练习题
    MAC地址注册的网络安全影响和措施分析
    并发编程day01
    已经建好了项目,上传到gitee
  • 原文地址:https://blog.csdn.net/qq_38946996/article/details/128079649