vue 实现双击编辑
实现双击编辑的思路
在 Vue 中实现双击编辑功能,通常需要结合事件监听和数据绑定的特性。核心思路是通过 dblclick 事件触发编辑状态,并通过 v-model 或自定义逻辑同步数据。
基础实现方法
模板部分
<template>
<div>
<span v-if="!isEditing" @dblclick="startEditing">{{ content }}</span>
<input
v-else
ref="inputField"
v-model="content"
@blur="stopEditing"
@keyup.enter="stopEditing"
/>
</div>
</template>
脚本部分
<script>
export default {
data() {
return {
content: '双击编辑这段文字',
isEditing: false
}
},
methods: {
startEditing() {
this.isEditing = true
this.$nextTick(() => {
this.$refs.inputField.focus()
})
},
stopEditing() {
this.isEditing = false
}
}
}
</script>
进阶优化方案
添加自动选中文本功能
startEditing() {
this.isEditing = true
this.$nextTick(() => {
const input = this.$refs.inputField
input.focus()
input.select()
})
}
支持 ESC 键取消编辑
<input
v-else
ref="inputField"
v-model="tempContent"
@blur="confirmEdit"
@keyup.enter="confirmEdit"
@keyup.esc="cancelEdit"
/>
data() {
return {
originalContent: '',
tempContent: ''
}
},
methods: {
startEditing() {
this.originalContent = this.content
this.tempContent = this.content
this.isEditing = true
},
confirmEdit() {
this.content = this.tempContent
this.isEditing = false
},
cancelEdit() {
this.tempContent = this.originalContent
this.isEditing = false
}
}
封装为可复用组件
创建 EditableText.vue 组件:
<template>
<div class="editable-text">
<span v-if="!isEditing" @dblclick="startEditing">
{{ value || placeholder }}
</span>
<input
v-else
ref="input"
v-model="localValue"
@blur="handleBlur"
@keyup.enter="handleBlur"
@keyup.esc="cancelEdit"
/>
</div>
</template>
<script>
export default {
props: {
value: String,
placeholder: {
type: String,
default: '双击编辑'
}
},
data() {
return {
isEditing: false,
localValue: this.value,
originalValue: this.value
}
},
methods: {
startEditing() {
this.isEditing = true
this.originalValue = this.localValue
this.$nextTick(() => {
this.$refs.input.focus()
})
},
handleBlur() {
this.$emit('input', this.localValue)
this.isEditing = false
},
cancelEdit() {
this.localValue = this.originalValue
this.isEditing = false
}
},
watch: {
value(newVal) {
this.localValue = newVal
}
}
}
</script>
使用自定义指令实现
创建全局指令 v-editable:
Vue.directive('editable', {
bind(el, binding, vnode) {
let originalValue = binding.value
const input = document.createElement('input')
el.addEventListener('dblclick', () => {
input.value = originalValue
el.style.display = 'none'
el.parentNode.insertBefore(input, el)
input.focus()
const save = () => {
el.style.display = ''
el.textContent = input.value
originalValue = input.value
vnode.context[binding.expression] = input.value
input.remove()
}
input.addEventListener('blur', save)
input.addEventListener('keyup', (e) => {
if (e.key === 'Enter') save()
})
})
}
})
使用方式:
<span v-editable="content">{{ content }}</span>
样式优化建议
添加基础样式提升用户体验:

.editable-text {
display: inline-block;
min-width: 100px;
}
.editable-text input {
border: 1px solid #ccc;
padding: 2px 5px;
font-size: inherit;
font-family: inherit;
}
.editable-text span {
cursor: pointer;
padding: 2px 5px;
border: 1px solid transparent;
}
.editable-text span:hover {
border-color: #eee;
}
这些方法提供了从基础到高级的双击编辑实现方案,可以根据项目需求选择适合的方式。封装成组件或指令更适合在大型项目中复用,而简单实现则适用于快速原型开发。






