首页 > 解决方案 > 如何在 Vue 3 中使用“this”

问题描述

我正在开发 Vue3/TypeScript 中的一个组件。我对 Vue 比较陌生。

我正在动态创建一个 div。我希望能够在用户单击“x”按钮时将其删除。这是“closeStatus”方法。

在 JavaScript 中我可以通过它,但 Vue 讨厌它。

如果有人可以提供帮助。

谢谢。

这是代码:

<template>
    <div>
        <button @click="addStatus()" >Add Status</button>

        <div id="slide" class="slide-modal">
            <div class="clear-notifications" @click='clearAllNotifications()'>Clear all notifications</div>

            <div class="status-div">
                <div>11:00 Booking requested</div>
                <div @click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
            </div>

            <div class="status-div">
                <div>11:30 Booking requested</div>
                <div @click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
            </div>

        </div>
    </div>
</template>

<script lang="ts">
    export default {
        name: 'SlideModal',
        methods: {
            clearAllNotifications() {
                const allNotifications = document.querySelectorAll(".status-div");
                for(let x=0;x<allNotifications.length;x++) {
                    allNotifications[x].remove(); //removes all the child elements.
                }
                document.getElementById('slide').style.visibility='hidden'; //This should be Vue reactive.
            },

            addStatus() {
                document.getElementById('slide').style.visibility='visible'; //This should be Vue reactive.
                const statusMessage = "Another Message"
                var div = document.createElement('div');
                div.setAttribute('class', 'status-div');
                div.innerHTML = '<div>' + statusMessage + '</div><div onclick="closeStatus(this)"><img src="/src/assets/cross.svg" /></div>'
                document.getElementById('slide').appendChild(div);
            },

            closeStatus(elm: any) {
                elm.parentNode.remove();
                const allNotifications = document.querySelectorAll(".status-div");
                if(allNotifications.length == 0 ) {
                    document.getElementById('slide').style.visibility='hidden'; //This should be Vue reactive.
                }
            }
        }
    }
</script>

标签: vue.jsvue-componentvuejs3

解决方案


代码是 javascript DOM 管理的东西,与 Vue 风格相去甚远。Vue 使用变量管理 DOM,这就是 javascript 框架很棒的原因。先分享一下修改后的代码。

<template>
  <div>
    <button @click="addStatus()" >Add Status</button>

    <div id="slide" class="slide-modal" v-show="visibleSlide">
      <div class="clear-notifications" @click='clearAllNotifications()'>Clear all notifications</div>
      <div class="status-div">
        <div>11:00 Booking requested</div>
        <div @click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
      </div>

      <div class="status-div">
        <div>11:30 Booking requested</div>
        <div @click="closeStatus(this)"><img src="../assets/cross.svg" /></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
  export default {
    name: 'SlideModal',
    data() {
      return {
        visibleSlide: true
      }
    },
    methods: {
      clearAllNotifications() {
        const allNotifications = document.querySelectorAll(".status-div");
        for(let x = 0; x < allNotifications.length; x++) {
          allNotifications[x].remove(); //removes all the child elements.
        }

        this.visibleSlide = false
      },

      addStatus() {
        this.visibleSlide = true;

        const statusMessage = "Another Message";
        var div = document.createElement('div');
        div.setAttribute('class', 'status-div');
        div.innerHTML = '<div>' + statusMessage + '</div><div onclick="closeStatus(this)"><img src="/src/assets/cross.svg" /></div>'
        document.getElementById('slide').appendChild(div);
      },

      closeStatus(elm: any) {
        elm.parentNode.remove();
        const allNotifications = document.querySelectorAll(".status-div");
        if(allNotifications.length == 0 ) {
          this.visibleSlide = false
        }
      }
    }
  }
</script>

我刚刚更新了评论:“//这应该是 Vue 反应式的。”

但它仍然没有从 Vue 框架中受益。这是我对 Vue 代码的全部想法

<template>
  <div>
    <button @click="addStatus()" >Add Status</button>
    <div id="slide" class="slide-modal" v-if="statuses.length">
      <div class="clear-notifications" @click='clearAllNotifications()'>Clear all notifications</div>
      <div v-for="status in statuses" :key="status.id" class="status-div">
        <div>{{ status.text }}</div>
        <div @click="closeStatus(status)"><img src="../assets/cross.svg" /></div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
  export default {
    name: 'SlideModal',
    data() {
      return {
        statuses: [
          {
             id: 1,
             text: '11:00 Booking requested'
           }, {
              id: 2,
              text: '11:30 Booking requested'
           }
        ]
      }
    },
    methods: {
      clearAllNotifications() {
        this.statuses = []
      },

      addStatus() {
        const statusMessage = "Another Message";
            
        this.statuses.push({
          id: this.statuses.length + 1,
          text: statusMessage
        })
      },

      closeStatus(elm: any) {
        const index = this.statuses.map((status) => status.id).indexOf(elm.id);
        this.statuses.splice(index, 1);
      }
    }
  }
</script>

如您所见,DOM 元素由变量及其操作管理,而不是 DOM 管理方法。

希望这会有所帮助


推荐阅读