【问题标题】:vue style binding based on object value基于对象值的vue风格绑定
【发布时间】:2021-05-28 05:28:38
【问题描述】:

我正在尝试根据口袋妖怪的类型动态设置元素的样式(例如,火得到一个火图标,火/飞行得到 1 火 1 飞)。

我尝试使用三元运算符和:style 来完成它,但它真的很长而且很乱,所以我不想这样做。目前,我将它设置为一个方法,并传入一个数组,如下所示:

types: ["water", "flying"] //or sometimes just one value eg: types: ['fire']

这是我的方法:

methods: {
    typeStyle: function (types) {
      const backgroundImageUrls = []
      for (const i in types) {
        backgroundImageUrls.push('url(../assets/' + types[i] + '.svg)')
      }
      console.log(backgroundImageUrls)
      let backgroundPosition = 'center'

      if (backgroundImageUrls.length > 1) {
        backgroundPosition = 'left right'
      }

      return {
        backgroundImage: backgroundImageUrls.join(','),
        backgroundPosition
      }
    }
  }

这是调用它的html模板:

<li
class="card"
v-for="(mon, index) in team"
:key="index"
>
  <div class="cardfront-images"
  :style="typeStyle(mon.types)"
  >
...
</li>

但它不起作用。我还想应用第二个效果,background-position,如果有 1 种类型,则使用 background-position: "center",如果有两种,则使用 background-position: "left right"。但由于 CSS 属性中的连字符而出现错误。

编辑

所以我让它在为背景图像制作url() 的地方工作(耶!),但不幸的是,没有应用样式。所以很明显,有些东西不起作用。我还更新了我的代码块以反映更改。

EDIT2:所以这个解决方案确实有效,我已经检查过了。出于某种原因,它不喜欢我的本地资产被字符串字面化,所以我只是从我的 git 存储库中调用图像。我想这已经足够好了,因为我真的只是为了我自己的教育而制作这个。

【问题讨论】:

    标签: javascript html vue.js


    【解决方案1】:

    你可以做的就是把所有的后台URL存储到一个数组中,然后在return语句之前加入这个数组。

    关于background-position属性,请记住在JS中所有CSS属性都是​​kebab case的,因为-会导致JS将其解释为算术运算,所以使用backgroundImage应该是这样做的方法.

    假设types对象数组中每个对象中的url键包含图像的实际路径,您可以这样做。 Note that you should really avoid using arrow functions when defining a Vue method,因为函数中的this 将不再引用组件实例。

    new Vue({
      el: '#app',
      data: function() {
        return {
          team: [{
            ability: "Keen Eye",
            name: "Wingull",
            id: 278,
            types: [{
                type: {
                  name: "water",
                  url: "http://via.placeholder.com/100x100?text=water"
                },
              },
              {
                type: {
                  name: "flying",
                  url: "http://via.placeholder.com/100x100?text=flying"
                }
              }
            ]
          }]
        };
      },
      methods: {
        typeStyle: function(types) {
          // Collect all URLs into an array with the template literal applied so we can use it directly in CSS
          const backgroundImageUrls = types.map(entry => `url(${entry.type.url})`);
    
          // Default value of background-position
          let backgroundPosition = 'center';
    
          if (backgroundImageUrls.length > 1) {
            // Example: you want one image on the top left, and another on the top right
            backgroundPosition = 'top left, top right';
          }
    
          return {
            backgroundImage: backgroundImageUrls.join(','),
            backgroundPosition
          };
        }
      }
    });
    .cardfront-images {
      width: 500px;
      height: 100px;
      background-repeat: no-repeat;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <ul>
        <li class="card" v-for="(mon, index) in team" :key="index">
          {{ mon.ability }}, {{ mon.name }}, {{ mon.id }}
          <div class="cardfront-images" :style="typeStyle(mon.types)"></div>
        </li>
      </ul>
    </div>

    【讨论】:

    • 嗯。我会试试这个。感谢您指出箭头功能的事情。这是其他几个帖子和资源的合并。
    • 我遇到了Uncaught (in promise) TypeError: _ctx.typeStyle is not a function。我尝试将它包装在template 区域的方括号中,但同样的错误(我什至不确定这是一个合适的解决方案)
    • @noscodemos 方括号是什么意思?您是否将函数定义正确复制并粘贴到 methods 对象中?
    • 方括号@:style="[typeStyle(mon.types)]"(已删除),是的。
    • 这不是您应该使用的方式。用您提供的基本数据更新了我的答案,它应该可以工作。
    【解决方案2】:

    有几种不同的方法可以做到这一点:

    对于条件样式,您可以使用动态类,例如:

    <div :class="{ mon.type }"
    

    然后,这将自动获取类型名称(“fire”、“water”等),如果您愿意,可以在其上使用 CSS。

    为了正确呈现图标,您需要对您提供给它的 JSON 对象进行一些调整。

    但为此,我需要知道您是否拥有所有可用信息,或者您将以什么格式获取它。

    当你让我知道时,我会更新我的答案。

    【讨论】:

    • 我从两个来源(粘贴的团队来源和获取 pokedex 编号(此处不相关)和类型的 API 调用)中提取它们并将其组合在一个 store.state.team 数组中,其中包含所有6 个对象(团队中每个口袋妖怪 1 个对象)。
    • 好的,还有更多的工作要做。你能编辑你的帖子以显示一个口袋妖怪的 JSON 对象的结构吗?
    • 我包含了一个简短的例子。
    猜你喜欢
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2021-07-07
    • 2020-11-13
    相关资源
    最近更新 更多