Vue3的动态组件和异步组价

792 阅读2分钟

今天小编在网上闲逛的时候,发现前端这几年的发展离不开组件的概念,之前小编接触到的组件,基本都是这样的。大家还可以关注我的微信公众号,蜗牛全栈。

const app= Vue.createApp({    
    template: `<input-item />
                <common-item />`
    })
app.component('input-item',{    
    template: `<div> <input /></div>`
})
app.component('common-item',{    
    template: `<div>Hello World</div>`
})
const vm = app.mount("#root")

这个时候页面显示的一个文本框,一行文字 ,这个时候,如果我们想通过一个按钮,来切换两个元素的现实和隐藏关系,就可以把代码修改成这样

const app= Vue.createApp({    
    data(){        
        return {            
            currentItem: 'input-item'        
        }    
    },    
    methods:{        
        handleClick(){            
            if(this.currentItem === 'input-item'){    
                this.currentItem = 'common-item'            
            }else{                
                this.currentItem = 'input-item'            
            }            
            // 也可以通过三目运算符来实现。还可以借鉴绑定class或者style绑定 
            // this.currentItem = this.currentItem === 'input-item'?'common-item':'input-item'        
        }    
    },    
    template: `<input-item v-show="currentItem === 'input-item'" /> 
    <common-item v-show="currentItem === 'common-item'" />    
    <button @click="handleClick">切换</button>        
`})
app.component('input-item',{    
    template: `<div><input /></div>`})
    app.component('common-item',{    
        template: `<div>Hello World</div>`})
const vm = app.mount("#root")

有了动态组件之后,同样的需求,我们的代码就可以写成这样

// 动态组件:根据数据的变化,结合component这个标签,来随时动态切换组件的实现
const app= Vue.createApp({    
    data(){        
        return {            
            currentItem: 'input-item'        
        }    
    },    
    methods:{        
        handleClick(){            
            if(this.currentItem === 'input-item'){    
                this.currentItem = 'common-item'            
            }else{                
                this.currentItem = 'input-item'            
            }        
        }    
    },    
    template: `    
    // 为了缓存文本框之前的数据    
    <keep-alive>        
        <component :is="currentItem" />    
    </keep-alive>    
    <button @click="handleClick">切换</button>`
})
app.component('input-item',{    
    template: `<div><input /></div>`
})
app.component('common-item',{    
    template: `<div>            
        Hello World        
    </div>`
})
const vm = app.mount("#root")

在小编的第一块代码中,都是引入自定义标签的组件之后,就可以直接展示效果,这种成为同步组件 ,当然还有异步组件,主要是为了解决首屏加载速度的问题,借助Vue3中的defineAsyncComponent,就像这样

const app= Vue.createApp({    
    data(){        
        return {            
            count: 1        
        }    
    },    
    mounted(){ 
        // 只有早这个生命周期或者之后,将元素挂载上,才存在DOM的概念        
        console.log(this.$refs.countele)  // <div>1</div>        
        this.$refs.commele.sayHello()    
    },    
    template: `<div @click="count += 1">
                <div ref="countele">{{ count }}</div>            
                <common-item ref='commele' />        
            </div>`
})
app.component('common-item',{    
    methods:{        
        sayHello(){           
            alert('hello')        
        }    
    },    
    template: `<div>Hello World</div>`
})
const vm = app.mount("#root")

二、privide inject:用于组件与子组件的子组件传递数据的方式

我们在通过组件向子组件的子组件传递数据的时候,可以这样

const app= Vue.createApp({    
    data(){        
    return {            
        count: 1       
    }    
},    
template: `<div>
            <child :count="count"/>        
        </div>`
})
app.component('child',{    
    props:['count'],    
    template: `<div>
                <child-child :count="count" />        
            </div>`
})

app.component('child-child',{    
    props:['count'],    
    template: `<div>            
                {{ count }}        
            </div>`
})
const vm = app.mount("#root")

显然,这样很麻烦,通过privide inject,我们可以这么写

const app= Vue.createApp({    
data(){        
    return {            
        count: 1        
    }    
},    
// provide:{ 
// 不能直接调用data中的数据,需要的时候,需要写成函数的方式   
//     count:1    
// },    
// 这种是一次性的,可以通过Vue3的getter方式响应式,通过传统props一层层传递是可以    provide(){        
    return {            
        count: this.count        
    }    
},    
template: `<div>           
    <child />            
        <button @click="count += 1">增加</button>        
    </div>`
})
app.component('child',{    
    template: `<div>            
        <child-child />        
    </div>`
})

app.component('child-child',{    
    inject:['count'],    
    template: `<div>            
                {{ count }}        
            </div>`
})
const vm = app.mount("#root")