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. JqGrid参考实例

    <div class="gridtable mt5"> <table id="tbList"></table> <di ...

  2. 树莓派安装使用docker

    2019/11/11, 树莓派4B, Raspbian Buster,Docker 19.03.4 摘要:树莓派Raspbian Buster中安装Docker,Dockerfile更改软件源 安装d ...

  3. mvc_第一遍_业务逻辑层和模型

    常用的动态网页对象: 之前我们提到了,使用request对象可以获得和用户请求相关的一系列信息.这一节,我们来看看另外两个常用对象的常规用途. response对象:用于向客户回应.最常用的用法类似于 ...

  4. LATEX 数学公式基本语法

    作者:@houkai本文为作者原创,转载请注明出处:https://www.cnblogs.com/houkai/p/3399646.html TEX 是Donald E. Knuth 编写的一个以排 ...

  5. 题解 POJ 2559【Largest Rectangle in a Histogram】(单调栈)

    题目链接:http://poj.org/problem?id=2559 思路:单调栈 什么是单调栈? 单调栈,顾名思义,就是单调的栈,也就是占中存的东西永远是单调(也就是递增或递减)的 如何实现一个单 ...

  6. maven项目整合SSM配置log4j, 实现控制台打印SQL语句

    在原有项目正常启动的情况下, 实现在控制台打印mapper包下SQL语句. 1.在pom.xml配置文件中添加两个依赖(缺一不可) <!--日志包--> <dependency> ...

  7. vuex简单化理解和安装使用

     1.简单化理解 首先你要明白 vuex 的目的 就是为了 集中化的管理项目中 组件所有的 数据状态 (state) 0. 第一步你要明白 , store 的重要性 , store 类似一个中央基站, ...

  8. redis-启用命令

    一.redis后端启动: 1.将redis源码包中的redis.conf配置文件复制到redis/bin/下 # cd /root/redis-3.0.0 # cp redis.conf /usr/l ...

  9. 机器学习笔记6:K-Means

    目录 目标函数 目标函数的表现函数 针对u和r求解: 最优解的表达式的意义: K-means聚类的形象化展示 聚类前 第一轮循环 第二轮循环 第三轮循环 最终结果 演示代码: 关于K-means的几个 ...

  10. 【转】STM32利用FATFS读写数组

    因为存为TXT可以实现,但是读取TXT里边的数据总是不尽如人意,所以,最终存为bin文件了. 先摘几个观点: http://www.openedv.com/posts/list/36712.htm “ ...