开发者问题收集

Vue 3 Composition API...如何替换 getElementById

2021-05-27
25065

我在 Vue 3 Composition API 中写了以下内容。

如果您查看“onMounted”,我会将事件侦听器附加到窗口,以将状态框保持在屏幕底部。我使用的是绝对位置和底部 0。

我想知道我是否可以通过替换 getElementById 使其更“Vue”?我尝试了 refs,但它不起作用。

有什么建议吗?还是我应该保持原样?

谢谢

<template>
  <div>
    <transition name="toast">
      <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)"><span class="-x10-cross"></span></div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, computed, watch, onMounted } from "vue";
  import { useStore } from "../model/DataStore";
  export default defineComponent({ 
    setup() {
    const store = useStore();

    const statuses = ref([]);

    const statusMessage = computed(() => store.state.statusMessage);
    function  addStatus(newMessage) {

          statuses.value.push({
            id: statuses.value.length + 1,
            text: newMessage
          })
        }

      watch(statusMessage, (newValue: string, oldValue: string) => {
        addStatus(statusMessage.value);
      })

      onMounted(() => {
          window.addEventListener("scroll", function (e) {
                let vertical_position = 0;
                vertical_position = pageYOffset;

                if(document.getElementById("slide")){
                  document.getElementById('slide').style.bottom = -(vertical_position) + 'px';
                }
          });
      })

    return {
      store,
      statuses,
      addStatus
    };
  },
  methods: {
        clearAllNotifications() {
          this.statuses = []
        },

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

这是幻灯片模式样式:

.slide-modal {
        max-height: 200px;
        width: 500px;
        background-color: #f2f2f2;
        color: #505050;
        padding: 8px;
        display: flex;
        flex-direction: column;
        gap: 8px;
        overflow-x: hidden;
        position: absolute;
        bottom: 0;
    }
1个回答

文档 提供了一个非常简单的示例

<template>
  <div ref="root">This is a root element</div>
</template>

<script>
  import { ref, onMounted } from 'vue'

  export default {
    setup() {
      const root = ref(null)

      onMounted(() => {
        // the DOM element will be assigned to the ref after initial render
        console.log(root.value) // <div>This is a root element</div>
      })

      return {
        root
      }
    }
  }
</script>
  • 创建时使用 ref()
  • 在返回函数中传递给模板
  • 在模板中使用 ref="..."
  • onMounted 中,通过 ref.value 访问

因此对于您的代码来说,它将是...

<template>
  <div>
    <transition name="toast">
      <div ref="slideRef" 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)"><span class="-x10-cross"></span></div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, computed, watch, onMounted } from "vue";
  import { useStore } from "../model/DataStore";
  export default defineComponent({ 
    setup() {
    const store = useStore();

    const statuses = ref([]);
    const slideRef = ref();

    const statusMessage = computed(() => store.state.statusMessage);
    function  addStatus(newMessage) {
          statuses.value.push({
            id: statuses.value.length + 1,
            text: newMessage
          })
        }

      watch(statusMessage, (newValue: string, oldValue: string) => {
        addStatus(statusMessage.value);
      })

      onMounted(() => {
          window.addEventListener("scroll", function (e) {
                let vertical_position = 0;
                vertical_position = pageYOffset;

                if(slideRef.value){
                  slideRef.value.style.bottom = -(vertical_position) + 'px';
                }
          });
      })

    return {
      store,
      statuses,
      addStatus,
      slideRef 
    };
  },
  })
</script>
Daniel
2021-05-27