javascript - Vue.js 更新的属性不会在子组件上更改
问题描述
我有一个子组件,它是一个 HTML 输入元素。它看起来像这样:
<label-input inputId="formProductId"
inputType="number"
inputName="productId"
:inputEnabled="filters.productId.options"
:label="translations['product_id']"
:placeholder="translations['product_id']"
:data="filters.productId.value"
/>
标签输入.vue 文件:
<template>
<div class="form-element">
<label :for="inputId" :class="['form-element-title', { 'js-focused': focused }]">{{ label }}</label>
<input @input="updateValue($event.target.value)" :type="inputType" :id="inputId" :name="inputEnabled ? inputName : false" v-model="inputData" :placeholder="placeholder" @focus="focused = true" @blur="focused = false">
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class LabelInput extends Vue {
@Prop({ default: () => '' }) inputId!: string
@Prop({ default: () => '' }) inputType!: string
@Prop({ default: () => '' }) inputName!: string
@Prop({ default: () => '' }) label!: string
@Prop({ default: () => '' }) placeholder!: string
@Prop({ default: () => {} }) data!: []
@Prop({ default: () => true }) inputEnabled!: string
private inputData = this.data
private focused = false
updateValue (value: string) {
this.$root.$emit('input', {'inputName' : this.inputName, 'inputValue' : value});
}
}
所以模型通过filters.productId.value作为数据传递,然后变成局部变量inputData。
现在,如果我更改输入值,我将使用 updateValue 函数,该函数将输入名称及其值返回到父组件,从而更新原始 filters.productId.value 值。这工作正常。
现在的问题是我的父组件上有一个函数,它将filters.productId.value 值重置回null。它看起来像这样:
clearFilters() {
for (const [key, value] of Object.entries(this.filters)) {
this.filters[key].value = null;
}
}
现在我的子组件 LabelInput 中的数据没有改变,即使 filters.productId.value 现在为空。如何刷新子组件?
解决方案
我还没有将 Vue 用作类组件,但似乎问题在于将 prop 设置为类中的属性。
private inputData = this.data
Vue 监听 prop 的变化,但是 data 不监听引用的变化,所以 prop 发生了变化,但不是inputData
因为 Vue 没有为它设置监听器。
当我想做与您类似的事情时,我会使用computed
属性而不使用类。检查文档以了解它是如何实现的。
使用计算属性。
get inputData() {
return this.data;
}
我相信这会如你所愿。
为了更好地可视化我们在评论中所说的内容,下面是没有 v-model 的代码应该是什么样子。
输入:
<input :value="inputData" @input="updateValue($event.target.value)" :type="inputType" :id="inputId" :name="inputEnabled ? inputName : false" :placeholder="placeholder" @focus="focused = true" @blur="focused = false">
吸气剂:
get inputData() {
// you can change your prop here and return a new value.
// A lower or upper case, for example. Just don't change the prop, only use it.
return this.data;
}
更新值:
updateValue(value) {
this.$root.$emit('input', {'inputName' : this.inputName, 'inputValue' : value});
}
}
另外,我认为不需要使用$root
,因为您可以$emit
在组件中使用。对于非类组件你通过它访问this.$emit
,我相信这里应该是一样的。
您可以做的另一个更改是在 html 中监听事件:
<label-input inputId="formProductId"
inputType="number"
inputName="productId"
:inputEnabled="filters.productId.options"
:label="translations['product_id']"
:placeholder="translations['product_id']"
:data="filters.productId.value"
@updateValue="doSomething"
/>
您可以声明一个名为的方法doSomething
,它将接收到的值作为第一个参数,或者简单地将变量设置为事件接收到的值@updateValue="(value) => {filters.productId.value = value}"
。这也将起作用。
推荐阅读
- angular - 处理带有明确表单的必填字段 - Angular
- python - Pandas.read_csv 未读取完整标题
- haskell - 数据族实例:newtype、data
- flask - Flask - jinja2.exceptions.UndefinedError: 'employee' is undefined
- centos7 - CentOS - 尝试 git clone 时没有路由到主机
- coffeescript - 如何在咖啡脚本中拆分长条件表达式?
- wordpress - 从非 www 移动到 www 后 WordPress 未加载
- php - Laravel - 多重身份验证的未经身份验证的重定向问题
- python - 如何在一个while循环中添加一个计数器来跟踪月份和年份?
- python - Python 子进程给出 OSError: [WinError 193] %1 is not an valid Win32 application