Vue3 在子组件中使用 v-model

Yov*_*tyo 2 javascript vue.js vue-component vuejs3

我刚刚发现在 Vue3 中,v-model没有响应式/响应式地与 child 一起工作Component

此代码将更新username数据

<template>
  <div>
    <input type="text" v-model="username" placeholder="Insert your username" />
    <p>{{ username }}</p>
  </div>
</template>

<script>
// Home.vue
export default {
  name: 'Home',
  data() {
    return {
      username: 'admin'
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

如果我在 中输入内容inputusername数据也会改变。

但是,当我Component像这个例子一样使用时:

<template>
    <input type="text" :class="'input-text ' + additionalClass" :placeholder="placeholder" />
</template>

<script>
// InputText.vue
import { defineComponent } from "vue"

export default defineComponent({
    name: 'InputText',
    props: {
        placeholder: {
            type: String,
            default: ''
        },
        additionalClass: {
            type: String,
            default: ''
        }
    }
})
</script>
Run Code Online (Sandbox Code Playgroud)

然后我更新了我的代码以使用Component.

注:Component注册成功。

<template>
  <div>
    <input-text v-model="username" :placeholder="`Insert your username`" />
    <p>{{ username }}</p>
  </div>
</template>

<script>
// Home.vue
export default {
  name: 'Home',
  data() {
    return {
      username: 'admin'
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

当我输入一些东西时,username数据没有更新,与上一个不同。

是否有任何解决方案或至少参考我想要实现的目标?

Moh*_*en_ 16

使用 Vue3script setup语法

<template>
  <input type="text" v-model="val" @input="handleInput">
</template>

<script setup>
import {ref, defineProps, defineEmits, watch} from 'vue'

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
})
const emit = defineEmits(['update:modelValue'])

const val = ref('')

watch(() => props.modelValue, nVal => val.value = nVal, {
  immediate: true
})

const handleInput = () => emit('update:modelValue', val.value)
</script>
Run Code Online (Sandbox Code Playgroud)

  • 对我帮助很大谢谢!我发现您的代码中有拼写错误或者他们更改了命名。它应该被称为defineEmits,并带有“s”。 (3认同)

Yom*_* S. 5

您不能期望v-model为您隐式更新底层元素。换句话说,您仍然需要在组件本身内处理它,并将其modelValue作为道具公开以使其真正起作用。类似的东西:

<template>
  <input
    type="text"
    @input="onChanged"
    :value="modelValue"
    :class="'input-text ' + additionalClass"
    :placeholder="placeholder" />
</template>

<script>
  // InputText.vue
  import { defineComponent } from "vue"

  export default defineComponent({
    name: 'InputText',

    emits: ['update:modelValue'],

    props: {
      modelValue: String,
      placeholder: {
        type: String,
        default: ''
      },
      additionalClass: {
        type: String,
        default: ''
      }
    },

    setup(props, { emit }) {
      function onChanged(e) {
        emit('update:modelValue', e.currentTarget.value);
      }

      return {
        onChanged
      }
    }
  })
</script>
Run Code Online (Sandbox Code Playgroud)


Hol*_*ick 5

VueUse 帮助器useVModel可以简化v-model子组件中的处理,请参阅https://vueuse.org/core/usevmodel/#usage

<script lang="ts" setup>
import { useVModel } from '@vueuse/core'

const props = defineProps<{
  modelValue: string
}>()
const emit = defineEmits(['update:modelValue'])

const model = useVModel(props, 'modelValue', emit)
</script>

<template>
    <input type="text" v-model="model" />
</template>
Run Code Online (Sandbox Code Playgroud)