vue中的css作用域

555 阅读5分钟

最近在做vue项目的时候碰到一个问题,使用js动态新增Dom的时候部分样式不生效,绑定的事件也不生效。

静态html:

<span class="el-tag el-tag--info">
                                    <span class="el-select-item-text" id="2">土豆泥</span>
                                    <i class="el-close-tag el-icon-close" @click="deleteItem(2)"></i>
                                </span>

动态生成代码:

this.innerHTML += `<span class="el-tag el-tag--info">
                                    <span class="el-select-item-text" id="${obj.id}">${obj.label}</span>
                                    <i class="el-close-tag el-icon-close" @click="deleteItem(${obj.id})"></i>
                                </span>`

土豆泥标签是写死的,另一个标签是js新增的,可以看到大部分样式是一致的,只是删除按钮不一致。

现在把图贴上来后自己马上反应过来事件不生效的原因了,@clickVue语法,只会在打包的时候解析一次,程序运行过程中新增的vue语法肯定就无法被正确解析了。

<style type="text/css">
.page[data-v-a1796016] {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
      flex-direction: column;
  background: #eff4f3;
  height: 100%;
  position: relative;
  font-size: 14px;
}
.page .page-title[data-v-a1796016] {
    background: url(data:image/png;base64,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) no-repeat;
    background-size: 40px 40px;
}
.page .page-content[data-v-a1796016] {
    background: white;
    height: 100%;
    margin: 24px;
    -ms-flex: 1;
        flex: 1;
    padding-bottom: 24px;
}
.page .page-content .info-body[data-v-a1796016] {
      padding-left: 53px;
      border-bottom: 1px solid #EAF0F4;
      padding-bottom: 20px;
}
.page .page-content .info-body[data-v-a1796016]:last-child {
        border-bottom: none;
}
.page .page-content .info-body .el-row .el-col[data-v-a1796016] {
        padding: 8px 0;
        color: #333;
}
.page .page-content .info-body .el-row .col-border[data-v-a1796016] {
        color: #666;
}
.page .page-content .info-body .el-row .col-qr[data-v-a1796016] {
        padding: 0;
}
.page .page-content .info-body .el-row .col-qr .qr-img[data-v-a1796016] {
          width: 24px;
          height: 24px;
}
.page .downloadImg[data-v-a1796016] {
    display: inline-block;
    width: 120px;
    height: 34px;
    border-radius: 2px;
    line-height: 34px;
}
header[data-v-a1796016] {
  vertical-align: middle;
  height: 96px;
  padding: 12px 32px 0 32px;
  background: #fff;
}
header p[data-v-a1796016] {
  font-size: 14px;
  font-family: PingFangSC-Regular;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.65);
  line-height: 22px;
}
header p[data-v-a1796016]:nth-child(2) {
  font-size: 20px;
  font-family: PingFangSC-Medium;
  font-weight: bolder;
  color: rgba(0, 0, 0, 0.85);
  line-height: 28px;
}
.select-tree input[data-v-a1796016] {
  border: 0px solid;
}
.el-close-tag[data-v-a1796016] {
  color: #909399;
  background: #c0c4cc;
  border-radius: 50%;
}
.setOtherUsersTable .el-dialog[data-v-a1796016] {
  width: 75%;
}
</style>

可以看到页面的最后一个样式标签就是写在组件里的样式(vue通过在DOM结构以及css样式上加唯一不重复的标记,以保证唯一,达到样式私有化模块化的目的。加了scope属性打包后就会有[data-v-hash标记)。但我们在代码中js自动生成的元素显然没有data-v-hash属性,所以部分本模块私有样式没有呈现出来。