如何在 vue.js 2 上从父组件重置子组件中的数据?
How can I reset data in child component from parent component on vue.js 2?
我的父组件是这样的:
<template>
<div ref="modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content modal-content-data">
<form id="form-data">
...
<location-select .../>
...
</form>
</div>
</div>
</div>
</template>
<script>
import LocationSelect from './LocationSelect.vue'
export default{
name: 'CartModal',
components:{
LocationSelect,
},
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
}
</script>
如果模态隐藏,它会重置父组件中的数据并且有效
我也想在子组件中重置数据
我这样试:
<template>
<select class="form-control" v-model="selected" ...>
...
</select>
</template>
<script>
export default{
name: 'LocationSelect',
...
created() {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
};
</script>
但是不行
子组件没有重置数据
我该如何解决这个问题?
此代码的主要问题是 LocationSelect
中的处理程序正在添加 之前 this.$parent.$refs.modal
存在。在安装组件之前,ref
不存在。
解决此问题的最简单方法是将代码移至 mounted
。
mounted() {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
或者您可以将其保留在 created
中并使用 nextTick
。
created() {
this.$nextTick(() => {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
})
}
另一种处理方法是向 LocationSelect
组件添加一个 ref
并添加一个可以从 parent 调用的清除它的方法。在 LocationSelect
中添加此方法:
methods:{
clear(){
Object.assign(this.$data, this.$options.data())
}
}
在 parent 模板中添加一个参考:
<location-select ref="locationSelect" ... />
并且在你的 parent 中安装:
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
this.$refs.locationSelect.clear()
})
}
但是,用 Vue 处理这个问题的最惯用的方法是修改组件以支持 v-model
然后当 parent 被清除。
<template>
<select class="form-control" v-model="selected" ...>
...
</select>
</template>
<script>
export default {
props: ["value"],
name: 'LocationSelect',
computed:{
selected:{
get(){ return this.value },
set(v) { this.$emit('input', v) }
}
},
};
</script>
然后在 parent 模板中:
<location-select v-model="someDataValue" ... />
如果您这样做,那么当 parent 被清除时,child 也会被自动清除。
我的父组件是这样的:
<template>
<div ref="modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content modal-content-data">
<form id="form-data">
...
<location-select .../>
...
</form>
</div>
</div>
</div>
</template>
<script>
import LocationSelect from './LocationSelect.vue'
export default{
name: 'CartModal',
components:{
LocationSelect,
},
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
}
</script>
如果模态隐藏,它会重置父组件中的数据并且有效
我也想在子组件中重置数据
我这样试:
<template>
<select class="form-control" v-model="selected" ...>
...
</select>
</template>
<script>
export default{
name: 'LocationSelect',
...
created() {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
};
</script>
但是不行
子组件没有重置数据
我该如何解决这个问题?
此代码的主要问题是 LocationSelect
中的处理程序正在添加 之前 this.$parent.$refs.modal
存在。在安装组件之前,ref
不存在。
解决此问题的最简单方法是将代码移至 mounted
。
mounted() {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
}
或者您可以将其保留在 created
中并使用 nextTick
。
created() {
this.$nextTick(() => {
$(this.$parent.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
})
})
}
另一种处理方法是向 LocationSelect
组件添加一个 ref
并添加一个可以从 parent 调用的清除它的方法。在 LocationSelect
中添加此方法:
methods:{
clear(){
Object.assign(this.$data, this.$options.data())
}
}
在 parent 模板中添加一个参考:
<location-select ref="locationSelect" ... />
并且在你的 parent 中安装:
mounted(){
$(this.$refs.modal).on('hidden.bs.modal', () => {
Object.assign(this.$data, this.$options.data())
this.$refs.locationSelect.clear()
})
}
但是,用 Vue 处理这个问题的最惯用的方法是修改组件以支持 v-model
然后当 parent 被清除。
<template>
<select class="form-control" v-model="selected" ...>
...
</select>
</template>
<script>
export default {
props: ["value"],
name: 'LocationSelect',
computed:{
selected:{
get(){ return this.value },
set(v) { this.$emit('input', v) }
}
},
};
</script>
然后在 parent 模板中:
<location-select v-model="someDataValue" ... />
如果您这样做,那么当 parent 被清除时,child 也会被自动清除。