vue中的scoped分析以及在element-UI和vux中的应用
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中的应用的更多相关文章
- Element UI table参数中的selectable的使用
Element UI table参数中的selectable的使用中遇到的坑:页面: <el-table-column :selectable='selectable' type="s ...
- vue使用自定义指令v-dialogDrag来控制element ui中el-dialog的拖动缩放,拉伸问题
1 在vue的utils中新建一个dialogDrag.js import Vue from 'vue' Vue.directive('dialogDrag', { bind(el, binding, ...
- element UI实现表格中添加开关控制按钮
我使用的是element ui V1.4.3 如下图是我要实现的效果: <template> <div> <el-button type="text" ...
- vue+element ui 的tab 动态增减,切换时提示用户是否切换
前言:工作中用到 vue+element ui 的前端框架,动态添加 Tab,删除 Tab,切换 Tab 时提示用户是否切换等,发现 element ui 有一个 bug,这里记录一下如何实现.转载 ...
- 封装一个优雅的element ui表格组件
现在做后台系统用vue + elementUI 的越来越多,那element ui的 el-table 组件肯定也离不开.虽然element ui的table组件很好.但是表格和分页是分离的.每次写表 ...
- vue组件样式添加scoped属性之后,无法被父组件修改。或者无法在本组件修改element UI样式
在vue开发中,需要使用scoped属性避免样式的全局干扰,但是这样在父组件中是无法被修改的,不仅如此如果项目中用了UI框架比如element Ui,这个时候在本组件也无法修改样式,因为权重问题.但是 ...
- vue加scoped后无法修改样式(无法修改element UI 样式)
有的时候element提供的默认的样式不能满足项目的需要,就需要我们队标签的样式进行修改,但是发现修改的样式不起作用 第一种方法 原因:scoped 解决方法:去掉scoped 注意:此时该样式会污染 ...
- Vue中的scoped及穿透方法
何为scoped? 在vue文件中的style标签上,有一个特殊的属性:scoped.当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组 ...
- vue中的css作用域、vue中的scoped坑点
一.css作用域 之前一直很困扰css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的.导致在css中需要加上对应模块的html的id/class ...
随机推荐
- 6、VUE指令
1.指令的格式 1.1. 指令的概念 指令是指带有v-前缀的特殊属性,指令的职责是当其表达式的值改变时,相应的将某些行为应用到DOM上. 1.2. 指令必须是html的属性 指令只能以带前缀的html ...
- EF Core 迁移整理
创建迁移 PowerShell Add-Migration InitialCreate 多数据源 Add-Migration InitialCreate -Context MyDbContext -O ...
- 自定义 Windows 右键菜单项
注:本文涉及到注册表操作,不认识请不要随意修改! 右键菜单项储存在注册表 HKEY_CLASSES_ROOT 中,一般各种程序的右键菜单项都可以在此项下面找到: 添加右键菜单项 右键单击 shell, ...
- 原生js数值开根算法
不借助Math函数求开根值 1.二分迭代法求n开根后的值 思路: left=0 right=n mid=(left+right)/2 比较mid^2与n大小 =输出: >改变范围,right=m ...
- C#读写设置修改调整UVC摄像头画面-曝光
有时,我们需要在C#代码中对摄像头的曝光进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的摄像 ...
- 带入gRPC:分布式链路追踪 gRPC + Opentracing + Zipkin
在实际应用中,你做了那么多 Server 端,写了 N 个 RPC 方法.想看看方法的指标,却无处下手? 本文将通过 gRPC + Opentracing + Zipkin 搭建一个分布式链路追踪系统 ...
- 2019 哔哩哔哩java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.哔哩哔哩等公司offer,岗位是Java后端开发,因为发展原因最终选择去了哔哩哔哩,入职一年时间了,也成为了面 ...
- 【转载】C#中AddRange方法往ArrayList集合末尾添加另一个集合
ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,如果需要往一 ...
- vue项目打包采坑
1. vue项目打包采坑 1.1. vue运行报错error:Cannot assign to read only property 'exports' of object '#' 这个错误我是在打包 ...
- win2003下安装python3.4 + pyspider
昨天尝试了在win2003下安装python2.7.这个是文章地址:https://www.cnblogs.com/alpiny/p/11706606.html 但是程序跑了一晚上,发现有一点问题,是 ...