对element ui动态可编辑的tag进行优化,点击tag后变为input可编辑
https://element.eleme.io/#/zh-CN/component/tag
重点1:$set的用法 修改响应数据
在data中声明editable: [], 通过this.$set(this.editable, index, true);来修改数组
this.$set(vm.item, indexOfItem, newValue); this.set(vm.item, indexOfItem, newValue); 参数1:要处理的数组名称 参数2:要处理的数组索引 参数3:要处理的数组的值
this.$
set(this.editable
, index
, true);
重点2: ref的使用
ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。
如果ref 是循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了。
this.$refs
[editableInput
][0].$refs
.input
.focus();
重点3:element ui 中input获取焦点
Vue.nextTick()
在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中 在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。
this.$nextTick((_
) => {
this.$refs
.saveTagInput
.$refs
.input
.focus();
});
源代码
<template>
<el-form
label-width="100px"
class="my-form"
size="mini"
label-position="left"
>
<el-form-item label="部门职位">
<div class="inline-box">
<div v-for="(tag, index) in depatment_role_name" :key="index">
<el-input
class="input-new-tag"
v-if="editable[index]"
v-model="tag.label"
:ref="'editableInput' + index"
size="small"
placeholder="请输入职位"
@keyup.enter.native="handleEditableInputConfirm(tag, index)"
@change="handleEditableInputConfirm(tag, index)"
@blur="handleEditableInputBlur(tag, index)"
maxlength="20"
show-word-limit
></el-input>
<el-tag
v-else
@click="showEditTagInput(index)"
closable
:disable-transitions="false"
@close="handleClose(tag, index)"
>{{ tag.label }}
</el-tag
>
</div>
<div>
<el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm"
@blur="handleInputConfirm"
maxlength="20"
show-word-limit
></el-input>
<el-button
v-else
class="button-new-tag"
size="small"
@click="showInput"
>+ 新增职位
</el-button
>
</div>
</div>
</el-form-item>
</el-form>
</template>
export default {
components
: {
},
data() {
return {
depatment_role_name
: [
{
value
: 1,
label
: "选择1",
},
{
value
: 2,
label
: "选择2",
},
{
value
: 3,
label
: "选择3",
},
],
inputVisible
: "",
editable
: [],
inputValue
: "",
};
},
methods
: {
showInput() {
this.inputVisible
= true;
this.$nextTick((_
) => {
this.$refs
.saveTagInput
.$refs
.input
.focus();
});
},
handleInputConfirm() {
let inputValue
= this.inputValue
;
if (inputValue
) {
var tagInfo
= {
label
: inputValue
,
value
: this.depatment_role_name
.length
+ 1,
};
this.depatment_role_name
.push(tagInfo
);
}
this.inputVisible
= false;
this.inputValue
= "";
},
showEditTagInput(index
) {
this.$
set(this.editable
, index
, true);
this.$nextTick((_
) => {
var editableInput
= "editableInput" + index
;
this.$refs
[editableInput
][0].$refs
.input
.focus();
});
},
handleEditableInputConfirm(item
, index
) {
if (item
.label
) {
this.$
set(this.editable
, index
, false);
} else {
this.$message({ message
: "请输入职位信息", type
: "info" });
}
},
handleEditableInputBlur(item
, index
) {
this.$
set(this.editable
, index
, false);
},
handleClose(tag
, index
) {
this.depatment_role_name
.splice(index
, 1);
},
},
};
.inline-box {
display: flex
;
}
.inline-box > div {
margin-right: 5px
;
}