簡體   English   中英

如何有條件地在范圍內的 Vue 組件中附加一個元素?

[英]How to conditionally append an element in a scoped Vue Component?

我正在嘗試為可以在雙擊時編輯的標題創建一個組件。 該組件將應該使用的 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM