本文介绍: 问题:在我们页面开发时,需要修改样式样式有的是全局公有样式,有的是局部样式。有时需要公有样式进行局部样式调整,那么如何灵活的调整样式呢?

问题:在我们页面开发时,需要修改样式样式有的是全局公有样式,有的是局部样式。有时需要公有样式进行局部样式调整,那么如何灵活的调整样式呢?

一、Vue使用scoped属性

1. scoped属性原理

1、在style标签添加scoped属性css只作用于当前组件中的元素,形成独立作用域,使样式私有化。
2、在加上scoped后,会为DOM节点自动添加一个唯一属性datavhashhash随机哈希值),以保证其唯一性。同时在相应的css选择器末尾,也加上了当前组件datavhash属性,来使其私有化。

在这里插入图片描述

1.正常代码
<template>
<div class="example" >hi</div>
</template&gt;
<style scoped&gt;
.example{
color:red;
}
</style>

2.编译后的代码
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>
<style>
.example[data-v-f3f3eg9]{
color:red;
}
</style>

2. scoped渲染规则

1、 给HTML的dom节点添加一个重复data属性唯一标识这个dom 元素
2、在每句css选择器末尾(编译后生成css语句)加一个当前组件data属性选择器(例如:[datav-5558831a])来私有化样式
3、如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性

3. 穿透scoped属性
使用scoped后,尽管实现组件样式的私有化,但在我们实际的项目中,在很多地方使用重复的子组件或其他的样式库时,在个别地方需要微调样式,这个时候不能直接改子组件样式,而且在父组件里的样式又不能渗透到子组件去。

一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以布局的角度出发,调整其子组件根元素的样式。

我们希望 父组件scoped 样式中的一个选择器能够作用得“更深”,影响子组件,可以使用**穿透(>>>、/deep/、::vdeep)**方法,编译后会在相应的选择器后面增加独有的属性;如下

一、编译前
1.没有使用编译器 使用>>>
<style scoped>
.a >>> .b { /* ... */ }
</style>

2.使用编译器 less、Sassscss
<style lang="scss" scoped>
-----------------::v-deep------------
/*用法1*/
.a{
 ::v-deep .b { 
  /* ... */
 }
} 
/*用法2*/
.a ::v-deep .b {
  /* ... */
}

---------------------/deep/---------
/*用法1*/
.a {
 /deep/ .b { 
  /* ... */
 }
} 
/*用法2*/
.a /deep/ .b { 
  /* ... */
 }
</style>

vue-cli3以上版本可以使用/deep/

二、编译后
/*编译后*/
.a[data-v-f3f3eg9] .b { /* ... */ }
</style>

4. 穿透演示
1.父组件App.vue

<template>
    <div class="container">
        <h3 class="title">Hello >Vue</h3>
        <card/>
    <div>
</template>
<script>
import Card from './Card.vue';
export default {
    components: { Card }
}
</script>
<style scoped>
.container { /* ... */ }
.title { /* ... */ }
.card { /* ... */ }
</style>

2.子组件Card.vue

<template>        
    <div class="title">Vue Cli</div>
        <div class="list">
            <div class="item">vue serve</div>
            <div class="item">vue build</div>
        </div>
    </div>
</template>
<style scoped>
    .card { /* ... */ }
    .title { /* ... */ }
    .item { /* ... */ }
</style>

3.编译后

<div data-v-4fe14a3c="" class="container">
    <h3 data-v-4fe14a3c="" class="title">Hello Vue</h3>
    // 子组件
    <div data-v-119ff0e6="" data-v-4fe14a3c="" class="card">
        <div data-v-119ff0e6="" class="title">Vue Cli</div>
        <div data-v-119ff0e6="" class="list">
            <div data-v-119ff0e6="" class="item">vue serve</div>
            <div data-v-119ff0e6="" class="item">vue build</div>
        </div>
    </div>
</div>

//样式
<style>
.card[data-v-119ff0e6] { /* ... */ }
.title[data-v-119ff0e6] { /* ... */ }
.item[data-v-119ff0e6]{ /* ... */ }
.container[data-v-4fe14a3c]{ /* ... */ }
.container .title[data-v-4fe14a3c] { /* ... */ }
.card[data-v-4fe14a3c] { /* ... */ }
</style>

4.在父组件中直接修改子组件中(非最外层)元素的样式

.card .title {
    color: #eee;
}

编译后

<div data-v-7a169200="" class="container">
    <h3 data-v-7a169200="" class="title">Hello Vue</h3>
    <div data-v-119ff0e6="" data-v-7a169200="" class="card">
        <div data-v-119ff0e6="" class="title">Vue Cli</div>
        <div data-v-119ff0e6="" class="list">
            <div data-v-119ff0e6="" class="item">vue serve</div>
            <div data-v-119ff0e6="" class="item">vue build</div>
        </div>
    </div>
</div>

<style>
.card[data-v-119ff0e6] { /* ... */ }
.title[data-v-119ff0e6] { /* ... */ }
.item[data-v-119ff0e6]{ /* ... */ }
.container[data-v-4fe14a3c]{ /* ... */ }
.container .title[data-v-4fe14a3c] { /* ... */ }
.card[data-v-4fe14a3c] { /* ... */ }

.card .title[data-v-7a169200] {
    color: #eee
}
//应该为:
//.card[data-v-dba577b2] .title {
//  color: #eee
//}
</style>

在父组件内编写的样式经编译后都会带上和父组件元素一样的data-v-hashxxxx,只对父组件范围内的元素起作用,触及不到引入的子组件的内部,也就是说无法覆盖子组件的样式。
5.使用穿透

.card >>> .title {
    color: #eee;
}
.container .card >>> .list .item {
    color: #FF6347;
}

6.这次起作用了

<div data-v-dba577b2="" class="container">
    <h3 data-v-dba577b2="" class="title">Hello Vue</h3>
    <div data-v-119ff0e6="" data-v-dba577b2="" class="card">
        <div data-v-119ff0e6="" class="title">Vue Cli</div>
        <div data-v-119ff0e6="" class="list">
            <div data-v-119ff0e6="" class="item">vue serve</div>
            <div data-v-119ff0e6="" class="item">vue build</div>
        </div>
    </div>
</div>

<style>
.card[data-v-119ff0e6] { /* ... */ }
.title[data-v-119ff0e6] { /* ... */ }
.item[data-v-119ff0e6] { /* ... */ }
.container[data-v-dba577b2] { /* ... */ }
.container .title[data-v-dba577b2] { /* ... */ }
.card[data-v-dba577b2] { /* ... */ }

.card[data-v-dba577b2] .title {
    color: #eee
}
.container .card[data-v-dba577b2] .list .item {
    color: tomato
}
</style>

可以看到,使用样式穿透后编译后没有在选择器末尾添加data-v-hashxxxx属性,而是把data-v-hashxxxx添加到了>>>的位置,这样就能够选中子组件中的元素了。

二、问题解

为什么使用>>>不起作用?
因为这个项目使用的scss,所以无法正常解析>>>,所以在父组件没有渗透下去。


为什么我使用了/deep/却没有成功的在手机上将样式修改过来?
用了两个/deep/,一个不编译,阻塞错误

/*错误代码:写了两次/deep */
.pop-content {
  /deep/ .input-wrapper /deep/  .form-item {
      ...
  } 
 }
 //换后在浏览器看到的代码,发现第二个是无法转换的。
 //.pop-content[data-v-b93cf8e0] .input-wrapper /deep/ .form-item {}

/*修改后的代码*/
.pop-content {  
     .input-wrapper /deep/  .form-item {  
    }
  }/*编译转换后的代码*/
 .pop-content .input-wrapper[data-v-b93cf8e0] .form-item 

③随之而来第三问题,我只写一个/deep/的话,我写在哪个位置呢,是不是写在哪都行,它们之间有什么区别
1、/deep/加在那个class之后就在其后面添加相应唯一的data-v属性值。
2、注意应该放在子组件外层,不然没起到穿透组件私有域的作用
3、如果写在父组件整体样式的前面,则父组件里的样式都可以穿透子组件私有域,并且去影响自组件样式。

三、Sass/Scss与Less区别

1、Sass (Syntactically Awesome Stylesheets)是一种动态样式语言,Sass语法属于缩排语法,比css比多出好些功能(如变量嵌套运算,混入(Mixin)、继承颜色处理函数等),更容易阅读。
2、Sass的缩排语法,对于写惯css前端web开发者来说很不直观,也不能将css代码加入到Sass里面,因此Sass语法进行了改良,Sass 3就变成了Scss(Sassy CSS)。SCSS(Sassy CSS)是CSS语法的扩展。这意味着每一个有效的CSS也是一个有效的SCSS语句,与原来的语法兼容,只是用{}取代了原来的缩进
3、Less也是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量,继承,运算函数. Less 既可以在客户端运行 (支持IE 6+, Webkit, Firefox),也可在服务端运行 (借助 Node.js)。

参考链接
https://www.cnblogs.com/songForU/p/11176696.html
https://www.cnblogs.com/wangpenghui522/p/5467560.html

原文地址:https://blog.csdn.net/qq_50577394/article/details/130771831

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_19065.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注