Vue非同步元件Demo

嘵嘵發表於2017-12-24

Vue非同步元件Demo

在大型應用中,我們可能需要將應用拆分為多個小模組,按需從伺服器下載。為了進一步簡化,Vue.js 允許將元件定義為一個工廠函式,非同步地解析元件的定義。Vue.js 只在元件需要渲染時觸發工廠函式,並且把結果快取起來,用於後面的再次渲染。

下面是我寫的一個簡單Vue非同步元件Demo。

index.html

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
            content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible"
            content="ie=edge">
        <title>Document</title>
        <script>
            // 如果瀏覽器不支援Promise就載入promise-polyfill
            if ( typeof Promise === `undefined` ) {
                var script = document.createElement( `script` );
                script.type = `text/javascript`;
                script.src = `https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js`;
                document.head.appendChild( script );
            }
        </script>
        <!-- 引入Vue -->
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    </head>

    <body>
        <div id="app" style="font-size: 22px">
            <!-- 非同步元件async-comp -->
            <async-comp :list="[`我是一個非同步元件,`,`如果載入完成,`,`我就會在這裡顯示`]"></async-comp>
        </div>

        <!-- 引入main.js     -->
        <script src="/main.js"></script>
    </body>

</html>

非同步元件Async-Comp.js,

  • 注意,Async-Comp.js並沒有在index.html中引用,而是在下面的main.js中動態載入。
window.async_comp = {
    template: `
        <ol>
            <li v-for="item in list">{{ item }}</li>
        </ol>`,
    props: {
        list: Array
    }
};

main.js

var vm = new Vue( {
    el: `#app`,
    components: {
        /* 非同步元件async-comp */
        `async-comp`: function () {
            return {
                /** 要渲染的非同步元件,必須是一個Promise物件 */
                component: new Promise( function ( resolve, reject ) {
                    var script = document.createElement( `script` );
                    script.type = `text/javascript`;
                    script.src = `/Async-Comp.js`;
                    document.head.appendChild( script );

                    script.onerror = function () {
                        reject( `load failed!` );
                    }

                    script.onload = function () {
                        if ( typeof async_comp !== `undefined` )
                            resolve( async_comp );
                        else reject( `load failed!` )
                    }
                } ),
                /* 載入過程中顯示的元件 */
                loading: {
                    template: `<p>loading...</p>`
                },
                /* 出現錯誤時顯示的元件  */
                error: {
                    template: `
                        <p style="color:red;">load failed!</p>
                    `
                },
                /* loading元件的延遲時間 */
                delay: 10,
                /* 最長等待時間,如果超過此時間,將顯示error元件。 */
                timeout:3200
            }
        }
    }
} )

see github

相關文章