VueJs 与父组件的反应性 属性 对象
VueJs reactivity with parent component property object
我很难获得父组件的 属性 对象,它具有动态填充的属性以使值在同一组件内可用。
有点难解释,请看下面的例子:
父组件
<script>
export default {
data() {
return {
fields: {},
}
}
}
</script>
子组件
<template>
<select
@change="update()"
v-model="field"
>
<option
v-for="option in options"
:value="option.value"
>
{{ option.name }}
</option>
</select>
</template>
<script>
export default {
props: {
initialOptions: {
type: Array,
required: true
}
},
data() {
return {
field: '',
options: this.initialOptions
}
},
mounted() {
if (
(this.field === undefined || this.field === '') &&
this.options.length > 0
) {
this.field = this.options[0].value;
}
this.update();
},
methods: {
update() {
this.$emit('input', this.field);
}
}
}
</script>
DOM
<parent-component inline-template>
<div>
<child-component>
:initial-options="[{..}, {..}]"
v-model="fields.type_id"
></child-component>
</div>
<div :class="{ dn : fields.type_id == 2 }">
// ...
</div>
</parent-component>
使用 Vue 控制台我可以看到 fields
对象获取所有子组件模型及其关联值,因为它们在安装时发出 input
,但是由于某些奇怪的原因 :class="{ dn : fields.type_id == 2 }"
does not append the class dn
when the selection changes to 2
. Dom 似乎没有反映在父组件和子组件之间同步的更改。
关于如何让它工作的任何帮助?
这是我在评论中试图表达的意思。 Vuecannot detect changes to properties that are added dynamically to an object unless you add them using $set。您的 fields
对象没有 type_id
属性,但它会被添加,因为您正在使用 v-model="fields.type_id"
。因此,Vue 不知道它何时更改。
在这里,我添加了它,并且文本的颜色如您所料的那样改变了。
console.clear()
Vue.component("child-component", {
template: `
<select
@change="update()"
v-model="field"
>
<option
v-for="option in options"
:value="option.value"
>
{{ option.name }}
</option>
</select>
`,
props: {
initialOptions: {
type: Array,
required: true
}
},
data() {
return {
field: '',
options: this.initialOptions
}
},
mounted() {
if (
(this.field === undefined || this.field === '') &&
this.options.length > 0
) {
this.field = this.options[0].value;
}
this.update();
},
methods: {
update() {
this.$emit('input', this.field);
}
}
})
new Vue({
el: "#app",
data: {
fields: {
type_id: null
}
}
})
.dn {
color: red;
}
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<div>
<child-component :initial-options="[{name: 'test', value: 1}, {name: 'test2', value: 2}]" v-model="fields.type_id"></child-component>
</div>
<div :class="{ dn : fields.type_id == 2 }">
Stuff
</div>
</div>
看起来您正在尝试制作可重复使用的组件。
我会问自己,当父组件必须处理一半以上的工作时,可重用组件的价值是什么。该组件的名称可能更好...
<DifficultToUseSelect/>.
本质上,您正在创建一个组件,它本身提供以下所有功能 HTML...
<select></select>
其他一切都由父组件管理。
执行以下任一操作可能会更有用...
将经常需要的选项封装在特定的 select 组件中,如
StateAbbrevsSelect v-model="状态"
将数据模型的名称传递给 select 组件。然后组件将通过模型加载和管理自己的数据。
将 Web 服务的 URL 传递给组件,然后组件调用它来加载其选项。
同样,我想在这里传达的主要观点是,制作一个可重用的组件,其中超过一半的工作量由父组件处理,实际上不是很可重用。
我很难获得父组件的 属性 对象,它具有动态填充的属性以使值在同一组件内可用。
有点难解释,请看下面的例子:
父组件
<script>
export default {
data() {
return {
fields: {},
}
}
}
</script>
子组件
<template>
<select
@change="update()"
v-model="field"
>
<option
v-for="option in options"
:value="option.value"
>
{{ option.name }}
</option>
</select>
</template>
<script>
export default {
props: {
initialOptions: {
type: Array,
required: true
}
},
data() {
return {
field: '',
options: this.initialOptions
}
},
mounted() {
if (
(this.field === undefined || this.field === '') &&
this.options.length > 0
) {
this.field = this.options[0].value;
}
this.update();
},
methods: {
update() {
this.$emit('input', this.field);
}
}
}
</script>
DOM
<parent-component inline-template>
<div>
<child-component>
:initial-options="[{..}, {..}]"
v-model="fields.type_id"
></child-component>
</div>
<div :class="{ dn : fields.type_id == 2 }">
// ...
</div>
</parent-component>
使用 Vue 控制台我可以看到 fields
对象获取所有子组件模型及其关联值,因为它们在安装时发出 input
,但是由于某些奇怪的原因 :class="{ dn : fields.type_id == 2 }"
does not append the class dn
when the selection changes to 2
. Dom 似乎没有反映在父组件和子组件之间同步的更改。
关于如何让它工作的任何帮助?
这是我在评论中试图表达的意思。 Vuecannot detect changes to properties that are added dynamically to an object unless you add them using $set。您的 fields
对象没有 type_id
属性,但它会被添加,因为您正在使用 v-model="fields.type_id"
。因此,Vue 不知道它何时更改。
在这里,我添加了它,并且文本的颜色如您所料的那样改变了。
console.clear()
Vue.component("child-component", {
template: `
<select
@change="update()"
v-model="field"
>
<option
v-for="option in options"
:value="option.value"
>
{{ option.name }}
</option>
</select>
`,
props: {
initialOptions: {
type: Array,
required: true
}
},
data() {
return {
field: '',
options: this.initialOptions
}
},
mounted() {
if (
(this.field === undefined || this.field === '') &&
this.options.length > 0
) {
this.field = this.options[0].value;
}
this.update();
},
methods: {
update() {
this.$emit('input', this.field);
}
}
})
new Vue({
el: "#app",
data: {
fields: {
type_id: null
}
}
})
.dn {
color: red;
}
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<div>
<child-component :initial-options="[{name: 'test', value: 1}, {name: 'test2', value: 2}]" v-model="fields.type_id"></child-component>
</div>
<div :class="{ dn : fields.type_id == 2 }">
Stuff
</div>
</div>
看起来您正在尝试制作可重复使用的组件。
我会问自己,当父组件必须处理一半以上的工作时,可重用组件的价值是什么。该组件的名称可能更好...
<DifficultToUseSelect/>.
本质上,您正在创建一个组件,它本身提供以下所有功能 HTML...
<select></select>
其他一切都由父组件管理。
执行以下任一操作可能会更有用...
将经常需要的选项封装在特定的 select 组件中,如
StateAbbrevsSelect v-model="状态"
将数据模型的名称传递给 select 组件。然后组件将通过模型加载和管理自己的数据。
将 Web 服务的 URL 传递给组件,然后组件调用它来加载其选项。
同样,我想在这里传达的主要观点是,制作一个可重用的组件,其中超过一半的工作量由父组件处理,实际上不是很可重用。