【问题标题】:Vue3 use v-model in Child ComponentsVue3 在子组件中使用 v-model
【发布时间】:2021-02-21 01:01:08
【问题描述】:

我刚刚发现在 Vue3 中,v-model 无法响应/响应子级 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>

如果我在input 中输入内容,username 的数据也会发生变化。

但是,当我像这个例子一样使用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>

然后我更新了我的代码以使用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>

当我输入内容时,username 数据没有更新,与之前的不同。

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

【问题讨论】:

    标签: javascript vue.js vue-component vuejs3


    【解决方案1】:

    您不能指望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>
    

    【讨论】:

    • 我遇到了这个确切的问题,但我使用的是一个计算属性(带有选项 api),它有一个 get() 和 set().. 感谢这个答案,我能够替换 :value="value" :value="modelValue"this.$emit("input", val)this.$emit("update:modelValue", val)
    【解决方案2】:

    使用 Vue3 script setup 语法

    <template>
        <input type="text" v-model="val" @input="handleInput">
    </template>
    
    <script setup>
        import {ref, defineProps, defineEmit} from 'vue'
    
        const props = defineProps({
            modelValue: {
                type: String,
                default: ''
            },
        })
        const emit = defineEmit(['update:modelValue'])
    
        const val = ref(props.modelValue)
    
        const handleInput = () => emit('update:modelValue', val.value)
    </script>
    

    【讨论】:

    • 帮了我很多谢谢!我发现您的代码中有错字,或者他们更改了命名。它应该被称为 defineEmits 并带有一个 's'。
    【解决方案3】:

    在 vue2 中,这件事起作用了:

    您的 InputText 组件

    <template>
        <input :value="value"
               @input="({target}) => $emit('input', target.value)"/>
    </template>
    
    <script>
        export default {
            props: {
                value: {}
            }
        }
    

    你的父组件

    <template>
        <inputText v-model="inputValue"/>
    </template>
    
    <script>
        export default {
            components: {inputText},
            data: () => ({
                inputValue: null
            })
        }
    </script>
    

    【讨论】:

      猜你喜欢
      • 2022-12-30
      • 2019-02-14
      • 2021-11-09
      • 2018-04-28
      • 2021-03-10
      • 2021-12-23
      • 2019-02-05
      • 1970-01-01
      • 2021-04-07
      相关资源
      最近更新 更多