利用v-model原理实现修改props

v-model的原理

<input v-model="searchText">

等价于:

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

在组件身上用v-bind绑定一个值,然后通过绑定的input事件,将 $event.target.value的值赋给v-bind绑定的值实现v-model数据的双向绑定。

同样自定义组件也是这个原理:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

官网是这样说的:

为了让它正常工作,这个组件内的 <input> 必须:将其 value attribute 绑定到一个名叫 value 的 prop 上

在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出,一般默认事件是input

使用场景

父传子我们一般使用props,在一些自己封装的组件当中,我们可能会需要修改props,这时就可以利用v-model的原理,通过在子组件触发自定义事件,在父组件内修改props的值。

vue2

在子组件身上写v-model(实际上是v-model:value),在子组件内部可以监测value值,监测值发生变化时,触发自定义emit事件,可以改掉父组件传递过来的props值而不引起警告。

model属性

在定义 vue 组件时,你可以提供一个 model 属性,用来定义该组件以何种方式支持 v-model

model 属性本身是有默认值的,如下:

// 默认的 model 属性
export default {
  model: {
    prop: 'value',
    event: 'input'
  }
}

      也就是说,如果你不定义 model 属性,或者你按照当面方法定义属性,当其他人使用你的自定义组件时,v-model="modelVersionListModalVisible" 就完全等价于 :modelVersionListModalVisible="foo" 加上 @input="foo = $event"

model属性写法
//父组件里面
 <ModelVersionListModal
      v-model="modelVersionListModalVisible"
      :modelId="currentDetail.id"
 />

//子组件
<template>
  <Modal
    v-model="visible"
    :title="$t('版本管理')"
    :width="800"
    footer-hide
  >
  </Modal>
</template>
<script>
export default {
  name: 'ModelVersionListModal',
  model: {//model属性
    prop: 'value',
    event: 'change'//默认是input,可以修改
  },
  props: {
    value: {
      type: Boolean,
      default: false
    },
  modelId: {
      type: [String, Number],
      required: true
    }
  },
  data () {
    return {
      visible: false
    }
  },
  watch: {
    value: {
      handler (val) {
        this.visible = val
      },
      immediate: true
    },
    visible (val) {
      this.$emit('change', val)
    }
  },
}
</script>
不用model的写法

当然这里也可以不配置model属性,使用this.$emit('input',val)

<script>
export default {
  name: 'ModelVersionListModal',
  props: {
    value: {
      type: Boolean,
      default: false
    },
  modelId: {
      type: [String, Number],
      required: true
    }
  },
  data () {
    return {
      visible: false
    }
  },
  watch: {
    value: {
      handler (val) {
        this.visible = val
      },
      immediate: true
    },
    visible (val) {
      this.$emit('input', val)
    }
  },
}
</script>

如果不用v-model,用的v-bind写法,则需要添加@自定义事件

vue3

父组件将props传递给子组件,子组件在对应的时机定义自定义事件,将数据传递给父组件,在父组件改props的值

//父组件
let visible = ref<boolean>(false)
  
<UpdateModal
    :visible="visible"
    @Cancel:visible="(val) => (visible = val)"
></UpdateModal>

//子组件定义自定义事件
emit('Cancel:visible', false)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值