关于vue的 scoped

发布时间 2023-09-11 15:54:00作者: -鹿-

前沿

关于在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的渲染原则

  1. 给HTML的DOM节点加上一个不重复的data属性(形如data-v-7ba5bd90)来表示他的唯一性
  1. 在每句css选择器的末尾(编译后生成的css语句)加上一个当前组件的data属性选择器来私有化样式
  1. 如果组件内包含其他组件,只会给其他组件的最外层标签上加上当前组件的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架构

BEMBlockElementModifier的首字母缩写,分为块层、元素层、修饰符层,它是一种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>