一、理解:

1.可能会导致 xss 攻击。比如用v-html一定要保证你的内容是可以依赖的,例:

<input type="text" v-model="msg"/>
<div v-html="msg"></div>
// 因为用户输入的信息不可信,这样输入什么就会放入什么,v-html就相当于一个innerHTML

2.v-html 会替换掉标签内部的子元素 

二、原理

    let template = require('vue-template-compiler');
    let r = template.compile(`<div v-html="'<span>hello</span>'"></div>`)
    // 编译后,domProps就是一个innerHTML
    with(this){
        return _c('div',{domProps: {"innerHTML":_s('<span>hello</span>')}})
    }

 // _c 定义在core/instance/render.js

 // _s 定义在core/instance/render-helpers/index,js

三、源码

文件位置:src/platforms/web/runtiem/models/dom-props.js

function updateDOMProps (oldVnode: VNodeWithData, vnode: VNodeWithData) {
  for (key in props) {
    cur = props[key]
    // 如果key是textContent或者innerHTML是会将vnode的子节点都变成空
    if (key === 'textContent' || key === 'innerHTML') {
      if (vnode.children) vnode.children.length = 0
      if (cur === oldProps[key]) continue
      if (elm.childNodes.length === 1) {
        elm.removeChild(elm.childNodes[0])
      }
    }

    if (key === 'value' && elm.tagName !== 'PROGRESS') {
    } else if (key === 'innerHTML' && isSVG(elm.tagName) && isUndef(elm.innerHTML)) {
    } else if (
      cur !== oldProps[key]
    ) {
      try {
        elm[key] = cur // 最终elm的key会被这个值覆盖
      } catch (e) {}
    }
  }
}

 

Logo

前往低代码交流专区

更多推荐