如何从Vue组件内的标签中删除属性?

时间:2017-12-21 16:30:14

标签: vue.js babeljs

我想使用Soru01 Soru02 属性(如建议here),因此在运行测试时我可以使用这些属性引用标记。

data-test

将使用以下内容找到该元素:

  <template>
    <div class="card-deck" data-test="container">content</div>
  </template>

但我不希望这些document.querySelector('[data-test="container"]') // and not using: document.querySelector('.card-deck') 属性进入生产阶段,我需要删除它们。我怎样才能做到这一点? (有babel plugins这样做可以做出反应。)

谢谢!

2 个答案:

答案 0 :(得分:3)

Linus Borgthread提供的解决方案(对于Nuxt.js项目)是:

// nuxt.config.js
module.exports = {
  // ...
  build:   {
    // ...
    extend(config, ctx) {
      // ...
      const vueLoader = config.module.rules.find(rule => rule.loader === 'vue-loader')
      vueLoader.options.compilerModules = [{
        preTransformNode(astEl) {
          if (!ctx.dev) {
            const {attrsMap, attrsList} = astEl
            tagAttributesForTesting.forEach((attribute) => {
              if (attrsMap[attribute]) {
                delete attrsMap[attribute]
                const index = attrsList.findIndex(x => x.name === attribute)
                attrsList.splice(index, 1)
              }
            })
          }
          return astEl
        },
      }]
    }
  }
}

其中tagAttributesForTesting是一个包含要删除的所有属性的数组,例如:["data-test", ":data-test", "v-bind:data-test"]

答案 1 :(得分:0)

对于那些想知道如何做到这一点的人来说,这是 vanilla Vue 3,请继续阅读。

根据 Vue CLI documentation,覆盖加载器选项的正确方法是在您的 Vue 配置中(在您的 chainWebpack 文件中)使用 vue.config.js 方法:

module.exports = {
  chainWebpack(config) {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap((options) => {
        options.compilerOptions.modules = [{
          preTransformNode(element) {
            if (process.env.NODE_ENV !== 'production') return

            const { attrsMap, attrsList } = element;

            if ('data-test' in attrsMap) {
              delete attrsMap[attribute];

              const index = attrsList.findIndex(x => x.name === attribute);
              attrsList.splice(index, 1)
            }

            return element;
          }
        }];

        return options;
      });
  }
};

对于您的特定用例,我认为最免维护的选择是使用模式匹配策略来删除测试属性。这将使您不必将每个新的测试属性添加到列入黑名单的属性列表中:

{
  preTransformNode(element) {
    if (process.env.NODE_ENV !== 'production') return

    const { attrsMap, attrsList } = element;

    for (const attribute in attrsMap) {
      // For example, you could add a unique prefix to all of your test
      // attributes (e.g. "data-test-***") and then check for that prefix
      // using a Regular Expression
      if (/^data-test/.test(attribute)) {
        delete attrsMap[attribute];

        const index = attrsList.findIndex(x => x.name === attribute);
        attrsList.splice(index, 1)
      }
    }

    return element;
  }
}

请注意,属性包含您附加到它们的任何 Vue 指令(例如“v-bind:”),因此如果您决定使用唯一前缀。

我认为最好提一下,就像我之前的@ahwo 一样,我从 Vue 论坛上的 Linus Borg's suggestion 中汲取灵感。

附言使用 Vue,可以创建具有 dynamic names 的属性。我认为这对于为测试添加属性的任何人来说都是有用的