解决vue scoped html样式无效的问题
作者:西洲 -
1、问题场景
page1,page2都使用flexible移动端自适应的时候,有一个页面page2需要手动设置rem基准值,
//手动设置基准 html{ font-size: 120px !important; }
但是在page2引用的self.less里面设置了基准,竟然没有生效
2、问题分析scoped属性
在引用self.less的时候,使用了属性scoped
vue中引入了scoped这个概念,设计思想就是让当前组件的样式不会修改到其他页面的样式,使用了data-v-hash的方式来使css有了他对应的模块的标识,通俗来说就是使用了scoped属性,template里面的html都会多一个data-v-hash的属性,css 选择器会根据data-v-hash来进行选择,当前的css文件只会对当前的页面生效。参考下图
那么问题来了,scoped只对当前组件里面的内容生效,会对组件里面的dom加data-v-hash属性,而不会对html,body等组件之外的dom添加,但是css里面的属性选择器都是data-v-hash属性的,参考下图,椭圆形里面是组件之外的,没有data-v-hash属性,所以加了scoped属性的css会对组件外无效。长方形里面的dom是组件里面的,data-v-hash跟css里面的data-v-hash是一致的会生效。
虽然css里面的body选择器也添加了data-v-hash,但是页面dom没有data-v-hash属性,所以css里面设置的body样式无效。
3、解决办法
针对必须设置属性scoped的组件,可以在page2.vue里面再单独写一个style,在页面里面单独写组件之外(html,body等)的样式,因为scoped不会对组件之外的dom增加data-v-hash属性
但是新问题来了,page2设置以后,影响了page1页面的布局,page1页面html的的font-size样式依然是120px,
当然会影响啊,page2也引用了page1的样式啊,但是page2设置了scoped,所以只有page2的html样式会影响page1,
解决办法就是再vue什么周期create里面,用js给html设置font-size
4、总结
遇到了这问题,终于搞明白了scoped染渲染规则,在添加了scoped属性的组件
给组件(template)里面的dom节点,加了一共不重复属性的data-v-hash,来标志唯一性
给组件里面引用的的样式文件,在每个选择器后面添加了一个等同于dom节点一样的data-v-hash字段,实现类似于作用域的问题,不影响全局
如果组件里面还有组件,只会给最外层的组件里面dom,添加data-v-hash,不会影响组件内部引用的组件
补充知识:vue中scoped慎用
scoped表示当前style属性只属于当前模块
实现原理:
vue通过在DOM结构以及css样式上加上唯一的标记 data-v-469af010,保证唯一,
问题:
1.父组件无scoped属性,子组件带有scoped,父组件是无法操作子组件的样式的(原因在原理中可知),虽然我们可以在全局中通过该类标签的标签选择器设置样式,但会影响到其他组件
2.父组件有scoped属性,子组件无,父组件也无法设置子组件样式,因为父组件的所有标签都会带有data-v-469af010唯一标志,但子组件不会带有这个唯一标志属性,与1同理,虽然我们可以在全局中通过该类标签的标签选择器设置样式,但会影响到其他组件
3.父子组建都有,同理也无法设置样式,更改起来增加代码量
因此如果组件内部还有组件,只会给最外层的组件里的标签加上唯一属性字段,不影响组件内部引用的组件( 注意 )
方案:
1.混合使用全局属性和局部属性
<style> /* global styles */ </style> <style scoped> /* local styles */ </style>
2.深选择器
<template> <div id="app"> <gHeader></gHeader> </div> </template> <style lang="css" scoped> .gHeader /deep/ .name{ //第一种写法 color:red; } .gHeader >>> .name{ //二种写法 color:red; } </style>
以上这篇解决vue scoped html样式无效的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。