我正在尝试为标题创建一个组件,当它们被双击时可以对其进行编辑。组件将应使用的h-tag和标题作为道具,并应产生一个普通的h-tag,一旦双击,它将变为一个输入字段。如果页面上只有一个标题,这已经可以工作,但是,一旦一个页面上使用了多个组件,它就会中断,因为该组件的作用域不正确。但是我不知道怎么做。这是代码:
<template>
<div class="edit-on-click">
<input
:class="sizeClass"
type="text"
v-if="edit"
v-model="editedTitle"
@blur="finishEdit"
@keyup.enter="finishEdit"
v-focus="true"
/>
<span v-show="!edit" @dblclick.prevent="edit = true"></span>
</div>
</template>
我不知道如何确定范围的已安装挂钩:
mounted() {
let node = document.createElement(this.size); // Takes h-tag (h1, h2 etc.)
let titleText = document.createTextNode(this.finalTitle); // Takes title
node.appendChild(titleText);
node.classList.add("editable-title");
// This breaks the code once there are multiple components in the document
document.getElementsByTagName("span")[0].appendChild(node);
},
我如何有效地确定范围?预先非常感谢!
嗯,使用Vue,您可能希望避免在任何可能的情况下以“本机”方式创建DOM元素,因为您可能会遇到竞争条件,在这种情况下Vue不知道这些元素的存在,您可能希望在某些情况下做出反应时间点(在您的情况下,双击<span>
)。
您可能要做的是,使用此<component>
和v-bind:is
属性在这些不同的标题之间动态“切换”。考虑以下示例:
Vue.component('EditableHeading', {
template: '#editable-heading',
props: {
size: {
type: String,
default: 'h1'
},
value: {
type: String,
required: true
}
},
data() {
return {
editing: false
}
},
methods: {
confirm(e) {
this.$emit('input', e.target.value);
this.close();
},
start() {
this.editing = true;
this.$nextTick(() => {
this.$el.querySelector('input[type="text"]').select();
});
},
close() {
this.editing = false;
}
}
})
new Vue({
el: '#app',
data: () => ({
titleList: [],
text: 'New Title',
size: 'h3'
}),
methods: {
addNewTitle() {
this.titleList.push({
text: this.text,
size: this.size
});
}
}
})
.edit-on-click {
user-select: none;
}
.heading-size {
margin-top: 1rem;
width: 24px;
}
p.info {
background-color: beige;
border: 1px solid orange;
color: brown;
padding: 4px 5px;
margin-top: 2rem;
}
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="app">
<editable-heading
v-for="(title, index) of titleList" :key="index"
v-model="title.text"
:size="title.size">
</editable-heading>
<div>
<label>
Heading size:
<input v-model="size" class="heading-size" />
</label>
</div>
<div>
<label>
Title:
<input v-model="text" />
</label>
</div>
<div>
<button @click="addNewTitle()">Add new title</button>
</div>
<p class="info">
[double-click]: Edit <br />
[enter]: Confirm <br />
[esc/mouseleave]: Cancel
</p>
</div>
<script id="editable-heading" type="text/x-template">
<div class="edit-on-click">
<input
type="text"
v-if="editing"
:value="value"
@blur="close"
@keydown.enter="confirm"
@keydown.esc="close" />
<component :is="size" v-else @dblclick="start">{{value}}</component>
</div>
</script>