条件付きスコープVueのコンポーネントに要素を追加する方法?

脇:

私は、彼らがダブルクリックされ得るときに編集することができますタイトルのためにコンポーネントを作成しようとしています。コンポーネントがダブルクリックされた後の入力フィールドに、そのターンを小道具として使用されるべきH-タグとタイトルを取り、通常のH-タグを生成しなければなりません。1つのページに使用される複数のコンポーネントがあるしかし一度、ページ上の1つのタイトルのみが存在する場合、これはすでにコンポーネントが適切にスコープされていないとして、それが壊れる、動作します。しかし、私はどのように把握することはできません。ここでは、コードは次のようになります。

<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);
  },

どのように効率的な方法でIスコープこれはできますか?事前にどうもありがとうございました!

ヨムS.:

まあ、Vueのと、あなたはおそらく、あなたが競合状態に遭遇する可能性があるとして、Vueのは、おそらくいくつかの時点での反応性が欲しい、これらの要素の存在を認識していない場合は、「ネイティブ」な方法可能な限りDOM要素を作成しないようにしたいと思います(あなたのケースでは、時間<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>

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=377689&siteId=1