面试官:组件库按需注册加载的实现思路是什么?

简介: 【10月更文挑战第6天】面试官:组件库按需注册加载的实现思路是什么?

简介

今天又去面试了,问得都是一些比较基础的问题,也都答了个差不多。但是面试官问我:组件库按需加载是如何实现的时候我卡壳了。平时都是使用组件库,具体按需加载原理我也不知道。

然后面试官给我巴拉巴拉讲了好久,大致就是原理好像就是:通过export导出,按需引入使用啥的

回来后,我搜了搜,注备写个简单的组件库框架,实现一下这个按需导出,模拟常见组件库的使用

项目搭建

image.png

如图,创建了两个组件

link组件select组件,分别在两个组件内写好自己的内容。

select组件:

modules\my-ui\Link\index.vue

<template>
    <div class="my-select">
        <div 
            class="result"
            @click="openOptions"
        >{
   {
    data[curIdx].text }}</div>
        <div class="options">
            <div 
                class="option" v-show="optionsShow"
                v-for="(item, index) in data"
                :key="item.id"
                @click="setOption(index, item)"
            >{
   {
    item.text }}</div>
        </div>
    </div>
</template>
<script>
import {
    reactive, toRefs, ref } from "vue"

export default {
   
    name: 'MySelect',
    props: {
   
        data:Array,
        currentIndex: {
   
            type: Number,
            default: 0
        },
        callback: Function
    },
    setup(props) {
   
        console.log(props.data)
        const state = reactive({
   
            curIdx: props.currentIndex,
            optionsShow: false
        })
        const setOption = (index, item) =>{
   
            state.curIdx = index;
            state.optionsShow = false
            props.callback(index, item)
        }
        const openOptions = () => {
   
            state.optionsShow = true
        }
        return {
   
            ...toRefs(state),
            setOption,
            openOptions
        }
    }
}
</script>
<style>

</style>

link组件:

modules\my-ui\Link\index.vue

<template>
   <a 
    :href="href"
    :target="target"
    :class="['my-link', type]"
   > <slot></slot></a>

</template>
<script>
import {
    reactive, toRefs, ref } from "vue"

export default {
   
    name: 'MyLink',
    props: {
   
        href: String,
        type: String,
        target :String
    }
}
</script> 
<style lang="scss">
    .my-link{
   
        color: #222;
        font-size: 14px;
        text-decoration: none;
        &.primary {
   
            color: blue;
        }
        &.success {
   
            color: green;
        }
    }
</style>

将组件导出

在my-ui文件内的index.js中定义相应逻辑

index.js:

modules\my-ui\index.js

import Select from './Select'  //同import Select from './Select/index.vue' 
import Link from './Link'

const COMPONENTS = [
    Select,Link
]
//按需导出部分,可按需引入
export const MySelect = {
   }
export const MyLink = {
   }
MySelect.install = Vue => Vue.component(Select.name,Select)
MyLink.install = Vue => Vue.component(Link.name,Link)

const MyUI = {
   };
//全部导出部分
MyUI.install = function(Vue) {
   
    COMPONENTS.forEach((component) => {
   
        Vue.component(component.name,component)
    })
} 

export default MyUI

实现原理分析

组件导入

import Select from './Select'; // 同 import Select from './Select/index.vue' 
import Link from './Link';

这两行代码导入了两个组件 Select 和 Link。默认情况下,Vue 文件会解析到 ./Select/index.vue 和 ./Link/index.vue。

组件列表

const COMPONENTS = [
    Select, Link
];

定义了一个包含所有组件的数组 COMPONENTS,用于后续的全局注册。

按需导出部分

export const MySelect = {};
export const MyLink = {};

MySelect.install = Vue => Vue.component(Select.name, Select);
MyLink.install = Vue => Vue.component(Link.name, Link);
    • MySelect 和 MyLink 分别作为 Select 和 Link 组件的按需导出对象。
    • install 方法将组件注册到 Vue 实例中,Vue.component 方法的第一个参数是组件的名称,第二个参数是组件本身。这样可以通过 Vue.use(MySelect) 或 Vue.use(MyLink) 单独引入组件。

全局导出部分

const MyUI = {};

MyUI.install = function(Vue) {
    COMPONENTS.forEach((component) => {
        Vue.component(component.name, component);
    });
};

export default MyUI;
    • MyUI 对象包含一个 install 方法,该方法遍历 COMPONENTS 数组,并将所有组件注册到 Vue 实例中。
    • 通过 Vue.use(MyUI) 可以一次性引入所有组件,实现全局注册。

引入使用

全局注册

import {
    createApp } from 'vue'
import App from './App.vue'
import MyUI from '../modules/my-ui'
createApp(App).use(MyUI).mount('#app')

import {
    createApp } from 'vue'
import App from './App.vue'
import MyUI from '../modules/my-ui'
const app = createApp(App)
app.use(MyUI)
app.mount('#app')

按需引入

import {
    createApp } from 'vue'
import App from './App.vue'
import {
    Select } from '../modules/my-ui'
createApp(App).use(Select).mount('#app')

使用demo

App.vue:

<template>
  <div> 
    <my-Select
      :data = "data"
      :currentIndex = "curIdx"
      :callback = "setOption"
    />
    <My-Link
      href="http://www/baidu.com"
      type="primary"
      target="_blank"
    >百度</My-Link>
    <My-Link
      href="http://www/baidu.com"
      type="success"
      target="_blank"
    >淘宝</My-Link>
  </div>
</template>

<script>
import {
    ref } from "vue";
// import MySelect from '../modules/my-ui/Select/index.vue'
// import MyLink from '../modules/my-ui/Link/index.vue'

export default {
   
  name: 'App',
  components: {
   
    // MySelect,MyLink
  },
  setup()  {
   
    const curIdx = ref(1)
    const data =[
      {
   
        id: 1,
        value: 'orange',
        text: '橘子'
      },
      {
   
        id: 2,
        value: 'apple',
         text: '苹果'
      },
      {
   
        id: 3,
        value: 'per',
        text: '梨'
      }
    ];
    const setOption = (index ,item) =>{
   
      console.log(index,item)
    }
    return{
   
      data,
      curIdx,
      setOption
    }
  }
}
</script>

相关文章
|
5月前
|
JavaScript 前端开发 Java
面试官:你的项目有什么亮点?我:解决了JS脚本加载失败的问题!
面试官:你的项目有什么亮点?我:解决了JS脚本加载失败的问题!
|
Java Spring
【面试题精讲】说一说springboot加载配置文件优先级
【面试题精讲】说一说springboot加载配置文件优先级
|
3月前
|
Java Android开发
Android面试题经典之Glide取消加载以及线程池优化
Glide通过生命周期管理在`onStop`时暂停请求,`onDestroy`时取消请求,减少资源浪费。在`EngineJob`和`DecodeJob`中使用`cancel`方法标记任务并中断数据获取。当网络请求被取消时,`HttpUrlFetcher`的`cancel`方法设置标志,之后的数据获取会返回`null`,中断加载流程。Glide还使用定制的线程池,如AnimationExecutor、diskCacheExecutor、sourceExecutor和newUnlimitedSourceExecutor,其中某些禁止网络访问,并根据CPU核心数动态调整线程数。
103 2
|
3月前
|
前端开发 Java 编译器
Java面试题:描述Java类的加载过程,包括加载、链接、初始化等阶段。
Java面试题:描述Java类的加载过程,包括加载、链接、初始化等阶段。
28 0
|
5月前
|
存储 缓存 前端开发
【面试题】浅谈css加载是否会造成阻塞
【面试题】浅谈css加载是否会造成阻塞
|
12月前
|
存储 Java
【面试题精讲】JVM*类的生命周期*加载阶段
【面试题精讲】JVM*类的生命周期*加载阶段
|
Java 关系型数据库 MySQL
阿里面试官(性能优化):描述一下jvm加载class文件的原理机制?
相信很多人对于性能优化都不陌生,为了获得更好的系统性能,或者是为了满足不断增加的业务需求。 都需要用到我们的性能调优。所以性能优化在面试中出现的频率特别高 楼主自认为自己对性能优化相关知识有很多了解,而且因为最近在找工作面试,所以单独复习了很多关于索引的知识。
|
Java 数据库连接 mybatis
面试官:讲一下Mybatis在SpringBoot中是如何被加载执行的?
本文主要讲述mybatis在springboot中是如何被加载执行的,由于涉及的内容会比较多,所以这次只会对调用关系及关键代码点进行讲解,为了避免文章太长,读起来昏昏欲睡,一些不影响整体流程的细节就不涉及了。
面试官:Java 类加载过程是怎么样的?又被问麻了。。
面试官:Java 类加载过程是怎么样的?又被问麻了。。
100 0
面试官:Java 类加载过程是怎么样的?又被问麻了。。
|
Java C语言
Java面试必问:类加载过程与类加载器
Java面试必问:类加载过程与类加载器
108 0
Java面试必问:类加载过程与类加载器