v-html的问题及解决办法1、v-html和v-text(简写:{{}})相⽐,可以识别字符串中的标签
data() {js获取子元素
return { html1: '<p>HTML1</p>' }
}
<p v-html="html1"></p>
<p v-text="html1"></p>
<p>{{html1}}</p>
结果:
2、v-html会覆盖当前标签内的⼦元素
<div v-html="html1">
<h1>标题</h1>
</div>
结果:
3、样式问题
scoped的样式不会应⽤在v-html内部,因为v-html的内容没有经过vue的模板编译器处理
解决办法:
①使⽤scoped时⽤深度选择器(>>>),scss和less使⽤ /deep/
data() {
return { html1: '<p class="my-p">HTML1</p>' }
}
<div v-html="html1"></div>
<style lang="less" scoped>
#app {
/deep/ .my-p {
color: red;
}
}
</style>
②不使⽤scoped,另写⼀个style标签针对全局样式,这⾥要使⽤BEM命名规则
<style lang='less'>
#app {
.my-p {
font-size: 30px;
}
}
</style>
4、XSS
data() {
return {
test: `<a onclick="alert('攻击你')">连接</a>`,
message: `hello vue<img src="xx" onerror="alert('这⾥也可以攻击你')">`
}
}
<div v-html="test"></div>
<div v-html="message"></div>
当图⽚加载错误时:
点击【连接】时:
如何解决:
①安装xss插件:npm i xss
②main.js中引⼊
import xss from 'xss'
Vue.prototype.xss = xss
③fig.js
chainWebpack: (config) => {
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap((options) => {
optionspilerOptions.directives = {
html(node, directiveMeta) {
;(node.props || (node.props = [])).push({
name: 'innerHTML',
value: `xss(_s(${directiveMeta.value}))`
})
}
}
return options
})
},
④重启后这些事件就没了
⑤vue官⽹强调了永远不要让⽤户输⼊的内容通过v-html渲染出来!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论