目录
使用CSS module
需要将样式文件命名为xxx.module.ooo
xxx为文件名
ooo为样式文件后缀名,可以是css、less
1、思路
css module 遵循以下思路解决类名冲突问题:
css的类名冲突往往发生在大型项目中
大型项目往往会使用构建工具(webpack等)搭建工程
构建工具允许将css样式切分为更加精细的模块
同JS的变量一样,每个css模块文件中难以出现冲突的类名,冲突的类名往往发生在不同的css模块文件中
2、实现原理
在webpack中,作为处理css的css-loader,它实现了css module的思想,要启用css module,需要将css-loader的配置modules设置为true。
css-loader的实现方式如下:
原理极其简单,开启了css module后,css-loader会将样式中的类名进行转换,转换为一个唯一的hash值。
由于hash值是根据模块路径和类名生成的,因此,不同的css模块,哪怕具有相同的类名,转换后的hash值也不一样。
3、如何渲染样式
css module带来了一个新的问题:源代码的类名和最终生成的类名是不一样的,而开发者只知道自己写的源代码中的类名,并不知道最终的类名是什么,那如何应用类名到元素上呢?
为了解决这个问题,css-loader会导出原类名和最终类名的对应关系,该关系是通过一个对象描述的
这样一来,我们就可以在js代码中获取到css模块导出的结果,从而应用类名了
style-loader为了我们更加方便的应用类名,会去除掉其他信息,仅暴露对应关系
得到组件渲染的DOM
/**
获取某个组件渲染的Dom根元素
*/
function getComponentRootDom(comp, props){
const vm = new Vue({
render: h => h(comp, {props})
})
vm.$mount();
return vm.$el;
}
扩展VUE实例
ref
<template>
<div>
<p ref="para">some paragraph</p>
<ChildComp ref="comp" />
<button @click="handleClick">查看所有引用</button>
</div>
</template>
<script>
import ChildComp from "./ChildComp"
export default {
components:{
ChildComp
},
methods:{
handleClick(){
// 获取持有的所有引用
console.log(this.$refs);
/*
{
para: p元素(原生DOM),
comp: ChildComp的组件实例
}
*/
}
}
}
</script>
通过
ref
可以直接操作dom
元素,甚至可能直接改动子组件,这些都不符合vue
的设计理念。除非迫不得已,否则不要使用
ref
代码运用
const iconDom = getComponentRootDom(Icon, {
type,
});
div.innerHTML = `
<span>${iconDom.outerHTML}</span>
<div>${content}</div>
`;
//将div加入到容器中
if(!container){
container = document.body;
} else {
//容器的position是否改动过
if(getComputedStyle(container).position === "static"){
container.style.position = "relative";
}
}
本文含有隐藏内容,请 开通VIP 后查看