前言

  • 在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>

子组件

使用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>

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>

子组件

使用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>

二、非表单类组件

绑定数据时使用.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>

子组件

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


    <div class="base-dialog"  v-show="isShow">
      <div class="title">
        <h3>温馨提示:</h3>
        <button class="close" @click="closeDialog">x</button>
      </div>
    </div>
<script>
export default {
  props: {
    isShow: Boolean,
  },
  methods: {
    closeDialog() {
      this.$emit('update:isShow', false)
    }
  }
}
</script>

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>

子组件

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


    <div class="base-dialog"  v-show="flag">
      <div class="title">
        <h3>温馨提示:</h3>
        <button class="close" @click="closeDialog">x</button>
      </div>
    </div>
<script>
export default {
  props: {
    flag: Boolean,
  },
  methods: {
    closeDialog() {
      this.$emit('update:flag', false)
    }
  }
}
</script>

Vue3

1.简写

父组件使用v-model

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

子组件使用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>

2.完整写法

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

<channel-select
          :modelValue="params.cate_id"
          @update:modelValue="params.cate_id = $event"
        ></channel-select>

子组件通过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>

可以自定义参数

父组件使用v-model

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

子组件使用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>
Logo

欢迎加入我们的广州开发者社区,与优秀的开发者共同成长!

更多推荐