彻底搞懂vue的use

127 阅读3分钟

使用场景:

如果希望在所有的页面都要用某组件,那么就要在main.js全局注册组件

import SButton from '@/components/s-button.vue'
app.component('SButton', SButton)

但是, 如果有很多个组件, 都要全局注册, 那么又会在main.js 中写很多内容

思考: 我们能在所有组件中, 使用 element-ui 的组件, 他是让我们一个个去全局注册的嘛 ? (它让我们 Vue.use 一下即可)

目标: 利用 Vue.use 统一全局注册组件

Vue2文档: cn.vuejs.org/v2/api/#Vue…

Vue3文档: v3.cn.vuejs.org/api/applica…

说明:

  1. Vue.use 可以接收一个对象, Vue.use(obj)

  2. 对象中需要提供一个 install 函数

    // 扩展vue原有的功能:全局组件,自定义指令,挂载原型方法,注意:没有全局过滤器。
    // 这就是插件
    // vue2.0插件写法要素:导出一个对象,有install函数,默认传入了Vue构造函数,Vue基础之上扩展
    // vue3.0插件写法要素:导出一个对象,有install函数,默认传入了app应用实例,app基础之上扩展import SButton from './SButton.vue'export default {
      install (app) {
        // 在app上进行扩展,app提供 component directive 函数
        // 如果要挂载原型 app.config.globalProperties 方式
        app.component(SButton.name, SButton)
      }
    }
    
  3. install 函数可以拿到参数 Vue, 且将来会在 Vue.use 时, 自动调用该 install 函数

例子:

封装组件SButtonSInput

目的:完成两个组件的封装

大致步骤:

  • src/components/下面封装SButtonSInput两个组件
  • App.vue中使用
  1. 封装组件:src/components/SButton.vue
<template>
  <button>点我</button>
</template>
<script>
export default {
  name: 'SButton'
}
</script>
  1. 封装组件:src/components/SInput.vue
<template>
  <input type="text">
</template>
<script>
export default {
  name: 'SInput'
}
</script>
  1. mian.js中全局引入
import { createApp } from 'vue'
import App from './App.vue'import SButton from '@/components/SButton'
import SInput from '@/components/SInput'const app = createApp(App)
app.component('SButton', SButton)
app.component('SInput', SInput)
app.mount('#app')
  1. App.vue中使用
<template>
  <h1>vue-use</h1>
  <s-button></s-button>
  <s-input></s-input>
</template><script>
export default {
  name: 'App'
}
</script>
  1. 但是, 如果有很多个组件, 都要全局注册, 那么又会在main.js 中写很多内容,所以引出use

提供统一注册的入口文件

提供统一注册的入口文件 src/componets/index.js

入口文件导出一个对象,对象中要有一个install函数,app.use 的时候会自动执行install函数

import SButton from './SButton.vue'
import SInput from './SInput.vue'export default {
  install (app) {
    app.component(SButton.name, SButton)
    app.component(SInput.name, SInput)
  }
}

修改main.js文件

import { createApp } from 'vue'
import App from './App.vue'
​
// import SButton from '@/components/SButton'
// import SInput from '@/components/SInput'
+ import SLUI from '@/components'
​
const app = createApp(App)
+ app.use(SLUI)
// app.component(SButton.name, SButton)
// app.component(SInput.name, SInput)
app.mount('#app')

这里如果有很多也是要一个个引入,下面讲解一个更好的方法

顶级类目-批量注册组件

自动的批量注册组件。

大致步骤:

  • 使用 require 提供的函数 context 加载某一个目录下的所有 .vue 后缀的文件。

  • 然后context函数会返回一个导入函数importFn

    • 它又一个属性 keys() 获取所有的文件路径
  • 通过文件路径数组,通过遍历数组,再使用 importFn 根据路径导入组件对象

  • 遍历的同时进行全局注册即可

代码:src/components/index.js

// import SButton from './SButton.vue'
// import SInput from './SInput.vue'export default {
  install (app) {
    // require.context有三个参数
    // - 参数1:加载的文件目录
    // - 参数2:是否加载子目录
    // - 参数3:正则,匹配文件
    const importFn = require.context('./', false, /.vue$/)
    importFn.keys().forEach(key => {
      const component = importFn(key).default
      app.component(component.name, component)
    })
    // app.component(SButton.name, SButton)
    // app.component(SInput.name, SInput)
  }
}

总结

  • 参数1:加载的文件目录

  • 参数2:是否加载子目录

  • 参数3:正则,匹配文件

  • 返回值:导入函数 fn

    • keys() 获取读取到的所有文件列表