Skip to content
当前页大纲

前言

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

Vue2

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

父组件

html
<el-form-item label="主体 :" prop="unitId">
	<select-loadmore
          ref="partnerUnitNameSearchRef"
          placeholder="请输入要搜索的运营商主体"
          :search-model-val.sync="form.unitId"
          :format-select-list="{value: 'id', label: 'name'}"
          :select-get-api="socialCreditUnitApi.getSocialCreditUnitPage"
          search-key="p.unit_id"
          select-searchkey="name"
          @onSelectEnter="onSelectEnter"
	/>
</el-form-item>

子组件

vue
<template>
  <el-select
    v-model="searchModelVal"
    v-select-loadmore="loadmore"
    remote
    filterable
    :placeholder="placeholder"
    class="w100"
    clearable
    :remote-method="selectSearch"
    @visible-change="selectVisibleChange"
    @change="onSelectChange"
    @clear="onSelectClear"
    @keyup.native.enter="onSelectEnter"
  >
    <el-option
      v-for="(item,index) in selectList"
      :key="index"
      :label="item.label"
      :value="item.value"
    />
    <!-- 分页状态 -->
    <el-option disabled style="height: 25px;" class="flex flex-center">
      <div v-show="selectLoading">
        <i class="el-icon-loading mr10" />
        <span>正在加载更多...</span>
      </div>
      <div v-show="selectList.length <= 0 && !selectLoading">无匹配数据</div>
      <div v-if="selectList.length > 0 && selectLeave <= 0">没有更多了</div>
    </el-option>
  </el-select>
</template>

<script>
import selectLoadmoreMixins from '@/mixins/select-loadmore-mixins'
import props from './props'

export default {
  name: 'SelectLoadmore',
  mixins: [props, selectLoadmoreMixins],
  methods: {
    onSelectChange() {
      this.$emit('update:searchModelVal', this.searchModelVal)
      this.$emit('onSelectChange', this.searchKey, this.searchModelVal)
    },
    onSelectClear() {
      this.$emit('onSelectClear', this.searchKey)
      this.searchModelVal = ''
    },
    onSelectEnter() {
      this.$emit('onSelectEnter', this.searchModelVal)
    },
    resetState() {
      this.onSelectClear()
    },
  }
}
</script>
  • 使用props接收父组件传递过来的参数
  • $emit发送固定事件名update:props接收过来的参数

Vue3

1.简写

父组件使用v-model

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

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

vue
<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

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

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

vue
<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>

可以自定义参数

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

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

vue
<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>

MIT License.