最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue defineAsyncComponent Api 这些知识学习起来~~

    正文概述 掘金(前端小智)   2021-07-23   604

    使用 Vue3 的 DefileAsyncComponent功能可让我们懒加载组件,说白了就是创建一个只有在需要时才会加载的异步组件。

    这是改进初始页面加载的好方法,因为我们的应用程序将加载到较小的块中而不是必须在页面加载时加载每个组件。

    Vue defineAsyncComponent Api 这些知识学习起来~~

    在本文中,我们将学习有关defineAsyncComponent的所有知识,并学习一个懒加载弹出窗口的例子。

    Vue defineAsyncComponent Api 这些知识学习起来~~

    defineAsyncComponent 是啥?

    const AsyncComp = defineAsyncComponent(
      () =>
        new Promise((resolve, reject) => {
          resolve({
            template: '<div>I am async!</div>'
          })
        })
    )
    

    defineAsyncComponent 可以接受一个返回 Promise 的工厂函数。Promise 的 resolve 回调应该在服务端返回组件定义后被调用。你也可以调用 reject(reason) 来表示加载失败。

    defineAsyncComponent 可以从 vue 中导入,并使用:

    import { defineAsyncComponent } from "vue" 
    
    // simple usage 
    const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
    

    这是defineAsyncComponent的最简单方法,对于高阶用法,defineAsyncComponent 可以接受一个对象:

    const AsyncPopup = defineAsyncComponent({ 
      loader: () => import("./LoginPopup.vue"),
       // 加载异步组件时要使用的组件
      loadingComponent: LoadingComponent,
       // 加载失败时要使用的组件
      errorComponent: ErrorComponent, 
      // 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
      delay: 1000, 
      // 如果提供了 timeout ,并且加载组件的时间超过了设定值,将显示错误组件
      // 默认值:Infinity(即永不超时,单位 ms)
      timeout: 3000 
    })
    

    基础已经介绍完了,接着,我们来做个例子。

    使用 defineAsyncComponent 异步加载 Popup 组件

    在这个例子中,我们将使用一个由点击按钮触发的登录弹框。

    我们不需要我们的应用程序在每次加载时都加载这个组件,因为只有在用户执行特定的动作时才需要它。

    下面是 login 组件的实现:

    // LoginPopup.vue
    <template>
       <div class="popup">
           <div class="content">
               <h4> Login to your account </h4>
               <input type="text" placeholder="Email" />
               <input type="password" placeholder="Password" />
               <button> Log in </button>
           </div>
       </div>
    </template>
    
    <script>
    </script>
    
    <style scoped>
    .popup {
        position: fixed;
        width: 100%;
        top: ; 
        left: ;
        height: 100%;
        background-color: rgba(, , , 0.2);
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .content {
       min-width: 200px;
       width: 30%;
       background: #fff;
       height: 200px;
       padding: 10px;
       border-radius: 5px;
    }
    input[type="text"], input[type="password"] {
        border: ;
        outline: ;
        border-bottom: 1px solid #eee;
        width: 80%;
        margin:  auto;
        font-size: 0.5em;
    }
    button {
       border: ;
       margin-top: 50px;
       background-color:#8e44ad;
       color: #fff;
       padding: 5px 10px;
       font-size: 0.5em;
    }
    </style>
    

    Vue defineAsyncComponent Api 这些知识学习起来~~

    在其它组件中导入它:

    <template>
      <button @click="show = true"> Login </button>
      <login-popup v-if="show" />
    </template>
    
    <script>
    import LoginPopup from './components/LoginPopup.vue'
    export default {
      components: { LoginPopup },
      data() {
        return {
          show: false
        }
      }
    }
    </script>
    

    我们可以使用 defineAsyncComponent,只在需要的时候加载它(按钮被点击时使用v-if来切换)。

    <!-- Use defineAsyncComponent  -->
    <template>
      <button @click="show = true"> Login </button>
      <login-popup v-if="show" />
    </template>
    
    <script>
    import { defineAsyncComponent } from 'vue'
    export default {
      components: { 
        "LoginPopup" : defineAsyncComponent(() => import('./components/LoginPopup.vue'))
      },
      data() {
        return {
          show: false
        }
      }
    }
    </script>
    

    这个用法看起来和上面的差不多,不急,我们 F12 打开控制台。

    如果我们不使用defineAsyncComponent,一旦我们的页面加载,我们就会看到我们的应用程序从服务器上获得LoginPopup.vue。虽然在这个例子中,性能问题不那么严重,但如果我们有几十个组件这样做,性能上多多少少还是有影响的。

    Vue defineAsyncComponent Api 这些知识学习起来~~

    然而,如果我们使用defineAsyncComponent查看同一个标签,会注意到,当我们的页面加载时,LoginPopup.vue是没有的,这是因为它还没有被加载。

    Vue defineAsyncComponent Api 这些知识学习起来~~

    但,如果切换按钮,我们就可以看到它了:

    Vue defineAsyncComponent Api 这些知识学习起来~~

    这有助于我们实现最佳性能。我们只想在我们的页面初始加载时加载需要的组件。有条件渲染的组件在我们的页面加载时往往是不需要的,所以为什么要让我们的应用程序加载它们呢?

    如何与异步的 setup 方法一起使用?

    不管我们是否用defineAsyncComponent来异步加载,任何具有异步 setup 方法的组件都必须用<Suspense>来包装。

    简而言之,创建一个异步 setup 函数是我们的一种选择,可以让我们的组件在渲染前等待一些API 调用或其他异步操作。

    下面是带有异步setup的组件,使用setTimeout()模拟API调用

    <template>
       <div class="popup">
           <div class="content">
                <p> Loaded API: {{ article }} </p>
               <h4> Login to your account </h4>
               <input type="text" placeholder="Email" />
               <input type="password" placeholder="Password" />
               <button> Log in </button>
           </div>
       </div>
    </template>
    
    <script>
    const getArticleInfo = async () => {
         // wait 3 seconds to mimic API call
        await new Promise(resolve => setTimeout(resolve, 1000));
        const article = {
            title: 'My Vue 3 Article',
            author: 'Matt Maribojoc'
        }
        return article
    }
    export default {
        async setup() {
            const article = await getArticleInfo()
            console.log(article)
            return {
                article
            }
        }
    }
    </script>
    

    我们可以使用或不使用defineAsyncComponent将它导入到组件中:

    import LoginPopup from './components/LoginPopup.vue'
    
    // OR 
    
    const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
    

    但如果我们想让它在我们的模板中渲染,我们需要把它包在一个Suspense元素中。这将等待我们的setup 解析后,然后再尝试渲染我们的组件。

    Suspense的一个很好的特点是,我们可以使用槽和模板显示回退内容。回退内容将显示,直到setup函数解析,我们的组件准备好渲染。 请注意,v-if已经从组件本身移到了我们的Suspense 组件上,所以所有回退内容都会显示。

    <template>
      <button @click="show = true"> Login </button>
      <Suspense v-if="show">
        <template #default>
          <login-popup  />
        </template>
        <template #fallback>
          <p> Loading... </p>
        </template>
      </Suspense>
    </template>
    

    下面是运行结果,会看到 "Loading…",然后在3秒后(setTimeout的硬编码值)组件渲染。

    Vue defineAsyncComponent Api 这些知识学习起来~~

    默认情况下,我们使用defineAsyncComponent定义的所有组件都是可Suspense的。

    这意味着如果一个组件的父链中有Suspense,它将被视为该Suspense的一个异步依赖。我们的组件的加载、错误、延迟和超时选项将被忽略,而是由Suspense来处理。

    总结

    当构建包许多组件的大型项目时,defineAsyncComponent是非常有用的。当我们使用懒加载组件时,可以更快地加载页面,改善用户体验,最终提高应用的留存率和转换率。

    我很想知道大家对这个特性的看法。如果你已经在你的应用中使用它了,记得下面留言分享一下哦。

    完,我是小智,今天准备去干点啥~


    代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

    原文:learnvue.co/2021/06/laz…

    交流


    起源地下载网 » Vue defineAsyncComponent Api 这些知识学习起来~~

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元