【问题标题】:Set CSS class dynamically without template无需模板即可动态设置 CSS 类
【发布时间】:2021-05-10 11:13:08
【问题描述】:

对于前缀为mycomponent- 的每个组件,我想添加一个带有组件名称的类。我不想为了做到这一点而修改组件。

我的第一个想法是使用 mixins 并以某种方式在 beforeCreate 中添加类,但我没有设法在不使用模板的情况下动态添加类。

我必须在beforeUpdate 中使用$el.classList.add(this.$options.name) 或类似名称吗?有更多 Vue 风格的方法吗?

【问题讨论】:

    标签: vue.js vuejs2


    【解决方案1】:

    就在这里,封装成插件:

    const addComponentNameAsClass = {
      install(Vue, options) {
        const fn = Vue.prototype.$mount;
        Vue.prototype.$mount = function() {
          fn.apply(this, arguments);
          if (this.$options._componentTag?.startsWith("mycomponent-")) {
            this.$el.classList.add(this.$options._componentTag);
          }
        }
      }
    }
    
    Vue.use(addComponentNameAsClass);
    
    // that's all you need
    // see it working:
    
    ['a', 'b', 'foo', 'whatever'].forEach(type => {
      Vue.component('mycomponent-' + type, {
        template: '<div><slot /></div>'
      })
    });
    
    new Vue({
      el: '#app'
    })
    [class^="mycomponent-"] {
      border: 1px solid;
      margin-bottom: 4px;
      padding: 1rem;
    }
    
    .mycomponent-a {
      border-color: red;
    }
    
    .mycomponent-b {
      border-color: blue;
    }
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <div id="app">
      <mycomponent-a>I should get a red border.</mycomponent-a>
      <mycomponent-b>I should get a blue one.</mycomponent-b>
      <mycomponent-foo>bar</mycomponent-foo>
      <mycomponent-whatever>Meh.</mycomponent-whatever>
    </div>

    注意事项:

    • 你不应该期望这可以在 Vue3 上工作。为什么?因为每当您使用以_ 开头的内部道具时,Vue 并不能保证它们在下一个主要版本更新中仍然存在。但是,另一方面,组件的 name 不会保存在其他任何地方($options._componentTag 除外)。
    • 如果您将组件用作&lt;MycomponentA&gt;&lt;/MycomponentA&gt;,上述方法将不起作用。但是,您可以通过辅助函数运行$options._componentTag 的值来快速绕过它(例如:lodash 中的kebabCase)。
      • 注意事项:如果您希望添加的类始终为kebab-case,您将运行通过kebabCase 传递给.classList.add() 的值,以及)。否则,&lt;MycomponentA&gt; 将添加 MycomponentA 类,&lt;mycomponent-a&gt; 将添加 mycomponent-a 类,原因很明显。

    参考。 “Vue 风格”:无论应用这个 “组件” 类的最终目标是什么,它都有可能实现得更干净。
    将类命名为组件类型的想法根本不像 Vue。
    感觉是 WordPress 风格和 Angular 风格。至少对我来说。

    【讨论】:

    • 您的示例有效,但是当我尝试将解决方案集成到我的项目中时,我遇到了问题。不确定其他一些库(可能是 Vuetify)是否使用相同的方法重写 $mount 并导致一些冲突。
    • 我找到了解决办法。如果被覆盖的 $mount() 函数从 fn.apply(this, arguments); 返回值一切都按预期进行!
    猜你喜欢
    • 2012-08-21
    • 2017-09-16
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 2012-08-28
    • 2021-08-25
    • 1970-01-01
    • 2017-05-31
    相关资源
    最近更新 更多