[英]Adding 'input' used to edit array object key in selected elements - Vue.js
我需要在當前選定的元素組件中添加一個用於編輯title
的input
字段(選擇是通過單擊完成的)。 問題是每個選定的元素都應該有一個輸入和工作。 我在互聯網上找不到類似的任務和解決方案。 也許有人會告訴你怎么做?
ItemsList.vue
組件:
<template>
<input type="text" placeholder="Edit selected items"/>
<div class="items-col">
<ul class="items-list">
<Item v-for="item in items" :key="item" :title="item.title"/>
</ul>
</div>
</template>
<script>
import Item from '@/components/Item.vue'
export default {
data() {
return {
items: [
{ title: 'item 1' },
{ title: 'item 2' },
{ title: 'item 3' },
{ title: 'item 4' },
{ title: 'item 5' },
{ title: 'item 6' }
]
}
},
components: {
Item
}
}
</script>
Item.vue
組件:
<template>
<li class="item" @click="isActive = !isActive" :class="{ active: isActive }">{{ title }}</li>
</template>
<script>
export default {
name: 'ItemsList',
data() {
return {
isActive: false
}
},
props: {
title: String
}
}
</script>
<style>
.item.active {
color: red;
}
</style>
您可能需要重新考慮哪個組件應該負責知道哪個項目在任何時間點處於活動狀態:提示:它應該是父/消費組件。 那是因為你:
因此,您應該做的第一件事是確保isActive
是Item
組件上的一個 prop,而父ItemList
組件會隨時跟蹤哪個處於活動狀態。
那么,這只是一個問題:
isActive
標志實現切換邏輯。 當從Item
組件觸發本機單擊事件時,會更新該標志。 對於切換邏輯,我們可以簡單地在點擊項的從零開始的索引或-1
之間切換,我們用它來表示沒有任何活動。v-bind:value
和一個計算屬性來反映當前活動項的值。 我們可以簡單地在父組件上使用this.items[this.activeIndex]
來檢索它onInput
事件,然后更新正確的項目請參閱下面的概念驗證:
Vue.component('item-list', { template: '#item-list-template', data() { return { items: [{ title: 'item 1' }, { title: 'item 2' }, { title: 'item 3' }, { title: 'item 4' }, { title: 'item 5' }, { title: 'item 6' } ], activeIndex: -1, } }, methods: { onItemClick(index) { this.activeIndex = this.activeIndex === index ? -1 : index; }, setActiveItemValue(event) { const foundItem = this.items[this.activeIndex]; if (!foundItem) return; return this.items[this.activeIndex].title = event.currentTarget.value; } }, computed: { activeItemValue() { return this.items[this.activeIndex]?.title ?? ''; } } }); Vue.component('item', { template: '#item-template', props: { isActive: Boolean, title: String } }); new Vue({ el: '#app' });
li.active { background-color: yellow; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <item-list></item-list> </div> <script type="text/x-template" id="item-list-template"> <div> <input type="text" placeholder="Edit selected items" :value="activeItemValue" @input="setActiveItemValue" /> <div class="items-col"> <ul class="items-list"> <item v-for="(item, i) in items" :key="i" :title="item.title" :isActive="activeIndex === i" @click.native="onItemClick(i)" /> </ul> </div> </div> </script> <script type="text/x-template" id="item-template"> <li class="item" :class="{ active: isActive }">{{ title }}</li> </script>
如果您想要使用當前組件(不是最干凈的)的解決方案,當您激活一個元素時,您實際上可以向父組件發出一個事件,該事件應包含項目數組中對象的索引
然后你可以使用索引來獲取和設置標題變量,這是一個例子:
項目.vue
<template>
<li class="item" @click="activateItem" :class="{ active: isActive }">{{ title }}</li>
</template>
<script>
export default {
name: 'ItemsList',
data() {
return {
isActive: false
}
},
methods:{
activateItem() {
this.isActive = !this.isActive
this.$emit('activatedItem', this.isActive ? this.index : null)
}
},
props: {
title: String,
index: Number
}
}
</script>
<style>
.item.active {
color: red;
}
</style>
項目列表.vue
<template>
<div>
<input type="text" placeholder="Edit selected items" @input="inputChange" :value="inputValue"/>
<div class="items-col">
<ul class="items-list">
<Item v-for="(item, index) in items" :key="index" :title="item.title" :index="index" @activatedItem="itemSelected"/>
</ul>
</div>
</div>
</template>
<script>
import Item from '@/components/Item.vue'
export default {
data() {
return {
items: [
{ title: 'item 1' },
{ title: 'item 2' },
{ title: 'item 3' },
{ title: 'item 4' },
{ title: 'item 5' },
{ title: 'item 6' }
],
selectedIndex: null,
inputValue: ''
}
},
methods:{
itemSelected(index){
this.selectedIndex = index;
if(this.selectedIndex != null) {
this.inputValue = this.items[this.selectedIndex].title;
}
},
inputChange(event){
this.inputValue = event.target.value;
if(this.selectedIndex != null){
this.items[this.selectedIndex].title = this.inputValue
}
}
},
components: {
Item
}
}
</script>
您還應該知道,使用您提供的組件 Item,您可以選擇多個項目!
對於您的第二個問題,您應該只更改索引以匹配數組中的索引,例如,如果 rowIndex 以 1 開頭:
onItemClick(index, rowIndex) {
let correctIndex = (index + (this.itemsPerRow * (rowIndex - 1));
this.activeIndex = this.activeIndex === correctIndex ? -1 : correctIndex);
},
謝謝各位,運行正常。
此任務的另一個問題:
如何使其在元素位於 3 個項目的行中的條件下工作?
例如我需要得到這個最終效果:
<ul class="items-list">
//my Item.vue component
<li class="item" :class="{ active: isActive }">item 1</li>
//my Item.vue component
<li class="item" :class="{ active: isActive }">item 2</li>
//my Item.vue component
<li class="item" :class="{ active: isActive }">item 3</li>
</ul>
<ul class="items-list">
//my Item.vue component
<li class="item" :class="{ active: isActive }">item 4</li>
//my Item.vue component
<li class="item" :class="{ active: isActive }">item 5</li>
//my Item.vue component
<li class="item" :class="{ active: isActive }">item 6</li>
</ul>
我寫了一個方法,將項目連續 3 分隔,在您的解決方案之后,我有以下內容:
ItemsList.vue
組件:
<template>
<div class="items-col">
<input type="text" placeholder="Edit selected items" :value="activeItemValue" @input="setActiveItemValue" />
<ul class="items-list" v-for="index in rowCount" :key="index">
<Item v-for="(item, i) in itemCountInRow(index)" :key="i" :title="item.title" :isActive="activeIndex === i" @click="onItemClick(i)"/>
</ul>
</div>
</template>
<script>
import Item from '@/components/Item.vue'
export default {
name: 'ItemsList',
data() {
return {
items: [
{ title: 'item 1' },
{ title: 'item 2' },
{ title: 'item 3' },
{ title: 'item 4' },
{ title: 'item 5' },
{ title: 'item 6' },
],
activeIndex: -1,
itemsPerRow: 3
}
},
components: {
Item
},
computed: {
rowCount(){
return Math.ceil(this.items.length / this.itemsPerRow);
},
activeItemValue() {
return this.items[this.activeIndex]?.title ?? '';
}
},
methods: {
onItemClick(index) {
this.activeIndex = this.activeIndex === index ? -1 : index;
},
setActiveItemValue(event) {
const foundItem = this.items[this.activeIndex];
if (!foundItem) return;
return this.items[this.activeIndex].title = event.currentTarget.value;
},
itemCountInRow(index){
return this.items.slice((index - 1) * this.itemsPerRow, index * this.itemsPerRow)
}
}
}
</script>
現在,當我單擊該項目時,您的方法僅適用於第一個列表。
是否可以使其與每行 3 個項目的划分一起工作?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.