<template>
  <div>
    <button v-loading='loading' @click='loadData'>Load Data</button>
    <div v-if='loading' class='loading-overlay'>
      <div class='loading-spinner'></div>
    </div>
    <div v-else class='data-container'>
      <!-- data goes here -->
    </div>
  </div>
</template>
<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    const loading = ref(false);

    const loadData = () => {
      loading.value = true;

      // simulate loading data from API
      setTimeout(() => {
        loading.value = false;
      }, 2000);
    };

    return {
      loading,
      loadData,
    };
  },
  directives: {
    loading: {
      mounted(el, binding) {
        const spinner = document.createElement('div');
        spinner.classList.add('loading-spinner');

        const overlay = document.createElement('div');
        overlay.classList.add('loading-overlay');
        overlay.appendChild(spinner);

        el.appendChild(overlay);

        watch(
          () => binding.value,
          (value) => {
            if (value) {
              overlay.style.display = 'block';
            } else {
              overlay.style.display = 'none';
            }
          }
        );
      },
    },
  },
};
</script>
<style>
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.5);
  display: none;
  z-index: 999;
}

.loading-spinner {
  border-radius: 50%;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #3498db;
  width: 20px;
  height: 20px;
  animation: spin 1s linear infinite;
  margin: auto;
  margin-top: calc(50% - 10px);
}

.data-container {
  /* styling for data container */
}
</style>
<p>在这个示例代码中,我们首先定义了一个 <code>loading</code> 变量,它是一个响应式的引用。我们使用 <code>ref</code> 函数来创建这个引用,并将其初始值设置为 <code>false</code>。我们还定义了一个 <code>loadData</code> 函数,它模拟了从 API 加载数据的过程,并在加载完成后将 <code>loading</code> 变量设置为 <code>false</code>。</p>
<p>在模板中,我们使用一个 <code>v-loading</code> 指令来实现 loading 效果。这个指令接受一个绑定值,即 <code>loading</code> 变量。当 <code>loading</code> 变量为 <code>true</code> 时,我们显示一个 loading 覆盖层,其中包含一个 loading 动画。当 <code>loading</code> 变量为 <code>false</code> 时,我们隐藏 loading 覆盖层,并显示数据容器。</p>
<p>在指令定义中,我们使用 <code>mounted</code> 钩子函数来初始化 loading 覆盖层。我们创建一个 loading 动画元素和一个覆盖层元素,并将它们添加到目标元素中。然后,我们使用 <code>watch</code> 函数来监听绑定值的变化,并在变化时显示或隐藏 loading 覆盖层。</p>
<p>最后,我们还添加了一些样式来定义 loading 覆盖层和 loading 动画的外观。在这个示例中,我们使用了一个简单的旋转动画来表示 loading。您可以根据需要自定义这些样式。</p>
Vue3 自定义指令实现 Loading 效果

原文地址: https://www.cveoy.top/t/topic/n397 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录