想写一个todolist的小demo的时候发现了这个问题,查阅了文档可得知。
v-for 利用 ref获取dom节点的话 节点不唯一,无法获取到,提示为null。
<li v-for="(item,index) in lists" :key="index+ new Date()">
<div v-if="!item.checked">
<input type="checkbox" v-model="item.checked" @change="()=>item.checked =true"/>
<span v-if="!item.isEdit">{{ item.name }}</span>
<input id="aInput" type="text" v-else v-model="item.name" ref="itemRef"/>
<button @click="item.isEdit = !item.isEdit, handleEdit(index)">编辑</button>
</div>
</li>
<script>
import { computed, reactive, toRefs, ref } from 'vue';
export default {
name: 'todoList',
setup() {
let itemRef = ref(null);
const addList = () => {
state.lists.push({
name: state.value,
checked: false,
isEdit: false
})
state.lists.value = ''
}
const mouseDown =(e) => {
if (e.target !== document.getElementById('aInput')) {
state.lists[state.currentIndex].isEdit = false
}
}
const handleEdit = (index) => {
state.currentIndex = index
}
const state = reactive({
currentIndex: 0,
value: '',
lists: [{
name: '1',
checked: false,
isEdit: false
},{
name: '2',
checked: false,
isEdit: false
},{
name: '3',
checked: false,
isEdit: false
}],
finish: computed(()=> state.lists.filter((item)=> {
return item.checked === true
})),
addList,
mouseDown,
handleEdit,
itemRef
})
return toRefs(state)
}
}
</script>
可用 如下代码代替
<input id="aInput" type="text" v-else v-model="item.name" :ref="el => itemRef = el" />
给它单向绑定:ref 后使得itemRef = el,获取到dom节点 进行后续的判断。