如何在 Nuxt.js 项目中引入 vant 并修改主题


vant 是由有赞前端团队维护的一个轻量、可靠的移动端 Vue 组件库,在 github 上有 13.8k 的 star,在项目中引入它,可以快速搭建页面,实现功能开发。但是在官方文档中,只提供了普通 vue 项目中的引入方式,而没有提供在 nuxt.js 项目中的用法,所以本文特此记录一下。

在 nuxt.js 项目中,不管是引入 vant,element-ui 等 UI 框架,还是 vConsole 之类,都应该把它当做一个插件来用,所以套路其实都是一样的。首先在依赖中安装 vant,在项目根目录的命令行中,使用 npm install vantyarn add vant。另外,后面为了解析 less 样式文件,也要用到 lessless-loader 两个依赖,也可以提前安装一下,使用 npm install less less-loader@5.0.0yarn add less less-loader@5.0.0(less-loader 的版本后面会讲到)。vant 的使用分为全量引用和按需引用,如果你的项目比较完善,完全依赖于 vant 来构建页面结构,那么就可以全量引入,如果你的项目比较简单,只是用到了 vant 里面的个别控件,那么可以按需引入,只引入自己用到的控件,按需引用可以减小项目打包的体积。

首先在项目的 plugins 目录下新建一个文件 vant-ui.js,按下面的方式写,就是全量引用。

import Vue from 'vue'
import Vant from 'vant'
Vue.use(Vant)

如果你想按需引用,可以按下面这样写,这里以 Tab 和 Tabs 为例。

import Vue from 'vue'
import { Tab, Tabs } from 'vant'
Vue.use(Tab)
Vue.use(Tabs)

创建完插件之后,就应该到 nuxt.config.js 文件中去使用这个插件。这个文件是导出了一个对象,在对象中有一个字段叫 plugins,取值为数组类型,可以在里面添加之前已经创建好的很多插件来用。这里就按照下面的方式加入 vant-ui。

module.exports = {
plugins: [{src: '@/plugins/vant-ui', ssr: true}]
}

然后,你运行项目,就会发现其实 vant 的控件已经可以使用了,只是没有样式而已。引用样式要根据你 vant 控件是全量引用还是按需引用,使用不同的方式。
如果你是全量引用,那么你也要全量引用所有的样式。有两种方法,第一种是在 nuxt.config.js 文件中,有一个 css 字段,取值为数组类型,专门用来引用所有用到的样式,包括第三方和自己项目的,推荐使用这种方式。

module.exports = {
css: ['vant/lib/index.less']
}

第二种是在 vant-ui.js 文件中,直接导入 vant 的样式。

import Vue from 'vue'
import Vant from 'vant'
import 'vant/lib/index.less'
Vue.use(Vant)

这时,全量引用的方式就已经完成了,运行项目,就可以看到 vant 的控件和样式都可以正常使用了。

而如果你是按需引用,那么你还需要安装一个依赖 babel-plugin-import,用来引入已经引入的控件的样式,毕竟如果你的控件是按需引用,而样式是全量引用,也是没有必要的。在 nuxt.config.js 文件中,有一个字段叫做 build,取值为对象类型,用来扩展一些 webpack 的配置。按照下面这样写,就可以自动引入那些你引入的 vant 控件对应的样式。

module.exports = {
build: {
transpile: [/vant.*?less/],
babel: {
plugins: [
[
'import',
{
libraryName: 'vant',
style: (name) => {
return `${name}/style/less.js`
}
},
'vant'
]
]
}
}
}

这时,按需引用的方式就已经完成了,运行项目,就可以看到按需引入的 vant 控件和对应的样式都可以正常使用了。

当然,因为 vant 是有赞前端团队开发的,所以很多样式都是以他们的项目为主的,比如说主题色是红色,色值为 #ee0a24。如果你想修改默认的样式,也是可以的。比如我想修改默认的主题色为 #ff5722,让 tabs 控件下面的指示器的颜色也是这个,那我就得先找我要改的变量是哪一个,然后进行覆盖。


在自己的页面上添加一个 van-tabs,然后通过定位,发现 tabs 底下的指示器的 class 为 van-tabs__line,背景颜色为 #ee0a24。然后就需要到 vant 的源码里面去找变量了。可能有些人一听到源码,就怕了,其实很简单。因为你已经安装了 vant 依赖,所以 vant 的源码在项目的 node_modules 文件夹中。打开 node_modules/vant/lib/tabs/index.less,会发现有很多 css 样式。然后往下找,发现有一个 &__line,它是在 .van-tabs 里面的,所以这个样式就是作用于 class 为 van-tabs__line 的组件的。里面有一个 background-color,就是我们要修改的样式。然后发现取值为一个变量 @tabs-bottom-bar-color,那么现在再去找这个变量。在这个 index.less 文件的最上面,有一个 @import '../style/var';,表示从这个文件中导入了很多变量。打开这个文件(style 文件夹跟 tabs 文件夹同级,都在 lib 文件夹里面),发现定义了很多变量,找到 @tabs-bottom-bar-color,发现它的取值为 @tabs-default-color,然后发现 @tabs-default-color 的取值为 @red,而 @red 的取值为 #ee0a24,正是有赞默认的背景色。那么我现在就要重新给 @red 赋值为 #ff5722,达到我想要的效果。

主要有两种方式,都是使用 modifyVars 去修改变量,也都是在 nuxt.config.js 文件中操作。我们在前面安装 less-loader 依赖时指定了它的版本为 5.0.0,是因为 6.x 的版本无法识别 modifyVars,导致不能修改变量。详情可以查看文末的资料 3。

方式一在 build 中添加下面的 loaders 部分,然后在 modifyVars 中就可以为变量赋值了,我在这里对 @red 赋值,然后重新运行项目,就会发现默认颜色已经变成了 #ff5722

module.exports = {
build: {
loaders: {
less: {
javascriptEnabled: true,
modifyVars: {
'@red': '#ff5722'
}
}
}
}
}

方式二是在 buildextend 中添加下面的部分。

module.exports = {
build: {
extend(config, ctx) {
config.module.rules.push({
test: /\.less$/,
use: [
{
loader: 'less-loader',
options: {
modifyVars: {
'@red': '#ff5722'
}
}
}
]
})
}
}
}

以上就是在 nuxt.js 项目中使用 vant 的全部流程,包括全量引入,按需引入,修改主题等等,希望对大家有所帮助。
(正文完)

参考资料:

  1. nuxt按需加载vant组件和样式
  2. 在nuxt中使用vant,并支持定制主题
  3. Customization of theme is broken with latest version of less-loader

 评论