最近工作上在用vue对现有项目进行重构。之前也用vue做过一些后台项目,但都是全新的项目,而且项目很小,所以遇到的问题很少。本次重构遇到了一些问题,做个记录。
先说一下,开始理解的误区:
在A组件中import css,那么css 就会应用于该组件及其子组件
组件可以设置类似 html 或者 body等标签的样式
本次项目重构样式基本没有做修改,所以最开始一股脑的将项目中的所有css 都import进来了。包括css的样式重置。但项目中有个页面的样式重置和其它页面不同,尝试了一下方法:
改变import "reset.css" 的组件位置 =》 放在任何组件中 import 进css后,单页应用都会在单页应用的header 中添加一个style标签,将import 的css引入
在样式有变化的组件中,在
经过研究,发现之前提到的误区,是css-loader造成的,正确的理解是:
1.css-loader 默认将import 或require 的css 文件插入到全局
By default CSS exports all classnames into a global selector scope. Styles can be locally scoped to avoid globally scoping
css-loader 提供了:local(.className) ,来将某一个.className 设置为scoped,但对项目的实际情况不是很实用,首先我们是reset css 不同,没有className, 其次即使全是className,全部加上:local工作量也很大,个人感觉不是特别优雅。
组件只能对组件template范围的样式进行设置,试图对父组件的样式进行设置,会被忽略
首先对第一点进行理解,因为是单页应用,css插入全局的意思就是说,无论我们的router如何变化,全局css 始终都会发生作用。
第二点,组件的控制范围只在组件内部,对于全局样式的控制,都显得特别不合理。
终于说到了解决方法,经过研究,发现style-loader有一个配置项Useable
实践改配置项:
项目用vue的脚手架vue-cli 搭建,vue-cli默认并没有实用style-loader,而是用了vue-style-loader,官方解释是fork base on style-loader, ,但经过试验发现vue-style-loader并没有 Useable 这个配置项,于是我们的解决方案步骤就清晰了:
install style-loader 替换vue-style-loader
修改utils.js 改变css的处理方式,(less标注的文件都会用style-loader 的Useable项处理)如下:
exports.cssLoaders = function (options) {
options = options || {}
var cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap
}
}
function generateLoaders(loader, loaderOptions) {
var loaders = [cssLoader]
if (loader && loader != 'less') {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
if (options.extract) {
if (loader != 'less') {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'style-loader'
})
} else {
return loaders;
}
} else {
if (loader != 'less') {
return ['style-loader'].concat(loaders)
} else {
return ['style-loader/useable'].concat(loaders);
}
}
}
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', {indentedSyntax: true}),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
tips: 这里说一下,
在App.vue 中
import reset from '@/css/reset.less'
export default {
created () {
reset.use()
}
}
假设Test.vue,需要用不同的reset ,那么再Test.vue中用unuse(), 来将在App.vue 中注入全局的css 取消。
import reset from '@/css/reset.less'
import newreset from '@/css/newreset.less'
export default {
created () {
reset.unuse()
newreset.use()
}
}
说一下,在解决过程中遇到的一些问题:
style-loader的useable配置项,只能通过style-loader/useable, 使用
options:{
useable:true
}
会报错
2. 官方建议,使用useable的css 文件,可以采用.useable.css来做后缀,但经过实践在vue-cli编译不过,具体原因待查明
最后本次重构没有计划对css做特别的改动,所以采取了很简单的方式(其实是因为懒☹️),比较优雅的方式,使用局部样式,比如css-loader的modules
import style from 'style.loader'