【发布时间】:2019-12-23 09:19:40
【问题描述】:
我正在使用 Vue.js。在我的模板中,我包含了包含多个输入元素的子组件 (componentB)。我想从我的父模板初始化这些输入元素。我找到了一种方法来做到这一点(见下面的代码)。但是,我想知道这是否是正确的方法,因为到目前为止我阅读的文章使用不同的方法(例如使用 $emit):
- https://simonkollross.de/posts/vuejs-using-v-model-with-objects-for-custom-components
- https://zaengle.com/blog/using-v-model-on-nested-vue-components
- https://alligator.io/vuejs/add-v-model-support/
您能否确认我的以下代码符合 Vue.js 的设计理念或是否存在缺陷?
<template>
<div>
<div class="md-layout">
<div class="md-layout-item md-size-100">
<ComponentB ref="componentB" v-model="componentB"></ComponentB>
</div>
</div>
</div>
</template>
<script>
import { ComponentB } from "@/components";
export default {
components: {
ComponentB
},
data() {
return {
componentB: {
textInputField: "my-initial-value"
}
};
},
methods: {
validate() {
return this.$refs.componentB.validate().then(res => {
this.$emit("on-validated", res);
return res;
});
}
}
};
</script>
<style></style>
表单组件B
<template>
<div>
<md-field
:class="[
{ 'md-valid': !errors.has('textInputField') && touched.textInputField },
{ 'md-form-group': true },
{ 'md-error': errors.has('textInputField') }
]"
>
<md-icon>label_important</md-icon>
<label>My text input</label>
<md-input
v-model="textInputField"
data-vv-name="textInputField"
type="text"
name="textInputField"
required
v-validate="modelValidations.textInputField"
>
</md-input>
<slide-y-down-transition>
<md-icon class="error" v-show="errors.has('textInputField')"
>close</md-icon
>
</slide-y-down-transition>
<slide-y-down-transition>
<md-icon
class="success"
v-show="!errors.has('textInputField') && touched.textInputField"
>done</md-icon
>
</slide-y-down-transition>
</md-field>
</div>
</template>
<script>
import { SlideYDownTransition } from "vue2-transitions";
export default {
name: "componentB",
props: ['value'],
components: {
SlideYDownTransition
},
computed: {
textInputField: {
get() {return this.value.textInputField},
set(textInputField) { this.$emit('input', { ...this.value, ['textInputField']: textInputField })}
}
},
data() {
return {
touched: {
textInputField: false
},
modelValidations: {
textInputField: {
required: true,
min: 5
}
}
};
},
methods: {
getError(fieldName) {
return this.errors.first(fieldName);
},
validate() {
return this.$validator.validateAll().then(res => {
return res;
});
}
},
watch: {
textInputField() {
this.touched.runnerName = true;
}
}
};
</script>
<style></style>
【问题讨论】:
-
数据/属性传输(在您的情况下是初始化)理想情况下应该通过
props进行。$emit是其他方式 OR pubsub 的一般用例。 -
明白了。另外,你能看到当前代码有什么问题吗?
标签: javascript vue.js vue-component