Vue.js Компонент с v-моделью
Мне удалось добиться двухуровневого связывания v-модели на одном уровне с пользовательским компонентом, но мне нужно сделать его еще глубже.
Текущий рабочий код:
<template lang="html">
<div class="email-edit">
<input ref="email" :value="value.email" @input="updateInput()"/>
<input ref="body" :value="value.body" @input="updateInput()"/>
</div>
</template>
<script type="text/javascript">
import LineEditor from './LineEditor.vue'
export default {
components: {
LineEditor
},
computed: {
},
methods: {
updateInput: function(){
this.$emit('input',{
email: this.$refs.email.value,
body: this.$refs.body.value
})
}
},
data: function(){
return {}
},
props: {
value: {
default: {
email: "",
body: ""
},
type:Object
}
}
}
</script>
Используется так: <email-edit-input v-model="emailModel" />
Однако, если я добавлю этот кусок, значение больше не будет распространяться вверх:
<div class="email-edit">
<line-editor ref="email" :title="'Email'" :value="value.email" @input="updateInput()"/>
<input ref="body" :value="value.body" @input="updateInput()"/>
</div>
</template>
<script type="text/javascript">
import LineEditor from './LineEditor.vue'
export default {
components: {
LineEditor
},
computed: {
},
methods: {
updateInput: function(){
this.$emit('input',{
email: this.$refs.email.value,
body: this.$refs.body.value
})
}
},
data: function(){
return {}
},
props: {
value: {
default: {
email: "",
body: ""
},
type:Object
}
}
}
</script>
Используя этот второй пользовательский компонент:
<template lang="html">
<div class="line-edit">
<div class="line-edit__title">{{title}}</div>
<input class="line-edit__input" ref="textInput" type="text" :value="value" @input="updateInput()" />
</div>
</template>
<script type="text/javascript">
export default {
components: {
},
computed: {
},
methods: {
updateInput: function(){
this.$emit('input', this.$refs.textInput.value)
}
},
data: function(){
return {}
},
props: {
title:{
default:"",
type:String
},
value: {
default: "",
type: String
}
}
}
</script>
Первый блок кода работает нормально только с вводом. Тем не менее, использование двух пользовательских компонентов, кажется, не всплывает через оба компонента, только LineEditor. Как я могу получить эти значения, чтобы пузыриться через все пользовательские компоненты, независимо от вложенности?
2 ответа
Я немного обновил ваш код для обработки с помощью v-модели ваших компонентов, чтобы вы могли передавать значения по дереву, а также создавать резервные копии дерева. Я также добавил наблюдателей к вашим компонентам, так что если вам нужно обновить значение объекта электронной почты вне компонента редактора электронной почты, обновления будут отражены в компоненте.
console.clear()
const LineEditor = {
template:`
<div class="line-edit">
<div class="line-edit__title">{{title}}</div>
<input class="line-edit__input" type="text" v-model="email" @input="$emit('input',email)" />
</div>
`,
watch:{
value(newValue){
this.email = newValue
}
},
data: function(){
return {
email: this.value
}
},
props: {
title:{
default:"",
type:String
},
value: {
default: "",
type: String
}
}
}
const EmailEditor = {
components: {
LineEditor
},
template:`
<div class="email-edit">
<line-editor :title="'Email'" v-model="email" @input="updateInput"/>
<input :value="value.body" v-model="body" @input="updateInput"/>
</div>
`,
watch:{
value(newValue){console.log(newValue)
this.email = newValue.email
this.body = newValue.body
}
},
methods: {
updateInput: function(value){
this.$emit('input', {
email: this.email,
body: this.body
})
},
},
data: function(){
return {
email: this.value.email,
body: this.value.body
}
},
props: {
value: {
default: {
email: "",
body: ""
},
type: Object
}
}
}
new Vue({
el:"#app",
data:{
email: {}
},
components:{
EmailEditor
}
})
<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<div id="app">
<email-editor v-model="email"></email-editor>
<div>
{{email}}
</div>
<button @click="email={email:'testing@email', body: 'testing body' }">change</button>
</div>
В приведенном выше примере при вводе значений во входные данные обновляется родительский элемент. Кроме того, я добавил кнопку, которая изменяет значение родительского элемента для имитации изменения значения вне компонента и изменений, отражаемых в компонентах.
Там нет никакой реальной причины для использования ref
S вообще для этого кода.
В моем случае не удалось выполнить сквозной перенос вручную для обоих компонентов. Тем не менее, замена моего первого пользовательского компонента следующим образом:
<line-editor ref="email" :title="'Email'" v-model="value.email"/>
<input ref="body" :value="value.body" @input="updateInput()"/>
Используя только v-модель в первом компоненте и затем позволяя второму пользовательскому компоненту излучать вверх, добились цели.