获取DOM

在Vue3中我们需要使用下面方式获取页面的DOM

<template>
  <div>
    <p>Show Something:</p>
    <input type="text" ref="myRef" />
  </div>
</template>

<script>
import { ref, onMounted } from "vue";
export default {
  name: "App",
  setup() {
    // 定义一个变量名与 DOM中ref名称一样的ref变量,
    const myRef = ref(null);
    onMounted(() => {
      console.log("onMounted:", myRef.value);
    });
    // 导出 该变量
    return { myRef };
  },
};
</script>

可以看到我们在 Mounted 时候就可以获取该DOM

在这里插入图片描述

解决延迟渲染无法获取DOM

但是在某些特殊情况,例如使用v-if等条件语句时,在页面加载时部分组件不会马上渲染,而是在满足条件之后进行渲染,看下面例子:

<template>
  <div>
    <p>Show Something:</p>
    <button @click="handleSwitch">Switch it!</button>
    <input v-if="flag" type="text" ref="myRef1" placeholder="One" />
    <input v-else type="text" ref="myRef2" placeholder="Two" />
  </div>
</template>

<script>
import { ref, onMounted } from "vue";
export default {
  name: "App",
  setup() {
    const flag = ref(true);

    const myRef1 = ref(null);
    const myRef2 = ref(null);
    onMounted(() => {
      console.log("onMounted:", myRef1.value, myRef2.value);
    });

    const handleSwitch = () => {
      flag.value = !flag.value;
      console.log("handleSwitch:", myRef1.value, myRef2.value);
    };
    // 导出 该变量
    return { myRef1, myRef2, handleSwitch, flag };
  },
};
</script>

在页面加载完成之后可以看到,由于flag为true,因此显示了myRef1的输入框。

在这里插入图片描述

onMounted的打印信息来看,myRef1指向了DOM,而myRef2却没有值,这就是因为延迟加载的问题导致。

如果我们点击按钮,可以看到下面状态:

在这里插入图片描述
这里界面上显示的是myRef2的Input框,但是从打印信息来看,myRef2任然为null,即便我们是在打印前重新设置的flag的值,从这里看出到Vue响应式并非实时的,而是存在延迟的

假如我们需要在 DOM 变换了之后 立马就获取到 最新的DOM,那么就需要使用到 nextTick方法

在Vue3中nextTick这个全局函数同样被支持了响应性API,通过import {nextTick} from 'vue' 导入使用。

我们改造handleSwitch方法,在DOM更新完成后立马获取到myRef2的DOM:

<template>
  <div>
    <p>Show Something:</p>
    <button @click="handleSwitch">Switch it!</button>
    <input v-if="flag" type="text" ref="myRef1" placeholder="One" />
    <input v-else type="text" ref="myRef2" placeholder="Two" />
  </div>
</template>

<script>
import { ref, onMounted, nextTick } from "vue";
export default {
  name: "App",
  setup() {
    const flag = ref(true);

    const myRef1 = ref(null);
    const myRef2 = ref(null);
    onMounted(() => {
      console.log("onMounted:", myRef1.value, myRef2.value);
    });

    const handleSwitch = () => {
      flag.value = !flag.value;
      console.log("handleSwitch:", myRef1.value, myRef2.value);
      nextTick(()=>{
          console.log("handleSwitch->nextTick:", myRef1.value, myRef2.value);
      })
    };
    // 导出 该变量
    return { myRef1, myRef2, handleSwitch, flag };
  },
};
</script>

在点击按钮后可以看到下面结果:
在这里插入图片描述

nextTick的回调函数中我们就可以获取到最新的DOM了,实际上nextTick将回调推迟到下一个 DOM 更新周期之后执行,因此我们才可以获取到最新的DOM。

更多细节请参考: https://v3.cn.vuejs.org/api/global-api.html#nexttick

参考文献

[1]. vue3 . 2021 . 全局API nextTick . https://v3.cn.vuejs.org/api/global-api.html#nexttick

Logo

前往低代码交流专区

更多推荐