关于vue的 scoped
前沿
关于在vite中使用 less | sass
npm install less -D
npm install sass -D
在style标签注明:
<style lang="less"></style>
<style lang="scss"></style>
scoped
scoped
实现组件的私有化,让当前的style
只属于当前模块在
DOM
结构中可以看到,vue
通过在DOM
结构以及css
样式上添加唯一标记:data-v-hash
的方式(这个工作是由 PostCSS 转译实现的),来实现组件样式私有化,不污染全局的作用
scoped的渲染原则
- 给HTML的DOM节点加上一个不重复的data属性(形如
data-v-7ba5bd90
)来表示他的唯一性
- 在每句css选择器的末尾(编译后生成的css语句)加上一个当前组件的data属性选择器来私有化样式
- 如果组件内包含其他组件,只会给其他组件的最外层标签上加上当前组件的data属性
大的
案例演示-样式穿透:deep()
修改Element-ui里的input
样式,发现无法生效
<template> <div><el-input class="ipt"></el-input></div> </template> <script setup lang="ts"> import { ref, reactive } from "vue"; </script> <style scoped lang="scss"> .ipt { width: 200px; margin: 100px 400px; input { // 修改input框的背景色 background-color: red; } } </style>
这是因为我们写了scoped
,它在进行PostCss
转化的时候,把元素选择器默认放在了最后
所以Vue提供了样式穿透:deep()
,它的作用就是用来改变属性选择器的位置
<style scoped lang="scss"> .ipt { width: 200px; margin: 100px 400px; :deep(input) { background-color: red; } } </style>
这样就可以修改框架上的CSS了
BEM架构
BEM
是Block
、Element
、Modifier
的首字母缩写,分为块层、元素层、修饰符层,它是一种css
命名规范。element-ui也是使用的这种架构。
命名约定的模式如下:
.block{} // 块 .block_element{} // 元素 .block--modifier{} // 修饰符
block
代表更高级别的抽象或组件block_element
代表.block
的后代,用于形成一个完整的.block
整体block--modifier
代表.block
的不同状态或不同版本复刻一个bem架构
$block-sel: "-" !default $element-sel: "__" !default $modifier-sel: "--" !default $namespace: "xc" !default // 混入 @mixin b($block) { $B: $namespace + $block-sel + $block // 变量 #{$B} { //插值语法"#{}" @content;// 内容替换,相当于占位符 } } @mixin e($element) { $selector:&; // 获取父元素的命名 @at-root{ // 跳出嵌套,将父级选择器改成根选择器 #{$selector + $element-sel + $element} { @content; } } } @mixin m($modifier) { $selector:&; @at-root{ #{$selector + $element-sel + $element} { @content; } } } @mixin bfc { height: 100%; overflow: hidden; } @mixin flex { display: flex; }
全局扩充sass
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], css: { preprocessorOptions: { scss: { additionalData: "@import './src/bem.scss';" } } } })
组件用法
<template> <div class="xc-box"> <div><Menu></Menu></div> <div class="xc-box__right"> <Header></Header> <Content></Content> </div> </div> </template> <script setup lang="ts"> import { ref, reactive } from "vue"; import Menu from "./Menu/index.vue"; import Header from "./Header/index.vue"; import Content from "./Content/index.vue"; </script> <style scoped lang="scss"> @include b(box) { @include bfc; display: flex; @include e(right) { display: flex; flex-direction: column; flex: 1; } } </style>