Поля ввода Vue.js
<h4 v-if="!showInput" class="card-title" @click="showInput = true" {{dataObject.attributes['name']}}</h4>
<input v-else type="text" v-model="title" v-on:keyup.enter="event => editField(event, 'name'),showInput = false ">
<h4 v-if="!showInput" class="card-title" @click="showInput = true" {{dataObject.attributes['surname']}}</h4>
<input v-else type="text" v-model="title" v-on:keyup.enter="event => editField(event, 'surname'),showInput = false ">
<h4 v-if="!showInput" class="card-title" @click="showInput = true" {{dataObject.attributes['age']}}</h4>
<input v-else type="text" v-model="title" v-on:keyup.enter="event => editField(event, 'age'),showInput = false ">
Есть поля вода порядка 10 шт, при клике по h4 он скрывается и появляется input, который по нажатию enter улетает в функцию и там обрабатывается.
Сейчас при клике по h4 открываются все формы, как решить чтоб каждый редактировался индивидуально ?
editField(event, key) {
const value = event.target.innerText;
if(value !== this.dataObject.attributes[key]){
this.dataObject.attributes[key] = value;
axios.post(this.postURL, {user_id: this.dataObject.id, field_name: key, field_value: value})
}
},
Ответы (1 шт):
На мой взгляд, нужно стараться использовать компонентный подход vue. Я бы сделал компонент, который заведовал бы логикой и данными для решения вашей задачи.
Это ни в коем случае не эталон, но как наглядный пример сойдет, а именно показывает как компонент "разгружает" родительский компонент (здесь приложение) и берет на себя всю работу по решению вашей задачи, т.е. взял данные из родителя и уже сам решает когда ему что показать (конечно в зависимости от действий пользователя): поле ввода <input> или текст <h4>, а в родитель отдает уже готовые данные для синхронизации.
Vue.component('inputForm', {
props: {
value: {
type: String,
required: true
}
},
data() {
return {
keyInputForm: null,
thisValue: this.value
}
},
template: `
<div>
<h4 v-if="!keyInputForm" class="card-title" @click="keyInputForm = true">{{ value }}</h4>
<input v-else type="text" :value="value" v-model="thisValue" @input="$emit('input', thisValue)" @blur="keyInputForm = false">
</div>
`
})
new Vue({
el: "#app",
data: {
dataObject: {
name: 'Name',
surname: 'Surname',
age: '17'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<input-form v-model="dataObject[key]" :key="key"></input-form>
<hr> Это объект dataObject
<pre>
{{ dataObject }}
</pre>
</div>
Здесь без v-for
Vue.component('inputForm', {
props: {
value: {
type: String,
required: true
}
},
data() {
return {
keyInputForm: null,
thisValue: this.value
}
},
template: `
<div>
<h4 v-if="!keyInputForm" class="card-title" @click="keyInputForm = true">{{ value }}</h4>
<input v-else type="text" :value="value" v-model="thisValue" @input="$emit('input', thisValue)" @blur="keyInputForm = false">
</div>
`
})
new Vue({
el: "#app",
data: {
dataObject: {
name: 'Name',
surname: 'Surname',
age: '17'
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<input-form v-model="dataObject.name"></input-form>
<input-form v-model="dataObject.surname"></input-form>
</div>
с функцией, добавленной в компонент
Vue.component('inputForm', {
props: {
value: {
type: String,
required: true
},
name: {
type: String,
required: true
}
},
data() {
return {
keyInputForm: null,
thisValue: this.value
}
},
template: `
<div>
<h4 v-if="!keyInputForm" class="card-title" @click="keyInputForm = true">{{ value }}</h4>
<input v-else type="text" :value="value" :name="name" v-model="thisValue" @input="$emit('input', thisValue)" @blur="keyInputForm = false;$emit('edit-field', $event)">
</div>
`
})
new Vue({
el: "#app",
data: {
dataObject: {
name: 'Name',
surname: 'Surname',
age: '17',
id: 1
}
},
methods: {
editField(e) {
console.clear();
const value = e.target.value;
const key = e.currentTarget.getAttribute('name');
// axios.post(this.postURL, { user_id: this.dataObject.id, field_name: key, field_value: value })
console.log('axios post => ', {
user_id: this.dataObject.id,
field_name: key,
field_value: value
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<input-form v-model="dataObject.name" name="name" @edit-field="editField"></input-form>
<input-form v-model="dataObject.surname" name="surname" @edit-field="editField"></input-form>
</div>
и на случай, когда нет свойства на которое ссылается v-model, допустим:
dataObject: {
name: 'Name',
// surname: 'Surname',
age: '17',
id: 1
}
наглядный пример:
Vue.component('inputForm', {
props: ['value', 'name'],
data() {
return {
keyInputForm: null,
thisValue: this.value
}
},
template: `
<div>
<button v-if="!thisValue && !keyInputForm" @click="keyInputForm=true;thisValue=''">Добавить {{ name }}</button>
<div>
<h4 v-if="!keyInputForm" class="card-title" @click="keyInputForm = true">{{ value }}</h4>
<input v-else type="text" :value="value" :name="name" v-model="thisValue" @input="$emit('input', thisValue)" @blur="keyInputForm = false;$emit('edit-field', $event)">
</div>
</div>
`
})
new Vue({
el: "#app",
data: {
dataObject: {
name: 'Name',
// surname: undefined,
age: '17',
id: 1
}
},
methods: {
editField(e) {
console.clear();
const value = e.target.value;
const key = e.currentTarget.getAttribute('name');
// axios.post(this.postURL, { user_id: this.dataObject.id, field_name: key, field_value: value })
console.log('axios post => ', {
user_id: this.dataObject.id,
field_name: key,
field_value: value
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
<input-form v-model="dataObject.name" name="name" @edit-field="editField"></input-form>
<input-form v-model="dataObject.surname" name="surname" @edit-field="editField"></input-form>
</div>