下面是我目前的 struct (不起作用).

父组件:

<template>
<field-input ref="title" :field.sync="title" />
</template>

<script>
import Field from './input/Field'
export default {
  components: {
    'field-input': Field
  },
  data() {
    return {
      title: {
        value: '',
        warn: false
      }
    }
  }
}
</script>

子组件:

<template>
<div>
  <input type="text" v-model="field.value">
  <p v-bind:class="{ 'is-invisible' : !field.warn }">Some text</p>
</div>
</template>

<script>
export default {
  props: ['field']
}
</script>

这些要求是:

  • 如果父对象的数据title.warn值在父对象中发生更改,则应更新子对象的class绑定(field.warn).
  • 如果子元素的<input>被更新(field.value),那么父母的title.value应该被更新.

实现这一目标最干净的解决方案是什么?

推荐答案

不要将子组件的<input>绑定到父组件的title.value(比如<input type="text" v-model="field.value">).这是一个known bad practice,能够让你的应用程序的数据流更难理解.

这些要求是:

  • 如果父对象的数据title.warn值在父对象中发生更改,则应更新子对象的class绑定(field.warn).

这很简单,只需创建一个warnprops ,并将其从父对象传递给子对象.

家长(将props 传递给子元素):

<field-input ref="title" :warn="title.warn" />

子/模板(使用props ——仅限阅读):

<p v-bind:class="{ 'is-invisible' : !warn }">Some text</p>

Child/JavaScript(声明props 及其预期类型):

export default {
  props: {warn: Boolean}
}

请注意,在模板中,它是!warn,而不是!title.warn.此外,您应该将warn声明为Boolean属性,因为如果您不这样做,父级可能会使用一个字符串(例如<field-input warn="false" />),这将产生意外的结果(!"false"实际上是false,而不是true).

  • 如果子元素的<input>被更新(field.value),那么父母的title.value应该被更新.

这里有几个可能的选项(like using .sync in a prop),但我认为在这种情况下最干净的解决方案是在父 node 上创建value prop and use v-model.

父级(使用v-model绑定props ):

<field-input ref="title" v-model="title.value" />

子/模板(使用props 作为初始值,并在其更改时发出input个事件):

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

Child/JavaScript(声明props 及其预期类型):

export default {
  props: {value: String}
}

这两种解决方案中的Click here for a working DEMO种加在一起.

Vue.js相关问答推荐

VueJS使所有组件崩溃,而不是只有一个

如何在Vue 3中将动态特性从主零部件同步到子零部件

Vue 3 需要 main.js 中的文件

Vuejs 通过数据键迭代复杂对象

Vue Router中.getRoutes()获取的路由顺序优化建议

Nuxt3: 安装vue3-spinner (error: require is not defined in ES module scope)

在 Vue 中更改 json 数据后,如何在屏幕上重新呈现表格组件?

如何在 vuejs 中导入和使用本地 .csv 文件

我是否必须在 Vue 3 中使用 Composition API,还是仍然可以使用Vue 2的方式工作?

Vue watch 意外调用了两次

Vue:如何将 store 与组件一起使用?

apache上的Vue-router,子目录下的SPA,只能通过重定向访问页面

Vuetify - 如何在 v-data-table 中单击时突出显示行

vuetify:以编程方式显示对话框

我在 Nuxt 2.14.0 中运行的是什么版本的 Vue?

错误:Node Sass 尚不支持您当前的环境:Linux 64-bit with Unsupported runtime (88)

无法访问函数内的数据属性

如何使用 Vue Test utils 测试输入是否聚焦?

Vuetify v-data-table 固定标题不起作用

如何订阅store 模块