自定义事件也可以用于创建支持 v-model 的自定义输入组件

<input v-model="searchText" />

等价于:

<input :value="searchText" @input="searchText = $event.target.value" />

当用在组件上时,v-model 则会这样:

<custom-input
  :model-value="searchText"
  @update:model-value="searchText = $event"
></custom-input>

为了让它正常工作,这个组件内的  必须:

  • 将其 value attribute 绑定到一个名叫 modelValue 的 prop 上
  • 在其 input 事件被触发时,将新的值通过自定义的 update:modelValue 事件抛出

写成代码之后是这样的:

app.component('custom-input', {
  props: ['modelValue'],
  emits: ['update:modelValue'],
  template: `
    <input
      :value="modelValue"
      @input="$emit('update:modelValue', $event.target.value)"
    >
  `
})

现在 v-model 就应该可以在这个组件上完美地工作起来了:

<custom-input v-model="searchText"></custom-input>

示例:

1、创建子组件InputModel.vue

正常使用v-model="inputVal" 需要 update:modelValue 事件抛出,如果使用自定义的名字就需要使用 v-model:inputVal="inputVal"  ,v-model:inputVal 将自定义名称声明到v-model上

<template>
  <div @click="$emit('update:inputVal',inputVal+1)" v-bind="$attrs">
      inputVal:{{inputVal}}--{{$attrs.num}}
  </div>
</template>

<script>
export default {
  props: {
     inputVal:{
         type:Number,
         default:0
     }
  },
  setup() {
    return {};
  },
};
</script>

2、在父组件引用

<template>
  <div class="home">

    <InputModel v-model:inputVal="inputVal" class="test-arrt" :style="'color:rgb(100,160,'+inputVal*2+')'" v-bind="{num:'kklll'}"></InputModel>

    <h1>{{inputVal}}</h1>
  </div>
</template>

<script>

import InputModel from "../components/test/inputCom.vue"

export default {
  name: "Home",
  components: {
    InputModel
  },
  data () {
    return {
      inputVal: 1
    }
  },

};
</script>

<style lang="scss" scoped>
.test-arrt{
  background: red;
}
</style>

效果:

点击改变值:

子组件使用input

<template>
  <!-- <div @click="$emit('update:inputVal',inputVal+1)" v-bind="$attrs">
      inputVal:{{inputVal}}--{{$attrs.num}}
  </div> -->

<input :value="inputVal" @input="$emit('update:inputVal',$event.target.value)" v-bind="$attrs">
</template>

<script>
export default {
  props: {
     inputVal:{
         type:Number,
         default:0
     }
  },
  setup() {
    return {};
  },
};
</script>

<style lang="scss" scoped>
.ddd{
    width: 50px;
    height: 50px;
    background: grey;
}
</style>

v-bind="$attrs"

非 Prop 的 Attribute

一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 props 或 emits 定义的 attribute。常见的示例包括 classstyle 和 id 属性。

$attrs 将父组件绑定的 class, style, id属性继承到子组件,将父组件绑定的prop但是没有在子组件props中定义的变量继承过来,类似于prop

可以继承 父组件的 :num="kkll"  v-bind="{num:'kkll'}"

v-model 自定义事件名

父组件使用:

<modelTem v-model:modeltemval="modeltemval" />

子组件:

<template>
  <div>
    <h2>{{ modeltemval }}</h2>
    <button @click="returnBk">back</button>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
    modeltemval: String,
  },
  emits: ["update:modeltemval"],
  methods: {
    returnBk() {
      this.$emit("update:modeltemval", "我是儿子传来的");
    },
  },
};
</script>

<style lang="scss" scoped>
</style>


vue2.x   自定义组件使用 v-model

父组件:

<template>
  <div>
      {{modelVal}}
      <vModel v-model="modelVal" />
  </div>
</template>

<script>
import vModel from "../components/vModel.vue"
export default {
  components: {
      vModel
  },
  props: {},
  data() {
    return {
        modelVal:'我是你爸爸传来的数据'
    };
  },
};
</script>

<style lang="scss" scoped>
</style>

子组件:

<template>
  <div>
      <h1>{{modelVal}}</h1>
      <button @click="backReturn">back</button>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
      modelVal:String
  },
  model:{
      prop:'modelVal',
      event:"backVal"
  },
  data() {
    return {};
  },
  computed: {},
  created() {},
  mounted() {},
  watch: {},
  methods: {
      backReturn(){
          this.$emit("backVal","我是儿子传过来的数据")
      }
  },
};
</script>

<style lang="scss" scoped>
</style>
  props: {
      modelVal:String
  },
  model:{
      prop:'modelVal', //props定义
      event:"backVal"//自定义event 
  },

this.$emit("backVal","我是儿子传过来的数据")

如果你比较懒 可以使用 value和input

<template>
  <div>
      <h1>{{value}}</h1>
      <button @click="backReturn">back</button>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
      value:String
  },
//   model:{
//       prop:'modelVal',
//       event:"backVal"
//   },
  data() {
    return {};
  },
  computed: {},
  created() {},
  mounted() {},
  watch: {},
  methods: {
      backReturn(){
          this.$emit("input","我是儿子传过来的数据")
      }
  },
};
</script>

<style lang="scss" scoped>
</style>

效果:

点击 back

 

 

 

 

Logo

前往低代码交流专区

更多推荐