--~---~---~---~---~---~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~--
使用篇
method
作为属性, 若未在 props
声明, 可通过 $attrs
访问. 多层级组件可使用 $listener
来抛出事件子组件中 v-model
优雅地绑定父组件属性: .sync
和 update:
结合计算属性. .sync
其实是语法糖, 父组件会自动同步在子组件的 update:
抛出的值
.sync
来自动接收子组件抛出的 update:
. 子组件重新定义一个带有 set / get
的计算属性: set
抛出更新触发 .sync
; get
取 props
值.sync
修饰, 否则子组件 update:
没有接收, 链条就断了. // 通过计算属性优雅地在子组件使用 `v-model` 绑定父组件的值
currentPage: {
get() {
return this.page
},
set(val) {
this.$emit('update:page', val)
}
}
若父组件是在 created
内使用 this.$nextTick(() => { })
,其内部执行会晚于子组件的 mounted
方法。如在 router-view
嵌套的二级路由页面 mounted
晚于父组件 $nextTick
.sync
处理对象更新
table
的封装, 监听多选抛出对选集合数据: 父组件传入空集合, 子组件在多选选择事件内进行抛出路由声明式传参:params
下页面刷新不会丢失,被存储在路径中,并且变量名提前声明了. 路由无参数会进入 404, 且 push 推入路由页面需要使用 name 属性
过滤器支持多参: 首参默认是数据源, 不能修改. 如 全局过滤器, 时间格式化和解析, 默认值: YYYY-MM-DD HH:mm:ss
, 也可自定义传入 fecha
支持的格式
计算属性和 watch: 计算属性监听的值没有变化不会重新计算, 且可以同时监听多个属性, 唯一的问题是, 她需要被使用才会触发: 如果有这个需求可以使用 watch,一个 watch 只能监听一个属性
process.env.VUE_APP_PLATFORM
集合的值决定: 若仅有 mob 入口为移动端, 否则为 admin. 若兼容两端则 index 根据设备自动跳转对应路由bus
flex-rem
中的 window.onresize
bus.$vm.$on
, 需要在 destroyed() { bus.$vm.$off(bus.$sel.window_resize); }
关闭监听. 若仅仅监听一次使用 bus.$vm.$off
, 抛出事件 bus.$vm.$emit
// vue 支持 vue-hooks
created() {
bus.$vm.$on(bus.$sel.window_resize, () => { });
// vue 支持 vue-hooks
this.$on("hook:destroyed", () => {
bus.$vm.$off(bus.$sel.window_resize);
});
}
优化
this.item = Object.freeze(Object.assign({}, this.item))
滤掉无用字段可用封装 optimize
库plop
方式下自动生成js 和 css 变量共享
css-modules :export
来实现, 如 variables.styl
导出 :export { colorTheme: $-color-theme }
. 在 js 内 import 文件即可. css 也可用App.vue
内, 通过 vuex 实现了高分屏兼容 @media 布局: 控制显示设备. IE 不支持 css var()
swiper
最新版 ^5.3.8
不支持 IE10
, 选择兼容版本 ^3.4.2
版本. 匹配 vue-awesome-swiper
版本 ^2.6.7"
(各个 swiper 版本间配置稍有不同)skeleton
: 若骨架屏注入, 提示资源加载异常, 将 .env
中 VUE_APP_SKELETON
设置为空字符串即可. (index.html 引入 skeleton.css
可不注释)vue add quasar
添加 quasar
组件库, 选择兼容 IE 11
, 依赖和配置会自动注入
底部导航栏体验优化 计算布局容器避免使用 margin
TabBar
上下滑动时会移动, 且 web
页面自身的滑动和 webview
自带的滑动体验感极差, 尤其添加了下拉刷新quasar
的 QScrollArea
组件, 其还支持自定义滚动条. 计算出固定位置高度后, 余下部分留给使用 QScrollArea
进行包裹, 是兼容 QPullToRefresh
下拉刷新的 <!-- 滚动标签 -->
q-scroll-area.main-area(:thumb-style="thumbStyle" :bar-style="barStyle" :style="{height: areaH}")
<!-- 高度属性 -->
data() {
return {
areaH: 0 // 自定义滑动区域, 优化体验
};
},
computed: {
// 自定义滚动区域 Bar 样式
thumbStyle() {
return {
right: "4px",
borderRadius: "5px",
backgroundColor: "#027be3",
width: "5px",
opacity: 0.75
};
},
barStyle() {
return {
right: "2px",
borderRadius: "9px",
backgroundColor: "#027be3",
width: "9px",
opacity: 0.2
};
}
},
async created() {
// 因为父组件内使用 `this.$nextTick(() => { })`
this.$nextTick(() => {
this.areaH =
document.body.clientHeight -
this.tabH -
this.$refs.dateDom.clientHeight +
"px";
});
},
created
内使用 $nextTick
,其内部执行会晚于子组件的 mounted
方法。如在 router-view
嵌套的二级路由页面 mounted
晚于父组件 $nextTick
100%
, 因此页面滑动 tabBar
不会出现上下移动体验差情况. 若有可能, 通过各平台 jsApi 关闭 webview 的弹性效果 import { ui as ddUI } from "dingtalk-jsapi";
mounted() {
// 锁定滑动, 自定义滑动区域
ddUI.webViewBounce.disable();
},
--~---~---~---~---~---~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~--
配置篇
plop-templates
, 包含了组件, 页面和 vuex
. vue
配置同于 vue.json
的 snippets
. vuex
同于其 modules
下配置plopfile.js
文件, 并在 package.json
的 scripts
配置 new
, 运行 npm run new
即可选择对应魔板和文件路径名称, 即可生成. 自动添加组件 name
mob
配置了 tabBar
(使用路由模式: 不需要绑定 active
. vant
跳转仅使用二级路由 path
即可), admin
配置了 sideBar
, 由 admin.js
路由文件 reduce 处理后加载children
内 path
前不添加 /
, 则使用时需要 一级path/二级路由path
的格式; 若添加了 /
, 则可直接使用其二级路由的 path
,tabBar.js
配合 vant
使用路由模式: 不需要绑定 active
. vant
跳转仅使用二级路由 path
即可. tab
的活跃取决于当前绑定的路由, 不使用 v-model
@import "~mixin"
, m-background-image('~image/background-admin.png')
, ...~
标识说明: 配置了 webpack 输出路径为 ./
, 样式和图片文件 实质上是从编译包读取, 因此在 css 内引入需要添加, 注意: hmtl 内不能使用别名, 未进入编译前言
webpack
运行会自动读取环境变量, 基于 NodeJs
. vue.config.js
内使用 ES5 语法不能通过 import
读取外部文件, 可用 require
. (process 不支持解构取值).env
为全局环境变量, 运行 package.json - scripts
对应环境命令时, 先加载全局 .env, 再加载对应环境下变量, 同名变量后覆盖前serve / dev
默认读取 .env.development
, build
读取 env.prod
. 若需要运行自定义环境, 在对应命令后追加 --mode 对应环境配置文件名称
.local
也可以加在指定模式的环境文件上,比如 .env.development.local 将会在 development 模式下被载入,且被 git 忽略 (配置秘钥会很有用)使用
VUE_APP_*
, 取值通过 process.evn.VUE_APP_*
取对应的 key 即可. 修改变量需要重新 run 项目, webpack 重新读取, 否则不生效ISANALYZ
. 若需要打到 dist 包内, 则必须符合 VUE_APP_*
格式"", 空字符串
.
.env
是 string
化的值, 非合法 json: string
可使用 includes
函数, 单独效验使用正则proxy
为对象类型, 继续添加对应环境变量, 同理配置即可实现// 本地代理
devServer: {
proxy: {
[env.VUE_APP_DEV_PROXY]: {
// target字段为空编译报错
target: env.VUE_APP_BASE_API,
changeOrigin: true,
pathRewrite: {
["^" + env.VUE_APP_DEV_PROXY]: ""
}
}
},
disableHostCheck: true
},
.local
文件内. 只需要修改开发环境文件中 VUE_APP_DEV_PROXY
即可// 开发代理
function _devProxy(url) {
return process.env.VUE_APP_DEV_PROXY + url;
}
不直接使用对 axios
的封装 request
, 进行网络请求: thunk 包装调用, 在实际请求文件中导入 request
. 对 axios 的封装是 create 新的对象
使用
详见 @/service/request:
. 发起请求不直接引用 request
, 通过 thunk
包装调用request
中新建了 axios 对象, 使用通过对应业务文件按需加载 (不使用 vue-router
插件, 不在原型链添加 axios 对象)拦截器
Uncaught (in promise) Error: 错误信息
, 阻断代码继续执行, 不需要添加额外条件处理try...catch
语法; 或在调用方法后追加 .catch(err => {})
进行捕获 (被捕获后则控制台不会报错, 注意后续代码执行, 不会阻断代码继续执行) // 当前月事件分布 - 实现 catch 要注意添加 if (!res) return; (catch 后 await 得到的就是其返回的值, 没有返回即为 undefined)
async refreshMonthMark(params) {
const res = await monthRecordList(params).catch(() => false);
if (!res) return;
this.dateEvents = res.list.map(item => item.date.replace(/-/gi, "/"));
}
async
方法, 内部没有返回 Promise
, 是不支持 await
的: 如 reLogin
的实现, 内部返回 Promise
, 通过 bus
实现监听. 在 progress
重置登录中 bus
抛出
async created () {
await this.loginAuth(); // 登录验证: 返回Promise
this.inputCalendar(this.today) // 调用封装的async方法, 内部没有返回Promise, 是不支持await的: 若成功执行到reLogin后被挂起
await this.relogin() // 重试登录: 返回Promise => 每次登录失效的请求都会触发: 内部做一个throttle, 避免多个连续登录请求
this.inputCalendar(this.today) // 若收到登录失效回调: 刷新所有请求接口. 若正常请求成功, 被reLogin的await挂起
},
destroyed() {
bus.$vm.$off(bus.$sel.login_timeout);
}
// 登录过期重新登录: 每次登录失效的请求都会触发. throttle, 避免多个连续登录请求
relogin () {
return new Promise(resolve => {
const _reLogin = throttle(() => this._ddingLoginAuth(this, resolve), 300);
bus.$vm.$on(bus.$sel.login_timeout, () => _reLogin()); // 响应抛出登录失效
})
},
// 钉钉免登
loginAuth () {
if (this.token) return Promise.resolve();
return new Promise(resolve => {
const _this = this;
ready(function () {
_this._ddingLoginAuth(_this, resolve)
});
});
},
// 钉钉登录授权
_ddingLoginAuth (_this, resolve) {
runtime.permission.requestAuthCode({
corpId: process.env.VUE_APP_CorpId,
onSuccess: function (result) {
_this.loginIn({ authCode: result.code }).then(() => resolve());
}
});
},
提示效果 @service/progres.js
import store from "@/store";
const progress = {};
const env = process.env;
const _this = Vue.prototype;
// 组件库优先于平台和设备: quasar 通用最优, 其次是优先移动端
const quasar = env.VUE_APP_PLATFORM.includes(env.VUE_APP_UI_QUASAR);
const vant = env.VUE_APP_PRIORITY !== "admin" && store?.state?.config?.native;
配置差异和说明
presets
配置使用 cli 自带插件, 不需要使用 es2015
. 若使用 npm i babel-preset-es2015 -D
依赖 (-D 为 --save-dev, -S 进入 dependencies
)element-ui
依赖于 babel-plugin-component
, vant-ui
依赖于 babel-plugin-import
. 都是开发依赖quasar
通过 vue add quasar
自动添加. 关于 quasar.variables.styl
不能修改文件名称和路径: 因为 loader
对路径做了绑定和优化, 需要引入才会生效babel.config.js
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
plugins: [
"@babel/syntax-dynamic-import" /*异步加载*/,
[
"component",
{
libraryName: "element-ui",
styleLibraryName: "theme-chalk"
},
"element-ui"
],
[
"import",
{
libraryName: "vant",
libraryDirectory: "es",
style: false // 主题和样式重置设置 false 减少包体积
},
"vant"
],
[
"transform-imports",
{
quasar: {
transform: "quasar/dist/babel-transforms/imports.js",
preventFullImport: true
}
}
]
]
};
重置主题和样式
App.vue
中导入通用和样式重置: @import '~@/styles/loader/common'
, @import '~@/styles/loader/browser.reset'
navBar
组件导入移动端重置: 禁用长按复制粘贴: 在 navBar
载入 @import '~@/styles/loader/navBar.reset'
element-ui
使用 sass
, 需要下载 node-sass
和 sass-laoder
开发依赖, 新建一个后缀为 .scss 而不是 .sass 的文件, 在 main.js 引入, 不是 App.vuevant-ui
使用 less
, 需要下载 less
和 less-laoder
开发依赖, 配置: loaderOptions
自动导入、main.js
导入主题、.babel.config.js
减少包体积vant-ui
在main.js
中import "vant/lib/index.less";
引入主题. 且在vue.config.js
配置loaderOptions
进行样式重置; 在babel.config.js
配置style: false
以减少包体积quasar
通过 vue add quasar
添加 quasar
组件库, 配置手动加载组件, styles
预编译, icons
使用 recommend
, 选择兼容 IE 11
, 依赖和配置会自动注入quasar
因不能修改 quasar.variables.styl
文件名和路径, 因此配置主题重置于此文件, 并在 mian,js
添加编译以引入 (quasar.styl
和 quasar
通过配置后删除)main.js
// 按需引入组件库 & 主题和样式重置
/* IFTRUE_ELEMENT */
import "@/config/loader/element.ui";
import "@/styles/loader/element.variables"; // 主题和样式重置
/* FITRUE_ELEMENT */
/* IFTRUE_VANT */
import "@/config/loader/vant.ui";
import "vant/lib/index.less"; // 需引入主题: 且在 vue.config.js 配置 loaderOptions 进行样式重置; babel.config.js 配置 style: false 以减少包体积
/* FITRUE_VANT */
/* IFTRUE_QUASAR */
import "@/config/loader/quasar.ui";
import "@/styles/quasar.variables"; // 备注: 不能修改文件名称和路径: loader对路径做了绑定和优化, 需要引入才会生效 (vue add quasar 自动添加)
/* FITRUE_QUASAR */
vue.config.js
// vant-ui 主题覆盖 less (条件编译) //
let vantVariables = {};
/* IFTRUE_MOB */
vantVariables = {
modifyVars: {
hack: `true; @import "~@/styles/loader/vant.variables";`
}
};
/* FITRUE_MOB */
// es5语法, 导出一份拷贝: 修改需要重新运行
module.exports = {
// css配置: 自动加载 loaderOptions 对 stylus 和 less 都无效
css: {
less: vantVariables
},
configureWebpack: config => {
// quasar: vue add quasar 自动添加
pluginOptions: {
quasar: {
importStrategy: "manual",
rtlSupport: false
}
},
transpileDependencies: ["quasar"]
}
}
vue-skeleton-webpack-plugin
注入骨架屏. 环境变量 VUE_APP_SKELETON
控制是否加载骨架屏// vue骨架屏插件配置
if (env.VUE_APP_SKELETON) {
config.plugins.push(
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: resolve("src/config/skeleton/conf")
}
},
minimize: true,
quiet: true
})
);
}
可通过 https://github.com/famanoder/dps
插件生成骨架屏, 将页面导入到 @/config/skeleton
即可; 或使用 vue-content-loader
组件库, mob 可使用 vant 组件
更建议使用全局 loading gif 替换, 将图片打包为 base64 注入到代码: 骨架屏是打包注入, 此时不能访问 window. 根据条件编译, 可选择优先平台. 移动端端优先
// 骨架屏是打包注入, 此时不能访问 window: 移动端优先
const compile = process.env.VUE_APP_PRIORITY === "mob";
// 骨架屏: 全局记录挂在方法
window.mountApp = () => {
app.$mount("#app");
window.mountApp = null;
};
// 骨架屏:当js晚于css加载完成,那直接执行渲染
if (window.STYLE_READY || process.env.VUE_APP_SKELETON) {
window.mountApp?.();
}
/* 骨架屏 (触发器): 服务于 index.hml, 触发自动挂载 vue 对象 -- skeleton.css */
<!-- 骨架屏结束触发自动挂载 vue 对象 -->
<link rel="preload" href="./skeleton.css" as="style" onload="rel='stylesheet';this.onload=null;loadSkeleton?.();">
<script>
function loadSkeleton() {
window.STYLE_READY = true;
window.mountApp && window.mountApp();
loadSkeleton = null
}
// Firefox 不支持 preload
if (navigator.userAgent.indexOf("Firefox") > 0) {
loadSkeleton && loadSkeleton()
}
</script>
前言: require
支持 if, import
需要使用 const x = () => import('') / import('').then()
, 返回 Promise
, 且返回值被 default
包裹 . 引入就被 build, 因此更优是条件编译
初衷: 不同平台按需加载对应模块, 定制化情况下减少包体积 (没有条件编译会打入包)
// 配置条件编译: js-conditional-compile-loader 下 npm 和 cnpm 不能混用
config.module.rules.push({
test: /\.js\$/,
include: [resolve("src"), resolve("test")],
use: [{
loader: "js-conditional-compile-loader",
options: {
isDebug: process.env.NODE_ENV == "development", // optional, this is default
// 自定义 flag: process.env.npm_config_flag
VANT: env.VUE_APP_PLATFORM.includes(env.VUE_APP_UI_VANT),
ELEMENT: env.VUE_APP_PLATFORM.includes(env.VUE_APP_UI_ELEMENT),
QUASAR: env.VUE_APP_PLATFORM.includes(env.VUE_APP_UI_QUASAR),
}
}
]
});
vue.config.js
添加了 MOB
和 ADMIN
和 UNI
编译条件, 通过 VUE_APP_PLATFORM
集合控制加载不同组件库 (配置见 按需加载
)/* IFDEBUG // 开发环境下远程调试vconsole
import "@/config/loader/vconsole";
FIDEBUG */
const indexAuto = "/index"; // 若有重定向, 使用目标页面, 避免由redirect触发router切换后报错
const indexMob = "/loginIn";
const indexAdmin = "/login";
let index = indexAuto;
import mob from "./modules/mob";
import admin from "./modules/admin";
import universal from "./modules/universal";
const compile = process.env.VUE_APP_PRIORITY;
const routes = [];
if (compile === "mob") {
index = indexMob;
routes.push(...mob);
} else if (compile === "admin") {
index = indexAdmin;
routes.push(...admin);
} else {
if (compile === "universal") {
routes.push(...universal);
} else {
routes.push(...mob, ...admin, ...universal);
}
}
// 代码压缩去除打印: npm i uglifyjs-webpack-plugin@1 需要使用低版本, 新版本不识别 const 关键字 - 报 npm audit fix
minimizer: [
new TerserPlugin({
cache: false,
sourceMap: false,
parallel: true, // 使用多进程并行运行来提高构建速度。默认并发运行数:os.cpus().length - 1。
terserOptions: {
compress: {
drop_debugger: true, // 去除 debugger
drop_console: true, // 生产环境自动删除 console
dead_code: true // 去除不可达代码: 如 if (false) { ... }
},
warnings: false
}
})
];
--~---~---~---~---~---~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~--
样式篇
css 颜色透明度:rgba(0, 0, 0, 0.6) / rgba("#000", 0.6)
因为高分屏 flexRem.js
设置了 viewport
高分屏缩放比例方案. 导致 @media
无效, -none、-xs、-sm、-md、-lg、-xl
无效. col
和 row
可用, 但不支持分设备
通过 vuex
配置了 config
文件, vuex
状态同步更新, 支持响应式动态绑定, 在 App.vue
全局进行响应
native
是否移动端设备: 在 flexRem
的 resize
响应式更新. flexRem 窗口 resize 同步更新 store.commit("config/SET_IS_NATIVE", isNative());
realWid
还原 document.body.clienWidth
真实的宽度. 在 setFlexRem
中同步 store.commit("config/SET_REAL_WID", document.body.clientWidth * scale);
getters
缓存和响应需要监听变更窗口的临界点, 实现了类 @media 效果, 响应式尺寸配置型 // computed
const getters = {
// 缓存realWid是否需要变更布局
media: state => {
const docWid = state.config.realWid;
return {
mob: docWid <= 734,
pad: docWid > 734 && docWid <= 1080,
pc: docWid > 1080
};
}
};
通过绑定动态 class
对象, 实现类似 @media
的效果
在页面顶层容器 App.vue
上绑定动态样式 `div(id="app" :class="classMedia"). 容器包含关系, 样式自然全局有效
将动态样式绑定在计算属性 computed
内, 和 App.vue
容器绑定. 如下监听 this.$store.getters
对于 @media
计算属性的变化
<script>
export default {
computed: {
// 实现了@media功能, 兼容高分屏方案
classMedia() {
const { mob, pad, pc } = this.$store.getters.media;
const native = this.$store.state.config.native;
return {
"media-mob": mob,
"media-pad": pad,
"media-pc": pc,
// 移动设备, 监听运行环境是否移动设备
"device-native": native,
"device-web": !native
};
}
}
};
</script>
@media
重置样式, 将样式写入对应类下即可, 注意权重, 建议直接复制修改对应值 // 通过vuex实现了高分屏兼容@media布局: 控制显示设备, only 当前设备显示, not 当前设备隐藏(_注意理解 `only` 的含义_)
.media-mob
.only-pad, .only-pc, .not-mob
display none
.media-pad
.only-mob, .only-pc, .not-pad
display none
.media-pc
.only-pad, .only-mob, .not-pc
display none
// 移动设备, 监听运行环境是否移动设备
.device-native
.only-web, .not-native
display none
.device-web
.only-native, .not-web
display none
若需要为指定自定义 @media
重置样式, 将样式写入对应类下即可
only
和 not
, 不同设备类下进行重置, 多个设备取并集即可. 注意权重, 建议直接复制然后修改对应值mob
显示: q-menu.only-mob
, 仅不在 mob
显示: q-tabs.not-mob
. 不要取并集如 q-tabs.only-pad.only-pc
可能两个设备下都不会显示. 注意理解 only
的含义 // 通过 vuex 实现了高分屏兼容@media 布局
.media-pc, .media-pad
.layout
&-content
&:first-child
left 25%
&:last-child
right 25%
.media-mob
.layout
&-content
width 100%
4. `device-web` 和 `device-native` 检测. 也同样添加了 `only` 和 `not` 处理. 样式重置可以取并集. _参考上面第2 和第1 的说明_
// 仅web环境下添加: q-btn 的 hover 效果
.device-web
.q-btn
transition all 0.5s
position relative
overflow hidden
.q-btn:before
content ''
position absolute
top 0
left 0
width 100%
height 100%
z-index 1
transition all 0.5s
opacity 1
transform translate(-105%, 0)
border-right-width 1px
border-right-style solid
border-right-color rgba(0, 0, 0, 1)
background-color rgba(0, 0, 0, 0.25)
.q-btn:hover:before
opacity 0
transform translate(0, 0)
基准值 100, 基准字号 14
, 可根据设计图实际调整, 配置在 .env
文件onsize
方法动态更新尺寸, 更新方法 setFlexRem
做了防抖和节流// setFlexRem 防抖和节流
import { debounce, throttle } from "@/utils/optimize";
import bus from "@/config/event-bus";
// 节流: 初始化和 onresize 加载时
const initLayout = throttle(isEmit => {
setFlexRem();
if (isEmit) bus.$vm.$emit(bus.$sel.window_resize); // 响应式更新
}, 400);
// 初始化
initLayout();
// 兼容 onresize 改变窗口全局调用: 防抖
window.onresize = debounce(() => initLayout(true), 200);
// 响应式需要调用resize事件以响应加载时更新
window.onload = () => {
bus.$vm.$emit(bus.$sel.window_onload);
bus.$vm.$emit(bus.$sel.window_resize);
};
// bus.$vm.$on(bus.$sel.window_resize, () => { }); // 响应resize
// bus.$vm.$on(bus.$sel.window_onload, () => { }); // 响应onload
初次不生效多刷新下
)@import '~styles/extend'
, 若使用 @extend
时, 导入必须在 @extend
之前. mixin 不受影响. @extend 导入后可直接使用已定义样式Unicode
模式下多色图标是无效的, 若有需求可使用 Font class
或 Symbol
. Unicode
下若图标需要在 data
传递到标签, 将 
替换为 \ue606
即可// css 配置: 自动加载 loaderOptions 对 stylus 和 less 都无效
css: {
extract: true,
sourceMap: false,
loaderOptions: {
// 自动加载仅导入主题: less sass stylus 方式不相同 - 细节详见 README.md
stylus: {
import: "~@styles/loader/variables.styl"
}
}
},
前言
loaderOptions
对, less sass stylus 方式不相同. 以下是使用 style-resource-loader
自动加载 css 整理说明
使用
配置
// 自动加载主题: 使用 vue add style-resources-loader 添加插件方式
pluginOptions: {
"style-resources-loader": {
preProcessor: "stylus",
// 自动加载仅导入主题: 支持 .css 文件,不需要添加 css-loader - 细节详见 README.md
patterns: [path.resolve(__dirname, "src/theme/index.styl")]
}
},
--~---~---~---~---~---~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~---~---~---~---~---~--~-----~---~-----~---~---~--