VUE单文件组件开发
前言
首先需要阐明的是本文单文件开发最终实现的结果:**在 HTML 中通过引入打包后的 js 文件,然后使用组件标签即可渲染。**例如:
1 |
|
为什么没有把 vue 打包到
main.js
中?考虑到一个页面可能会用到多个组件,而多个组件可能并不是使用的一个 js 生成,因此将 VUE 使用 CDN 方式引入。为了避免引入的繁琐,样式文件也没有进行拆分。
快速开始
此部分只包含核心部分,代码可能不可以直接使用。
既然想要把vue
单文件打包成 js 文件,那么核心就是webpack
和vue-loader
。
截至到目前(2021-07-04)为止,vue-loader 最新版本为 16+,但是 16 版本是针对 VUE3 的,而我所要使用的则是 VUE2 版本,因此并不能使用最新版本。因此需要安装的版本依赖如下:
1 | { |
接下来配置 webpack(只列出了核心配置)
1 | // webpack.config.js |
vue-loader15 版本后需要引入一个
VueLoaderPlugin
的 plugin 才可以使用。并且在 15 版本后 vue 中对应的 js 和 css 会分别对应其后缀的文件进行解析。
不出意外此时即可编译出一个 js,将其引入到 HTML 中即可实现。
优化配置
以src
为开发目录进行配置
webpack 配置文件
入口文件
因为我们开发的是单文件组件,因此入口文件可能不止一个(不同类型或用途的组件),因此我们的入口最好是动态获取。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25/**
* @description: 获取入口
*/
const fs = require('fs')
const { parse, resolve } = require('path')
/**
* 传入路径获取入口文件配置
* @date 2021-05-18
* @param {String} path 入口js文件夹
* @returns {Object} 入口配置对象
*/
const getEntry = (path) => {
const files = fs.readdirSync(path)
const entry = {}
files.forEach((item) => {
const { name, ext, base } = parse(resolve(__dirname, path, item))
// 如果ext存在,则认为是入口js文件
if (ext) {
entry[name] = resolve(path, base)
}
})
return entry
}
module.exports = getEntry向外暴露一个函数,参数传入一个路径,该函数会返回入口文件的对象。
loader
由于 loader 包含的类型比较多(sass、scss、stylus 等)因此我会讲他单独提取出来。
1
2
3
4
5
6
7
8
9
10
11
12module.exports = [
require('./stylus'),
require('./less.js'),
require('./sass'),
require('./scss'),
require('./css'),
require('./javascript'),
require('./image'),
require('./font'),
require('./font'),
require('./vue')
]通过一个入口文件,向外暴露一个 loader 的列表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14// stylus示例
const stylus = {
test: /\.styl(us)?$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: { importLoaders: 1 }
},
'postcss-loader',
'stylus-loader'
]
}
module.exports = stylus其他 loader 也是如此配置
plugins
plugins 由于只用到了两个,且不需要过多配置,因此个人认为无需提取。
其他
例如
mode
和devtool
则是根据环境变量和个人需求进行配置。
组件开发
入口文件
这里入口文件暂定为
/src/components
目录下的每一个 js 文件。1
2
3
4
5
6
7
8
9
10
11
12
13
14// 导入头部组件
import head from '../components/head/head.vue'
/**
* 全局filter
*/
import filterInit from '../util/filter'
filterInit(Vue)
Vue.component(head.name, head)
Vue.config.devtools = process.env.NODE_ENV === 'production' ? false : true
window.Vue = Vue
问题
vue-loader
版本问题vue-loader
版本 16 只支持 vue3,因此如果使用 vue2 则需要使用 15.x 版本.组件库
例如
elementui
组件库1
2import { Button } from 'element-ui'
Vue.component(Button.name, Button)