vue中用v-html加载html元素及三种方法给v-html元素添加样式(详解)
金蝶云社区-honey缘木鱼
honey缘木鱼
16人赞赏了该文章 3.7万次浏览 未经作者许可,禁止转载编辑于2018年11月20日 11:03:07
summary-icon摘要由AI智能服务提供

本文介绍了在Vue项目中,后台使用富文本编辑器生成的HTML内容如何在前端展示,并遇到图片宽度超出屏幕宽度时如何控制图片大小的问题。通过`v-html`指令可以解析HTML标签并渲染,但遇到样式作用域`scoped`导致无法直接对动态生成的HTML内容中的元素(如`img`)应用样式。文章提出了三种解决方案:移除`scoped`属性、定义两个样式标签(一个带`scoped`一个不带)、使用`>>>`(或`/deep/`、`::v-deep`)穿透`scoped`作用域来应用样式。

在写商城项目,关于图文介绍的商品详情,后台用了富文本,前端接收到的是一个一个html标签的字段,vue如何解析html元素呢?百度一下,很简单,一个v-html标签搞定!


下面以具体的例子介绍如何使用?



introduction: "<ul> ↵ <li>款式:&nbsp;运动休闲鞋</li> ↵</ul> ↵ ↵<p><img src="https://img.alicdn.com/imgextra/i4/454112876/O1CN011X7FY52tnrblYVU_!!454112876.jpg" /><img src="https://img.alicdn.com/imgextra/i3/454112876/O1CN011X7FY3lVnqf4P7L_!!454112876.jpg" /><img src="https://img.alicdn.com/imgextra/i4/454112876/O1CN011X7FY4f4q5RA2Sa_!!454112876.jpg" /><img 

</p> ↵ ↵<p>&nbsp;</p> ↵ ↵<p>&nbsp;</p> ↵ ↵<p>高帮款送增高鞋垫1双/袜子1双/除味香包1包</p> ↵ ↵<p>赠品款式和颜色随机派送</p> ↵"



introduction这个字段就是后台返回html标签元素,用v-html一行代码搞定加载上述html元素展示:


<template>
    <div v-html="goodDetails.introduction" class="introduction">
</template>


屏幕快照 2018-11-19 下午8.18.57.png


但是发现有问题,后台返回图片太大,宽度超过了屏幕宽度时,页面可以滑动,所以我们要控制图片,找到html元素中的img,然后设置img的样式。


<style scoped>
.introduction{ 
   width: 100%; 
   margin-bottom: 3rem; 
  }

.introduction img{
  width: 100%;
  object-fit: fill;
}
</style>


以为容易找到img标签,按照上述就可以改变样式,可是不行,根本找不到对应的img标签。因为scoped属性导致css仅对当前组件生效,而html绑定渲染出的内容可以理解为是子组件的内容,子组件不会被加上对应的属性,所以这样无效。


以下三种方式可以解决:


一、去掉<style scoped>中的scoped


通过scoped属性,可以使得组件之间的样式不互相污染。如果一个项目中的所有style标签全部加上了scoped,相当于实现了样式的模块化。去掉scoped时,发现影响页面布局很大,这种方式不可取。


简单介绍下scoped 的实现原理:


vue中的scoped属性的效果主要通过PostCSS转译实现,如下是转译前的vue代码:


<style scoped>
.example { 
 color: red;
}
</style>
<template>
  <div class="example">你好</div>
</template>


转译后:


<style scoped>
.example[data-v-5556841b] { 
 color: red;
}
</style>
<template>
  <div class="example">你好</div>
</template>


即:PostCSS给一个组件中的所有dom添加了一个独一无二的动态属性,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom,这种做法使得样式只作用于含有该属性的dom——组件内部dom。


二、定义两个style标签,一个含有scoped属性,一个不含有scoped属性


可以这样写样式:


<style scoped>
 .introduction{ 
   width: 100%;  
   margin-bottom: 3rem;
  }
</style>

<style>
  .introduction img{
    width: 100%;
    object-fit: fill;
  }
</style>


不改变原来的基础上,在需要的地方添加一个不含有scoped属性即可!这样可以解决,但是显的代码过于繁琐。


三、通过 >>> 可以使得在使用scoped属性的情况下,穿透scoped,修改其他组件的值


<style scoped>
  外层 >>> 第三方组件 {
        样式
    }
</style>


上述为模板,以此为例的改变样式为:


<style scoped>
.introduction{  
  width: 100%;   
  margin-bottom: 3rem; 
  }
  
.introduction>>> img{
  width: 100%;
  object-fit: fill;
}
</style>


这种方式很容易解决上述的问题,以后在遇到引入第三方样式需要修改时,可以用这种方法完美解决。



本文独发金蝶云社区

图标赞 16
16人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!