vue使用了单文件组件方式来解耦视图即.vue后缀文件名

单文件组件组成部分:

<template>

</template>

<script>

</script>

<style>

</style>

其中template、script以及实现了私有化

那么style如何实现私有化?

为此vue为style提供了一个scoped属性用于实现样式私有化
    <style scoped>

    </style>

实现样式私有化的原理:

先看一个例子
<style scoped>
.example {
color: red;
}
</style> <template>
<div class="example">hi</div>
</template>

显示结果

<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style> <template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>

从上面两段代码对比可以得知scoped为组件设置一个data-v-id这个全局唯一属性,在对应的样式后面追加了一个属性选择器来唯一确定样式作用对象

属性选择器是一个容易被人遗忘点属性呢

看个简单例子
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.main[data-a]{
height: 300px;
background-color:black;
}
</style>
</head> <body>
<div class="main" data-a>
</div>
</body> </html>

大家会看到背景有300px高度被渲染成黑色的

我们分析一下不同类型组件组合引用的情况的渲染情况

1.一般组件引用私有组件

文件

    //content.vue
<template>
<div class="content">
<p class="title"></p>
<!-- v-button假设是上面定义的组件 -->
<v-button></v-button>
</div>
</template>
...
<style>
.content{
width: 1200px;
margin: 0 auto;
}
.content .button{
border-raduis: 5px;
}
</style>

渲染结果:

<div class="content">
<p class="title"></p>
<!-- v-button假设是上面定义的组件 -->
<div data-v-2311c06a class="button-warp">
<button data-v-2311c06a class="button">text</button>
</div>
</div>
*button.vue渲染出来的css*/
.button-warp[data-v-2311c06a]{
display:inline-block;
}
.button[data-v-2311c06a]{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
/*content.vue渲染出来的css*/
.content{
width: 1200px;
margin: 0 auto;
}
.content .button{
border-raduis: 5px;
}

可以看到,虽然在content组件修改了button的border-radius属性,但是内部组件的样式权重比外部的高,如果想要生效,就需要增加权重

2.私有组件引用私有组件

<div data-v-57bc25a0 class="content">
<p data-v-57bc25a0 class="title"></p>
<!-- v-button假设是上面定义的组件 -->
<div data-v-57bc25a0 data-v-2311c06a class="button-warp">
<button data-v-2311c06a class="button">text</button>
</div>
</div>
    /*button.vue渲染出来的css*/
.button-warp[data-v-2311c06a]{
display:inline-block;
}
.button[data-v-2311c06a]{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
/*content.vue渲染出来的css*/
.content[data-v-57bc25a0]{
width: 1200px;
margin: 0 auto;
}
.content .button[data-v-57bc25a0]{
border-raduis: 5px;
}

可以看出.content .button后面属性选择器里面的自定义属性是content的data-v-id,这样就无法影响到button.vue

<div data-v-57bc25a0 class="content">
<p data-v-57bc25a0 class="title"></p>
<!-- v-button假设是上面定义的组件 -->
<div data-v-57bc25a0 class="button-warp">
<button class="button">text</button>
</div>
</div>
    /*button.vue渲染出来的css*/
.button-warp{
display:inline-block;
}
.button{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
/*content.vue渲染出来的css*/
.content[data-v-57bc25a0]{
width: 1200px;
margin: 0 auto;
}
.content .button[data-v-57bc25a0]{
border-raduis: 5px;
}

这种情况与私有组件引用私有组件类似,出现了属性选择器出现正在选择器表达式点末尾,导致样式无法对子组件内部元素生效

这里可以增加一个不带scoped的style和scoped的style共存,来在普通的style中去全局样式来改变,但是这样也不优雅,为了避免全局污染需要定义好全局样式名称

总结:

1.组件的style加入了scoped后,组件的所有元素都会加一个唯一的data-v-id属性,属性选择会被加入到表达式末尾,同时这个自定义属性会作用到子组件的根元素上

2.因为私有组件会把属性选择器加到CSS表达式末端,导致CSS无法选择到子组件内部元素,所以一个猜想是把属性选择器移至父级选择器末端,而不是表达式末端来实现css样式私有化与样式作用到子元素的效果

第二点总结的vue-loader语法支持

深度选择器:

>>>
    //content.vue
<template>
<div class="content">
<p class="title"></p>
<!-- v-button假设是上面定义的组件 -->
<v-button></v-button>
</div>
</template>
...
<style>
.content{
width: 1200px;
margin: 0 auto;
}
.content >>> .button{
border-raduis: 5px;
}
</style>

上述css渲染结果:

    /*button.vue渲染出来的css*/
.button-warp[data-v-2311c06a]{
display:inline-block;
}
.button[data-v-2311c06a]{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
/*content.vue渲染出来的css*/
.content[data-v-57bc25a0]{
width: 1200px;
margin: 0 auto;
}
.content[data-v-57bc25a0] .button{
border-raduis: 5px;
}

可以看到在表达式中父级结束选择器.content这里使用了深度选择器来实现了属性选择器的移动,达到了修改子组件样式的效果,当然,实际项目中我记得vue-loader 10.x好像是不完全支持>>>,这里就要大家升级一下项目的vue-loader了。

以下附上本人在项目中使用element-UI和vux这两个分别在pc端和手机端受宠的vue框架,我查看了这两者的组件源码,他们都没使用scoped这种方法私有化样式,所以可以采用下面的方法:

1.样式少:

直接在组件上写一个style内联标签

2.样式多

组件上写一个class进行style的集合配置

3.scoped的style修改子组件样式

在子class和父class之间插入一个>>>深度选择器来实现属性选择器的移位

vue中的scoped分析以及在element-UI和vux中的应用的更多相关文章

  1. Element UI table参数中的selectable的使用

    Element UI table参数中的selectable的使用中遇到的坑:页面: <el-table-column :selectable='selectable' type="s ...

  2. vue使用自定义指令v-dialogDrag来控制element ui中el-dialog的拖动缩放,拉伸问题

    1 在vue的utils中新建一个dialogDrag.js import Vue from 'vue' Vue.directive('dialogDrag', { bind(el, binding, ...

  3. element UI实现表格中添加开关控制按钮

    我使用的是element ui V1.4.3 如下图是我要实现的效果: <template> <div> <el-button type="text" ...

  4. vue+element ui 的tab 动态增减,切换时提示用户是否切换

    前言:工作中用到 vue+element ui 的前端框架,动态添加 Tab,删除 Tab,切换 Tab 时提示用户是否切换等,发现 element ui  有一个 bug,这里记录一下如何实现.转载 ...

  5. 封装一个优雅的element ui表格组件

    现在做后台系统用vue + elementUI 的越来越多,那element ui的 el-table 组件肯定也离不开.虽然element ui的table组件很好.但是表格和分页是分离的.每次写表 ...

  6. vue组件样式添加scoped属性之后,无法被父组件修改。或者无法在本组件修改element UI样式

    在vue开发中,需要使用scoped属性避免样式的全局干扰,但是这样在父组件中是无法被修改的,不仅如此如果项目中用了UI框架比如element Ui,这个时候在本组件也无法修改样式,因为权重问题.但是 ...

  7. vue加scoped后无法修改样式(无法修改element UI 样式)

    有的时候element提供的默认的样式不能满足项目的需要,就需要我们队标签的样式进行修改,但是发现修改的样式不起作用 第一种方法 原因:scoped 解决方法:去掉scoped 注意:此时该样式会污染 ...

  8. Vue中的scoped及穿透方法

    何为scoped? 在vue文件中的style标签上,有一个特殊的属性:scoped.当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组 ...

  9. vue中的css作用域、vue中的scoped坑点

    一.css作用域 之前一直很困扰css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的.导致在css中需要加上对应模块的html的id/class ...

随机推荐

  1. 配置两个不同kerberos认证中心的集群间的互信

    两个Hadoop集群开启Kerberos验证后,集群间不能够相互访问,需要实现Kerberos之间的互信,使用Hadoop集群A的客户端访问Hadoop集群B的服务(实质上是使用Kerberos Re ...

  2. Linux环境下:vmware安装Windows报错误-无人参与应答文件包含的产品密钥无效

    最近在安装window server 2012 R2的时候,输入好密钥可以继续安装,但在后面又提示我“无人参与应答文件包含的产品密钥无效.删除无效的密钥或在无人参与应答文件中提供有效的产品密钥继续进行 ...

  3. Java自学-操作符 算数操作符

    Java的算数操作符 算数操作符 基本的有: + - * / % 自增 自减 ++ -- 基本的加 减 乘 除: public class HelloWorld { public static voi ...

  4. iOS - 什么!iOS13 又获取不到WiFi了

    iOS 12 适配WiFi 增加隐私权限 https://www.cnblogs.com/baitongtong/p/10179519.html ios13又新增定位权限 别的不说,理解请看上篇文章 ...

  5. ios、安卓前端兼容性

    1.日期兼容性 解决方法(请看我上一篇文章)安卓.ios时间转换成时间戳的形式 2.input框聚焦,ios出现outline或者阴影,安卓显示正常 解决方法 input:focus{outline: ...

  6. JavaScript 之 Date对象

    Date对象 Date 是一个构造函数,首先要通过 new Date() 来创建实例对象,提供实例成员.  创建 Date 实例用来处理日期和时间.Date 对象基于 1970年1月1日(世界标准时间 ...

  7. 安全SECUERITY英文SECUERITY证券

    security Alternative forms secuerity (mostly obsolete) English Alternative forms secuerity Pronuncia ...

  8. RPC相关知识

    为什么要进行系统拆分,为什么要用dubbo RPC的由来,基本架构,实现原理,整个调用过程经历了哪几步 Java动态代理及 RPC框架介绍 一篇文章了解RPC框架原理 dubbo详解及demo实例 d ...

  9. Android 指定调用已安装的某个“相机”App

    在做项目时,有这样一个需求:如果我的手机中安装了四个相机软件,那么,在调用系统相机的时候,这四个相机软件都会被列出来,但是其中的两个在拍照完后并不能将拍得的照片返回给我,因此,能不能指定开启一个我已知 ...

  10. spec开发思路以及理解

    一.spec说明 描述:编写SEPC采用创联公司自主开发的CIT语言,它是一种过程化的.类似数据库编码的语言.SPEC中除了关键字外提倡使用中文. 理解:可以理解为业务逻辑层.链接前台页面和后台数据库 ...