当前位置: 首页 > news >正文

Vue学习记录之六(组件实战及BEM框架了解)

一、BEM

BEM是一种前端开发中常用的命名约定,主要用于CSS和HTML的结构化和模块化。BEM是Block、Element、Modifier的缩写。

  • Block(块):独立的功能性页面组件,可以是一个简单的按钮,一个复杂的导航条,或者任何其他独立的UI部分。块的名称是唯一的,且通常是名词,比如menu、button等。
  • Element(元素):块的组成部分,具体表现为块内部的某个部分。元素的命名是在块的名称后加上两个下划线__,然后是元素的名称,比如menu__item、button__icon等。
  • Modifier(修饰符):用于定义块或元素的不同状态或外观。修饰符的命名是在块或元素的名称后加上两个破折号–,然后是修饰符的名称,比如button–large、menu__item–active等。

通过这种命名方式,可以使代码具有更好的可读性和可维护性,并且不同组件之间不会发生命名冲突。例如:

<div class="menu"><ul class="menu__list"><li class="menu__item menu__item--active">Home</li><li class="menu__item">About</li></ul>
</div>

在这个例子中:

menu 是块(Block),表示一个菜单。
menu__list 是元素(Element),表示菜单中的列表。
menu__item 是元素(Element),表示列表项。
menu__item - - active 是修饰符(Modifier),表示列表项的活动状态。

使用BEM的好处包括:
可读性强:通过明确的命名规则,代码变得更加容易理解。
可维护性高:模块化的结构使得代码更容易维护和更新。
避免命名冲突:由于每个类名都包含了块的名称,避免了全局命名空间的冲突。

二、sass

(Syntactically Awesome Style Sheets)是CSS的扩展,提供了更强大的功能。使用的时候先进行安装。

pnpm i sass

1、变量: 定义变量使用 $变量名

$primary-color: #3498db;

2、嵌套:

.nav {ul {list-style: none;}li {display: inline-block;}
}

3、混合(Mixins): 使用@mixin
定义和使用混合宏
定义混合宏(mixin):使用 @mixin 指令来定义一组样式。
包含混合宏(mixin):使用 @include 指令来将这些样式应用到某个选择器中。

@mixin border-radius($radius) {border-radius: $radius;
}
.box {@include border-radius(10px);
}

4、继承(Extend):

.button {padding: 10px;background: $primary-color;
}.primary-button {@extend .button;color: white;
}

5、运算:

.container {width: 100% - 20px;
}

6、条件语句:

@if $theme == dark {background: black;
} @else {background: white;
}

7、循环:

@for $i from 1 to 3 {.item-#{$i} {width: 100px * $i;}
}

8、插值语法
用于动态生成类名、ID或其他属性值,通常通过#{$variable}的方式实现。以下是一些插值语法的常见用法:

//动态生成类名
$color: red;
.text-#{$color} {color: $color;
}
这段代码生成的类名是 .text-red。
--------------------------------------
//动态生成属性值 
$size: 16px;
.box {width: #{$size * 2};
}
这段代码生成的样式为 width: 32px;。
---------------------------------------
//与其他字符串结合
$prefix: "btn-";
.#{$prefix}primary {background-color: blue;
}
这段代码生成的类名是 .btn-primary。
-------------------------------------------
// 在选择器中使用插值
$state: "active";
.button-#{$state} {color: green;
}
这段代码生成的类名是 .button-active。

这些语法使得Sass更加灵活,易于管理和维护样式表。 @content 相当于一个占位符,也可以理解为slot(插槽)

  • #{} 用于插入任何类型的值(如属性、选择器名等),不特定于类。
  • .#{} 主要用于生成类选择器,确保插入的内容以.开头,形成有效的类选择器。
    所以,如果你需要插入的内容是类名,就使用.#{};如果是属性名或者其他类型的选择器,则直接使用#{}。

三、使用

1、在src 目录下建立一个bem.scss 文件。

$namespcae: 'xm' !default;
$block-sel:"-" !default;
$elem-sel:"__" !default;
$mod-sel:"--" !default;//1、定义block
@mixin b($block){//如 class="xm-block" 即: .xm-block{}$B: #{$namespcae + $block-sel + $block};//命名完了以后,我们初始化下.#{$B}{//相当于占位符或者插槽@content;}
}
//2、定义element  如 .xm-block__inner{}  类型的。
@mixin e($e){$selector: &; //&符号读取到父级的类名(它代表‌父选择器),即: .xm-block/*#{$selector + $elem-sel + $e}{@content;}*///但是我们一般希望编译出去不要在增加这么一个父级的类型//如 .xm-block .xm-block__inner{},这里需要跳出嵌套,// 使用 @at-root进行包裹,然后就变成了独立的.xm-block__inner{}@at-root{#{$selector + $elem-sel + $e}{@content;}}
}
//3、modify
@mixin m($m){$selector: &; @at-root{#{$selector + $mod-sel + $m}{@content;}}
}

2、写完规则,要在全局使用,还需要进行配置。 在vite.config.ts 中进行配置。

css:{preprocessorOptions:{scss:{additionalData:`@import "./src/deom.scss";`}}}

在这里插入图片描述
3、配置完了以后就可以使用了。在App.vue中使用
注意 结构,以块为单位,块内的元素,和修饰符要写在自己的块内。

<template><div><div class="xm-test">我是块<div class="xm-test__inner">我是元素</div><div class="xm-test--success">我是修饰符</div></div></div>
</template>
<script setup lang='ts'>
import A from './components/A.vue';
</script>
<style lang="scss">
@include b(test){color: red;@include e(inner){color: green;}@include m(success){color: orangered;}
}
</style>

在这里插入图片描述
如果不使用@at-root包裹,那么编译以后就会变成下面的格式:
在这里插入图片描述

四、实战

在这里插入图片描述

一、使用vite+vue3 构成程序框架。
二、清除默认样式
在根目录下的index.html中加入

<style>*{padding: 0;margin: 0;}html,body{height: 100%;overflow: hidden;}

在我们的scss文件中在加入一个混合项:bfc

$namespcae: 'xm' !default;
$block-sel:"-" !default;
$elem-sel:"__" !default;
$mod-sel:"--" !default;@mixin bfc{height: 100%;overflow: hidden;
}@mixin b($block){$B: #{$namespcae + $block-sel + $block};.#{$B}{@content;}
}
@mixin e($e){$selector: &; @at-root{#{$selector + $elem-sel + $e}{@content;}}
}
@mixin m($m){$selector: &; @at-root{#{$selector + $mod-sel + $m}{@content;}}
}

然后app.vue 的style中加入:

<style lang="scss">#app{@include bfc;}
</style>

新增目录结构
在这里插入图片描述
Layout/index.vue 代码如下:

<template><div class="xm-box"><div><Menu></Menu></div><div class="xm-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  //左右拉满,也就是100%显示}
}
</style>

Layout/Content/index.vue 代码如下:

<template><div class="xm-content"><div class="xm-content__items" v-for="item in 100">{{ item }}</div></div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
</script>
<style scoped lang="scss">
@include b(content){flex: 1;  //向下也拉满了overflow: auto;  //自适应高度@include e(items){padding: 10px;margin: 10px;border: 1px solid #ccc;border-radius: 4px;}
}
</style>

Layout/Header/index.vue 代码如下:

<template><div class="xm-header">Header</div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
</script>
<style scoped lang="scss">
@include b(header){height:50px;border-bottom: 1px solid #ccc;
}
</style>

Layout/Menu/index.vue 代码如下:

<template><div class="xm-menu">Menu</div>
</template>
<script setup lang='ts'>
import { ref,reactive } from 'vue'
</script>
<style scoped lang="scss">
@include b(menu){height: 100%;min-width: 200px;border-right: 1px solid #ccc;
}
</style>

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • STM32巡回研讨会总结(2024)
  • [000-01-008].第05节:OpenFeign特性-重试机制
  • LeetCode题练习与总结: 数字 1 的个数--233
  • Resnet50网络——口腔癌病变识别
  • 在HTML中添加视频
  • Dell PowerEdge 网络恢复笔记
  • 胤娲科技:谷歌DeepMind祭出蛋白质设计新AI——癌症治疗迎来曙光
  • Thymeleaf
  • 网安面试题1
  • 计算机二级 MS office总结
  • 移植Linux:如何制作rootfs?
  • Alluxio Enterprise AI on K8s FIO 测试教程
  • 2024年中国研究生数学建模竞赛ABCDEF题【附带解题思路代码+结果】
  • 【RPA私教课:UIPath】RPA 赋能科技企业,登录时验证码自动截取
  • 详解npm源及其使用方法
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 2019.2.20 c++ 知识梳理
  • C++11: atomic 头文件
  • Java|序列化异常StreamCorruptedException的解决方法
  • js递归,无限分级树形折叠菜单
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • mysql innodb 索引使用指南
  • Octave 入门
  • Theano - 导数
  • v-if和v-for连用出现的问题
  • webgl (原生)基础入门指南【一】
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 理清楚Vue的结构
  • 数组的操作
  • 微服务框架lagom
  • 项目实战-Api的解决方案
  • ‌移动管家手机智能控制汽车系统
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • (1)STL算法之遍历容器
  • (4)(4.6) Triducer
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (LLM) 很笨
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (十三)Flink SQL
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (算法)区间调度问题
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)iOS字体
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (转)可以带来幸福的一本书
  • **python多态
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .JPG图片,各种压缩率下的文件尺寸
  • .NET CLR基本术语
  • .NET 简介:跨平台、开源、高性能的开发平台