在子文件夹中的 Vuejs 中全局注册组件

Posted

技术标签:

【中文标题】在子文件夹中的 Vuejs 中全局注册组件【英文标题】:Registering components globally in Vuejs in subfolders 【发布时间】:2019-05-09 15:37:57 【问题描述】:

我已经按照 Vuejs 网站上的文档学习了如何在全局范围内注册 vue 组件。

我已定义组件文件夹的相对路径为./global,并设置为在子文件夹中查找true(默认为false)。但是,它仍然不会查看子文件夹。

我还控制台记录了组件键以查看是否包含任何 vue 组件,但它仅返回全局(根)文件夹中的组件。

https://vuejs.org/v2/guide/components-registration.html

import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'

const requireComponent = require.context(
  // The relative path of the components folder
  './global',
  // Whether or not to look in subfolders
  true,
  // The regular expression used to match base component filenames
  /[A-Z]\w+\.(vue|js)$/
)

console.log(requireComponent.keys())

requireComponent.keys().forEach(fileName => 
  // Get component config
  const componentConfig = requireComponent(fileName)

  // Get PascalCase name of component
  const componentName = upperFirst(
    camelCase(
      // Strip the leading `./` and extension from the filename
      fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    )
  )

  // Register component globally
  Vue.component(
    componentName,
    // Look for the component options on `.default`, which will
    // exist if the component was exported with `export default`,
    // otherwise fall back to module's root.
    componentConfig.default || componentConfig
  )
)

【问题讨论】:

子目录下的组件文件命名是否正确?它们应该以大写字母开头。 【参考方案1】:

@Anson C

const requireComponent = require.context(
  // The relative path of the components folder
  './global',
  // Whether or not to look in subfolders
  true,
  // The regular expression used to match base component filenames
  /[A-Z]\w+\.(vue|js)$/
)

此代码完全按预期工作。意味着它将按预期返回子文件夹中的所有文件(如./Base/BaseInput.vue 将返回BaseInput)。但是要导入这些文件,您还必须添加相应的路径。

// Get PascalCase name of component
  const componentName = upperFirst(
    camelCase(
      // Strip the leading `./` and extension from the filename
      fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    )
  )

这只会导入./BaseInput,这不是准确的路径,应该是./Base/BaseInput

为了:

// Get PascalCase name of component
  const componentName = Vue._.upperFirst(
    Vue._.camelCase(
      fileName
        .split('/')
        .pop()
        .replace(/\.\w+$/, '')
    )
  )

此代码返回文件和文件夹的完美路径。

【讨论】:

【参考方案2】:

为了达到同样的效果,我最终写了以下内容:

const requireComponent = require.context(
  // The relative path of the components folder
  './global',
  // Whether or not to look in subfolders
  true,
  // The regular expression used to match base component filenames
  /[A-Z]\w+\.(vue|js)$/
)

requireComponent.keys().forEach(fileName => 
  // Get component config
  const componentConfig = requireComponent(fileName)
  // Get PascalCase name of component
  const componentName = Vue._.upperFirst(
    Vue._.camelCase(
      fileName
        .split('/')
        .pop()
        .replace(/\.\w+$/, '')
    )
  )

  // Register component globally
  Vue.component(
    componentName,
    // Look for the component options on `.default`, which will
    // exist if the component was exported with `export default`,
    // otherwise fall back to module's root.
    componentConfig.default || componentConfig
  )
)

确保全局中的所有文件都是大写的,并且具有 .vue 或 .js 扩展名。

还使用您提供的路径确保 main.js(或任何您的引导文件被调用)位于全局目录中的一个目录中。示例:

/src main.js /全局

这将使诸如 ProgressBar.vue 之类的文件作为 ProgressBar 在您的所有组件中全局可用

<ProgressBar></ProgressBar>

【讨论】:

谢谢!为什么文档中提供的那个不起作用?当我将“在子文件夹中查看”变量更改为 true 时,它​​应该默认工作,不是吗? 我也很困惑为什么提供的文档不起作用。这似乎应该内置到子文件夹遍历逻辑中...... 我将提交一个提交到 VueJS 文档仓库以供考虑。

以上是关于在子文件夹中的 Vuejs 中全局注册组件的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs 中的动态导入

VueJS:在子组件中触发事件时在父组件中运行函数

Vuejs组件

VueJS 组件注册

Vuejs爬坑记

如何使用道具 vuejs 在子组件中打开和关闭模式?