跟着官网学 Vue - 组件 v-model

2023-12-14 14:03:05

1. v-model在组件上的用法

  • v-model 可以在组件上使用以实现双向绑定。
  • 在组件内部,v-model 会被展开为一个带有 model-value prop 和 update:model-value 事件的自定义组件。
  • 为了使其正常工作,组件内部需要将内部 <input> 元素的 value 属性绑定到 modelValue prop,并在原生的 input 事件触发时触发 update:modelValue 事件。
<template>
 <div id="app">
   <CustomInput v-model="inputValue" />
   <p>父组件的值:{{ inputValue }}</p>
 </div>
</template>

<script>
import CustomInput from "./CustomInput.vue";

export default {
 components: {
   CustomInput,
 },
 data() {
   return {
     inputValue: "", // 这个值将与 CustomInput 组件同步
   };
 },
};
</script>

<style>
#app {
 text-align: center;
 margin-top: 60px;
}

p {
 font-size: 18px;
 margin-top: 20px;
}
</style>
<!-- CustomInput.vue -->
<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue']
}
</script>

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

2. 使用computed属性实现v-model

  • 另一种在组件内实现 v-model 的方式是使用一个可写的、同时具有 getter 和 setter 的 computed 属性。
  • get 方法返回 modelValue prop 的值,而 set 方法触发相应的事件。
<template>
  <div id="app">
<!--    <CustomInput v-model="inputValue" />-->
    <ComputedMul v-model="inputValue" />
    <p>父组件的值:{{ inputValue }}</p>
  </div>
</template>

<script>
// import CustomInput from "./CustomInput.vue";
import ComputedMul from "@/components/vmodel/ComputedMul.vue";

export default {
  components: {
    ComputedMul,
    // CustomInput,
  },
  data() {
    return {
      inputValue: "", // 这个值将与 CustomInput 组件同步
    };
  },
};
</script>

<style>
#app {
  text-align: center;
  margin-top: 60px;
}

p {
  font-size: 18px;
  margin-top: 20px;
}
</style>
<!-- CustomInput.vue -->
<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue'],
  computed: {
    value: {
      get() {
        return this.modelValue
      },
      set(value) {
        this.$emit('update:modelValue', value)
      }
    }
  }
}
</script>

<template>
  <input v-model="value" />
</template>

3. v-model的参数

  • 默认情况下,v-model 在组件上使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。
  • 通过给 v-model 指定一个参数可以更改这些默认名字。
<template>
  <div id="app">
<!--    <CustomInput v-model="inputValue" />-->
<!--    <ComputedMul v-model="inputValue" />-->
<!--    <p>父组件的值:{{ inputValue }}</p>-->
    <MyComponent v-model:title="parentTitle" />
    <p>父组件的标题:{{ parentTitle }}</p>
  </div>
</template>

<script>
// import CustomInput from "./CustomInput.vue";
// import ComputedMul from "@/components/vmodel/ComputedMul.vue";
import MyComponent from "./MyComponent.vue";

export default {
  components: {
    MyComponent,
    // ComputedMul,
    // CustomInput,
  },
  data() {
    return {
      // inputValue: "", // 这个值将与 CustomInput 组件同步
      parentTitle: "", // 这个值将与 MyComponent 组件中的 title 同步
    };
  },
};
</script>

<style>
#app {
  text-align: center;
  margin-top: 60px;
}

p {
  font-size: 18px;
  margin-top: 20px;
}
</style>
<!-- MyComponent.vue -->
<script>
export default {
  props: ['title'],
  emits: ['update:title']
}
</script>

<template>
  <input
    type="text"
    :value="title"
    @input="$emit('update:title', $event.target.value)"
  />
</template>

4. 多个v-model绑定

  • 在单个组件实例上,可以创建多个 v-model 双向绑定,每个 v-model 会同步不同的 prop。
<template>
  <div id="app">
<!--    <CustomInput v-model="inputValue" />-->
<!--    <ComputedMul v-model="inputValue" />-->
<!--    <p>父组件的值:{{ inputValue }}</p>-->
<!--    <MyComponent v-model:title="parentTitle" />-->
<!--    <p>父组件的标题:{{ parentTitle }}</p>-->
    <UserName v-model:firstName="parentFirstName" v-model:lastName="parentLastName" />
    <p>父组件的姓氏:{{ parentFirstName }}</p>
    <p>父组件的名字:{{ parentLastName }}</p>
  </div>
</template>

<script>
// import CustomInput from "./CustomInput.vue";
// import ComputedMul from "@/components/vmodel/ComputedMul.vue";
// import MyComponent from "./MyComponent.vue";
import UserName from "@/components/vmodel/UserName.vue";

export default {
  components: {
    UserName,
    // MyComponent,
    // ComputedMul,
    // CustomInput,
  },
  data() {
    return {
      // inputValue: "", // 这个值将与 CustomInput 组件同步
      // parentTitle: "", // 这个值将与 MyComponent 组件中的 title 同步

      parentFirstName: "", // 这个值将与 UserName 组件中的 firstName 同步
      parentLastName: "", // 这个值将与 UserName 组件中的 lastName 同步
    };
  },
};
</script>

<style>
#app {
  text-align: center;
  margin-top: 60px;
}

p {
  font-size: 18px;
  margin-top: 20px;
}
</style>
<!-- UserName.vue -->
<script>
export default {
  props: {
    firstName: String,
    lastName: String
  },
  emits: ['update:firstName', 'update:lastName']
}
</script>

<template>
  <input
    type="text"
    :value="firstName"
    @input="$emit('update:firstName', $event.target.value)"
  />
  <input
    type="text"
    :value="lastName"
    @input="$emit('update:lastName', $event.target.value)"
  />
</template>

5. 处理v-model修饰符

  • 可以为组件的 v-model 添加修饰符,并通过 modelModifiers prop 在组件内访问这些修饰符。
  • 修饰符的使用可以在组件内部的方法中进行检查,从而改变抛出的值。
<template>
  <div id="app">
<!--    <CustomInput v-model="inputValue" />-->

<!--    <ComputedMul v-model="inputValue" />-->
<!--    <p>父组件的值:{{ inputValue }}</p>-->

<!--    <MyComponent v-model:title="parentTitle" />-->
<!--    <p>父组件的标题:{{ parentTitle }}</p>-->

<!--    <UserName v-model:firstName="parentFirstName" v-model:lastName="parentLastName" />-->
<!--    <p>父组件的姓氏:{{ parentFirstName }}</p>-->
<!--    <p>父组件的名字:{{ parentLastName }}</p>-->
    <MyComponentModifier v-model.capitalize="parentText" />
    <p>父组件的文本:{{ parentText }}</p>
  </div>
</template>

<script>
// import CustomInput from "./CustomInput.vue";
// import ComputedMul from "@/components/vmodel/ComputedMul.vue";
// import MyComponent from "./MyComponent.vue";
// import UserName from "@/components/vmodel/UserName.vue";
import MyComponentModifier from "@/components/vmodel/MyComponentModifier.vue";

export default {
  components: {
    MyComponentModifier,
    // UserName,
    // MyComponent,
    // ComputedMul,
    // CustomInput,
  },
  data() {
    return {
      // inputValue: "", // 这个值将与 CustomInput 组件同步
      // parentTitle: "", // 这个值将与 MyComponent 组件中的 title 同步

      // parentFirstName: "", // 这个值将与 UserName 组件中的 firstName 同步
      // parentLastName: "", // 这个值将与 UserName 组件中的 lastName 同步

      parentText: "", // 这个值将与 MyComponentModifier 组件中的 modelValue 同步

    };
  },
};
</script>

<style>
#app {
  text-align: center;
  margin-top: 60px;
}

p {
  font-size: 18px;
  margin-top: 20px;
}
</style>
<!-- MyComponentModifier.vue -->
<script>
export default {
  props: {
    modelValue: String,
    modelModifiers: {
      default: () => ({})
    }
  },
  emits: ['update:modelValue'],
  methods: {
    emitValue(e) {
      let value = e.target.value
      if (this.modelModifiers.capitalize) {
        value = value.charAt(0).toUpperCase() + value.slice(1)
      }
      this.$emit('update:modelValue', value)
    }
  }
}
</script>

<template>
  <input type="text" :value="modelValue" @input="emitValue" />
</template>

文章来源:https://blog.csdn.net/qq_43116031/article/details/134983821
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。