vue 异步加载远程组件(支持编译less语法)

本代码已组件化,可以直接使用。

说明:本组件可以直接解析.vue文件,为了支持less语法解析,在组件中引入less.js,可在less官网下载。

组件代码

<template>
    <div class="remote">
        <component :is="currentView" v-bind="$props"/> 
    </div>
</template>
<script>
import Axios from 'axios';
import '@/utils/less.min';


export default {
    props:{
        url:{
            type:String,
            default(){
                return null;
            }
        }
    },
    data(){
        return {
            resData:null,
            cssId:null,
        }
    },
    computed:{
        currentView(){
            if(!this.resData)return {template:"<div class='remoteInfo'>正在加载中。。。</div>"};
            const tplData = this.resolveStr(this.resData);
            let ponentObj = new Function(`return ${tplData.sctipts.slice(tplData.sctipts.indexOf('{'),tplData.sctipts.lastIndexOf('}')+1)}`)();
            ponentObj.template = tplData.templates;
            this.$el.setAttribute('class',`remote css${this.cssId}`);
            if(!document.querySelector(`style[id=css${this.cssId}]`)){//防止重复创建
                let cssStr = `
                    .css${this.cssId}{
                        ${tplData.styles}
                    }
                `;
                this.resolveCss(cssStr);
            }
            return ponentObj;
        }
    },
    watch:{
        url(){
            this.getData();
        }
    },
    mounted(){
        this.getData();
    },
    methods:{
        getId() {
            var d = new Date().getTime();
            var uid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                var r = (d + Math.random()*16)%16 | 0;
                d = Math.floor(d/16);
                return (c=='x' ? r : (r&0x3|0x8)).toString(16);
                });
            return uid;
        },
        resolveCss(lessInput){
            less.render(lessInput).then(function(output) {
                let style = document.createElement("style");
                style.setAttribute("type", "text/css");
                style.setAttribute("id",'css' + this.cssId);
                if(style.styleSheet)// IE
                    style.styleSheet.cssText = output.css;
                else {// w3c
                    var cssText = document.createTextNode(output.css);
                    style.appendChild(cssText);
                }
                var heads = document.getElementsByTagName("head");
                if(heads.length)
                    heads[0].appendChild(style);
                else
                    document.documentElement.appendChild(style);
            }.bind(this));
        },
        resolveStr(str){
            return {
                templates:str.match(/<template>([\s\S]*)<\/template>/)[1],
                sctipts:str.match(/<script.*>([\s\S]*)<\/script>/)[1],
                styles:str.match(/<style.*>([\s\S]*)<\/style>/)[1],
            }
        },
        async getData(){
            let remoteData = this.$store.getters.getRemoteByUrl(this.url);
            if(remoteData){
                this.resData = remoteData.resData;
                this.cssId = remoteData.cssId;
            }else{
                const res = await Axios.get(this.$props.url);
                this.cssId = this.getId();
                this.resData = res.data;
                this.$store.dispatch('doAction',{
                    event:'addRemote',
                    data:{url:this.url,cssId:this.cssId,resData:this.resData}
                });
            }        
        }
    }
}
</script>

 

转载于:https://www.cnblogs.com/helloluckworld/p/9858269.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当在Vue中使用异步加载组件时,有时候可能会遇到白屏的问题。这通常是由于异步加载组件的过程中,加载时间过长导致的。以下是一些常见的解决方法: 1. 添加加载状态:在异步加载组件的过程中,可以添加一个加载状态,显示一个loading界面或者加载动画,以提供用户反馈。这可以通过在组件的data中添加一个isLoading的状态来实现,并在加载完成后将其设置为false。 ```javascript data() { return { isLoading: true, // 初始加载状态为true component: null, // 初始化组件为null }; }, mounted() { import('./AsyncComponent.vue') .then((component) => { this.component = component.default; // 导入组件 }) .catch((error) => { console.error('Failed to load component:', error); }) .finally(() => { this.isLoading = false; // 加载完成,loading状态为false }); }, ``` 然后,在模板中根据isLoading状态来显示不同的内容: ```vue <template> <div> <!-- 根据isLoading状态显示不同内容 --> <div v-if="isLoading"> <!-- 显示loading界面或加载动画 --> <Loading /> </div> <div v-else> <!-- 异步加载组件 --> <component :is="component" /> </div> </div> </template> ``` 2. 代码拆分与懒加载Vue支持代码拆分和懒加载,可以将组件按需加载,避免在初始加载时就加载所有组件。可以使用`import()`函数进行动态导入组件。 ```javascript Vue.component('AsyncComponent', () => import('./AsyncComponent.vue')); ``` 这样,组件将会在需要使用时才进行加载,减少了初始加载的资源量。 3. 预加载组件:如果某个组件在初始加载时不会被立即使用,但是会在后续被频繁使用,可以考虑使用Vue提供的`Vue.component`的`preload`函数来预加载组件。这样可以在初始加载时就预先加载组件,避免后续使用时的延迟。 ```javascript Vue.component('AsyncComponent', () => import('./AsyncComponent.vue').then(m => m.default), { preload: true }); ``` 通过以上方法,可以解决异步加载组件导致的白屏问题。希望对您有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值