import { ref, reactive } from 'vue'
const names = reactive([
{ first: 'Emil', last: 'Hans' },
{ first: 'Mustermann', last: 'Max' },
{ first: 'Tisch', last: 'Roman' },
]);
const selectIndex = ref(-1);
function handleCurrentChange(val) {
if (val) {
selectIndex.value = names.findIndex(item => item === val);
//...
}
}
function deleteName() {
if (selectIndex.value !== -1) {
names.splice(selectIndex, 1);
}
}
<el-table :data="names" highlight-current-row @current-change="handleCurrentChange">
<el-table-column type="index" label="NO." width="50" />
<el-table-column property="first" label="First Name" />
<el-table-column property="last" label="Last Name" />
</el-table>
<el-button type="danger" round @click="deleteName">Delete</el-button>
在练习使用vue3的时候,写了上面这段代码,需求是:选择表格中的一行,点击Delete按钮时将这行数据删除。
于是我写了上面这段脚本,发现效果不理想,无论选中哪一行,删除的永远是第一行!然后我很自然地怀疑是不是selectIndex
的值没维护好,但是看了看Devtools发现他也是对的。
卡在这儿半天,后来猛地发现selectIndex
没加.value
!哎,那为什么names.splice(selectIndex, 1);
不报错呢?
查了MDN发现,splice方法的第一个参数如果传的不是整数,会被转为整数。
比如我这里传了一个对象,对象在转换为数值时,首先会调用对象的 valueOf 方法,如果返回的不是一个数值类型,JavaScript 会进一步调用 toString 方法来将对象转换为字符串,然后再尝试将该字符串转换为数值。 如果对象最终无法转换为有效的数值(比如返回的字符串是 "[object Object]"),那么它会被转换为 NaN,最终 splice 会使用 0 作为索引。
开发人员在设计splice方法的时候,为了提高容错率而在这里做了隐式类型转换,我这里反而受其害,要是它抛出异常我就能早发现这里漏了.value
了......