• 子组件和父组件数据双向绑定



    前言

    • 在vue2中
      v-model实际上是表单的 :value属性 和@input事件的合写,是一个语法糖
    • 在vue3中
      v-model实际上是表单的 :modelValue属性 和@update:modelValue事件的合写,是一个语法糖

    Vue2

    一、表单类组件

    1.简写

    子组件身上使用v-model绑定数据

    <BaseSelect v-model="selectId">BaseSelect>
    <script>
    import BaseSelect from './components/BaseSelect.vue'
    export default {
      data() {
        return {
          selectId: '101',
        }
      },
      components: {
        BaseSelect,
      },
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    子组件

    使用props接收父组件传递过来的value参数
    并使用$emit发送input事件给父组件

    	<select :value="value" @change="changeCity">
          <option value="101">北京option>
          <option value="102">上海option>
          <option value="103">武汉option>
          <option value="104">广州option>
          <option value="105">深圳option>
        select>
        <script>
    export default {
      props: {
        value: {
          type: String
        }
      },
      methods: {
        changeCity(e) {
          this.$emit('input', e.target.value)
        },
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2.完整写法

    在子组件身上使用:value绑定数据,@自定义事件名处理参数

    <BaseSelect :value="selectId" @handleChange='selectId=$event'>BaseSelect>
    <script>
    import BaseSelect from './components/BaseSelect.vue'
    export default {
      data() {
        return {
          selectId: '101',
        }
      },
      components: {
        BaseSelect,
      },
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    子组件

    使用props接收父组件传递过来的value参数
    并使用$emit发送自定义事件给父组件

    	<select :value="value" @change="changeCity">
          <option value="101">北京option>
          <option value="102">上海option>
          <option value="103">武汉option>
          <option value="104">广州option>
          <option value="105">深圳option>
        select>
        <script>
    export default {
      props: {
        value: {
          type: String
        }
      },
      methods: {
    changeCity(e){
          this.$emit('handleChange',e.target.value)
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    二、非表单类组件

    绑定数据时使用.sync修饰符

    作用:可以实现 子组件 与 父组件数据 的 双向绑定,简化代码
    特点:props属性名,可以自定义,非固定为 value
    场景:封装弹框类的基础组件, visible属性 true显示 false隐藏
    本质:就是 :属性名 和 @update:属性名 合写

    1.简写

    <button @click='open'>退出按钮button>
        <BaseDialog :isShow.sync="isShow">BaseDialog>
    <script>
    import BaseDialog from "./components/BaseDialog.vue"
    export default {
      data() {
        return {
          isShow: false
        }
      },
      components: {
        BaseDialog,
      },
      methods: {
        open() {
          this.isShow = true
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    子组件

    使用props接收父组件传递过来的参数
    $emit发送固定事件名update:props接收过来的参数

    
        <div class="base-dialog"  v-show="isShow">
          <div class="title">
            <h3>温馨提示:h3>
            <button class="close" @click="closeDialog">xbutton>
          div>
        div>
    <script>
    export default {
      props: {
        isShow: Boolean,
      },
      methods: {
        closeDialog() {
          this.$emit('update:isShow', false)
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.完整写法

    <button @click='open'>退出按钮button>
        <BaseDialog :flag.sync="isShow"
        @update:flag='isShow=$event'>BaseDialog>
    <script>
    import BaseDialog from "./components/BaseDialog.vue"
    export default {
      data() {
        return {
          isShow: false
        }
      },
      components: {
        BaseDialog,
      },
        methods: {
        open() {
          this.isShow = true
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    子组件

    使用props接收父组件传递过来的参数
    $emit发送固定事件名update:props接收过来的参数

    
        <div class="base-dialog"  v-show="flag">
          <div class="title">
            <h3>温馨提示:h3>
            <button class="close" @click="closeDialog">xbutton>
          div>
        div>
    <script>
    export default {
      props: {
        flag: Boolean,
      },
      methods: {
        closeDialog() {
          this.$emit('update:flag', false)
        }
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Vue3

    1.简写

    父组件使用v-model

    <channel-select v-model="params.cate_id"></channel-select>
    
    • 1

    子组件使用defineProps接收数据和defineEmits发送数据

    <script setup>
    // 接收父组件传递过来的参数
    defineProps({
      modelValue: {
        type: [Number, String]
      }
    })
    // 子向父传递的参数
    const emit = defineEmits(['update:modelValue'])
    </script>
    <template>
      <el-select :modelValue="modelValue" @update:modelValue="emit('update:modelValue', $event)" >
        <el-option
          v-for="item in channelList"
          :label="item.cate_name"
          :value="item.id"
          :key="item.id"
        ></el-option>
      </el-select>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.完整写法

    父组件使用 :modelValue 和 @update:modelValue

    <channel-select
              :modelValue="params.cate_id"
              @update:modelValue="params.cate_id = $event"
            ></channel-select>
    
    • 1
    • 2
    • 3
    • 4

    子组件通过defineProps接收数据和defineEmits发送数据

    <script setup>
    // 接收父组件传递过来的参数
    defineProps({
      modelValue: {
        type: [Number, String]
      }
    })
    // 子向父传递的参数
    const emit = defineEmits(['update:modelValue'])
    const changeHandel = (e) => {
      console.log(e)
      emit('update:modelValue', e)
    }
    </script>
    <template>
      <el-select :modelValue="modelValue" @change="changeHandel">
        <el-option
          v-for="item in channelList"
          :label="item.cate_name"
          :value="item.id"
          :key="item.id"
        ></el-option>
      </el-select>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    可以自定义参数

    父组件使用v-model

    <channel-select v-model:cid="params.cate_id"></channel-select>
    
    • 1

    子组件使用defineProps接收数据和defineEmits发送数据

    <script setup>
    // 接收父组件传递过来的参数
    defineProps({
      cid: {
        type: [Number, String]
      }
    })
    // 子向父传递的参数
    const emit = defineEmits(['update:cid'])
    </script>
    <template>
      <el-select :modelValue="cid" @update:modelValue="emit('update:cid', $event)" >
        <el-option
          v-for="item in channelList"
          :label="item.cate_name"
          :value="item.id"
          :key="item.id"
        ></el-option>
      </el-select>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    vue165-main.js-vue中的小提示
    3.树莓派4b+ubuntu18.04(ros版本melodic)+arduino mega自制两轮差速小车,实现建图导航功能
    2716. 最小化字符串长度
    Android Studio Koala | 2024.1.1 发布,快来看看有什么更新吧
    【论文阅读】CTAB-GAN: Effective Table Data Synthesizing
    【Leetcode】134.加油站
    编译“零汇编(Zero-Assembler)“的OpenJDK11
    什么是线程?
    Kubernetes 部署发布镜像(cubefile:0.4.0)
    深入理解Netty以及为什么项目中要使用?(一) IO模型
  • 原文地址:https://blog.csdn.net/zyue_1217/article/details/132731367