如何在Vuetify轮播组件中切换右/左箭头的开/关状态

4
我想动态控制Vuetify 走马灯组件中的(<)(>)箭头的可见性。

例如,使最后一个项目上的最后一个右箭头消失,或者在carousel-item内容内部使用内部按钮或其他互动方式动态替换这些按钮。(我知道continuous属性可以处理简单的结束场景)。 next-iconprev-icon属性的文档是boolstring类型,其默认值为$next
Name    next-icon
Type    boolean | string
Default $next
Description Icon used for the "next" button if show-arrows is true

我可以通过将其设置为false来使图标按钮消失,但是true不能使其重新出现。

我猜测字符串值是图标名称(例如md-arrow-right?),但文档没有说明默认值是什么,而且那样也不起作用。我猜想“off”将属性设置为false,“on”将其恢复为图标名称。

我还不理解$next的含义,而这在页面上没有解释。如果您将其用作值,则会出错。其他所有内容似乎都计算为false。

我猜它应该是这样的:

<template>
  <v-carousel v-model="stepNo" :show-arrows="show.arrows" :next-icon="show.nextArrow" height="auto" light>
  <!-- ... -->
</template>

<script>
export default {
  data: () => {
    return {
      stepNo: 0,
      show: {
        arrows: true,
        nextArrow: "md-arrow-right",
      },
    }
  },
  watch: {
    stepNo: function(newStep, oldStep) {
      // some logic here, for example
      this.nextArrow = (newStep === 4) ? "md-arrow-right" : false;
    },
  },
  //...
}
</script>

更新

我的一个错误是将md-arrow-right写成了mdi-arrow-right(缺少字母),或者实际上应该是mdi-chevron-right,正如tony19所指出的那样。所以现在我可以将它设置为文字图标。

但是将其设置为$next$prev仍然不起作用-它要么显示为空,要么显示一个空圆圈,要么显示一个$符号,而这实际上是单词$next。而且这似乎“破坏”了绑定,直到重新加载页面后将其设置为文本图标才能成功。

<i aria-hidden="true" class="v-icon notranslate material-icons theme--light" style="font-size: 36px;">$next</i>

1
我已经有一段时间没有使用Vuetify了,但是通过查看文档,您是否尝试将属性continuous设置为false - Liang-Shih Lin
@Liang-ShihLin 是的,我看过了,它提供了在结尾处关闭下一个示例,但是我需要更多对它们的控制,例如当交互式旋转木马项包含按钮时。也许这是个不好的例子! - scipilot
你的意思是,如果按左右箭头,只想移动到下一个或上一个吗?我理解得对吗? - V. Sambor
@V.Sambor 不,我想要在代码内根据显示的项目(或其他规则)切换按钮的可见性/显示。 - scipilot
4个回答

2
我认为如果文档无法提供所需内容,您可以在不依赖文档的情况下实现所需行为。
只需检查轮播组件的左右箭头并通过选择器获取DOM节点,然后您就可以根据需要对元素进行操作。
例如:
const nextButton = document.querySelector('.v-window__next button');

const prevButton = document.querySelector('.v-window__prev button');

也许你可以在组件内部使用 $el,而不是 document。
现在你可以对元素进行任何操作。
动态地显示/隐藏元素:
nextButton.style.display = 'None'; // Hide
nextButton.style.display = 'Block'; // Show

要进行导航:
nextButton.click(); // Go next.
prevButton.click(); // Go prev.

“Vue”最终只是“JavaScript”,没有任何魔法 ;)
顺便说一下,您可以直接在您提供的旋转木马链接中尝试此方法。

是的,你说得对。这是我多年来一直在做的事情,无论是原生还是Prototype、JQuery、Dojo等等!但是我正在努力成为一个好孩子,不想在幕后进行黑客攻击,并希望正确使用Vue/Vuetify的API。我担心如果他们在下一个版本中更改选择器或DOM结构,这种方法可能会出现问题。 - scipilot
没错!但只要他们没有提供方法,你就得等待他们实现,或者自己做出贡献,或者像这样做事情,而且你必须为未来维护它... :-| - V. Sambor
1
在Vue中进行DOM操作是不被推荐的,因为当Vue组件重新渲染时,这些更改可能会被撤销。 - tony19

1

在将图标设置为$next时,应恢复图标的可见性(如下面演示代码片段所示)。

关于$next...

对于框架中的所有图标,Vuetify使用v-icon来渲染指定名称的图标。图标名称映射到一个图标集(默认为Material Design Icons)。映射的图标名称由$前缀标识,并在图标渲染期间重新映射

例如,mdi 预设将 $prev 映射为 mdi-chevron-left,将 $next 映射为 mdi-chevron-right;而 fa(Font Awesome)预设将 $prev 映射为 fas fa-chevron-left,将 $next 映射为 fas fa-chevron-right
文字图标名称(不带$前缀)也可以明确使用。例如,在v-icon中,您可以指定mdi-arrow-expand-right而不是$next

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      nextIcon: '$next',
      prevIcon: '$prev',
      nextIconEnabled: true,
      prevIconEnabled: true,
      colors: [
        'indigo',
        'warning',
        'pink darken-2',
        'red lighten-1',
        'deep-purple accent-4',
      ],
      slides: [
        'First',
        'Second',
        'Third',
        'Fourth',
        'Fifth',
      ],
    }
  },
  watch: {
    nextIconEnabled(nextIconEnabled) {
      if (nextIconEnabled) {
        this.nextIcon = this._lastNextIcon
      } else {
        this._lastNextIcon = this.nextIcon
        this.nextIcon = false
      }
    },
    prevIconEnabled(prevIconEnabled) {
      if (prevIconEnabled) {
        this.prevIcon = this._lastPrevIcon
      } else {
        this._lastPrevIcon = this.prevIcon
        this.prevIcon = false
      }
    }
  }
})
.controls {
  display: flex;
  flex-direction: column;
}
<script src="https://unpkg.com/vue@2.6.11/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuetify@2.2.8/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@mdi/font@4.x/css/materialdesignicons.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons">
<link rel="stylesheet" href="https://unpkg.com/vuetify@2.2.8/dist/vuetify.min.css">


<div id="app">
  <v-app id="inspire">
    <div class="controls">
      <label>Toggle next-icon
        <input type="checkbox" v-model="nextIconEnabled">
      </label>
      <label>next-icon:
        <input v-model="nextIcon" placeholder="icon name"/>
      </label>
      <label>Toggle prev-icon
        <input type="checkbox" v-model="prevIconEnabled">
      </label>
      <label>prev-icon:
        <input v-model="prevIcon" placeholder="icon name"/>
      </label>
    </div>
    <v-carousel
      height="400"
      hide-delimiter-background
      :prev-icon="prevIcon"
      :next-icon="nextIcon"
    >
      <v-carousel-item
        v-for="(slide, i) in slides"
        :key="i"
      >
        <v-sheet
          :color="colors[i]"
          height="100%"
        >
          <v-row
            class="fill-height"
            align="center"
            justify="center"
          >
            <div class="display-3">{{ slide }} Slide</div>
          </v-row>
        </v-sheet>
      </v-carousel-item>
    </v-carousel>
  </v-app>
</div>


好的,我走在正确的轨道上 - 我的代码应该是可以工作的,所以这是一个错误而不是缺少功能。当我设置下一个图标为"$prev"或"$next"和"md-arrow-right"时,我得到一个空圆圈,或者一个带有大美元符号的圆圈。 - scipilot
抱歉,我刚意识到在格式化问题时我错过了将:next-icon属性绑定到show.nextArrow。现在已经更新了。但我会进行调试,现在我知道它应该可以工作了。 - scipilot
请问除了查看代码之外,您能否解释一下我应该在哪里找到$next映射的相关信息?这样我就知道将来从哪里获取信息了。 - scipilot
Vuetify文档中关于图标使用的部分直接引导您查看代码以确定映射。请参阅用法段落的最后一行:“有关更多信息,请查看默认的图标预设值。”我不知道还有其他的参考资料。 - tony19
好的,谢谢,我现在明白了。但是即使我读了这个,我也不认为我会将其与$prev联系起来,因为美元符号的添加或含义没有在任何地方解释。当我阅读轮播时,我没有考虑阅读图标文档。将来我会更加努力地思考子组件。 - scipilot

0

图标名称中的一个简单的拼写错误:

nextArrow: "md-arrow-right",

应该是

nextArrow: "mdi-arrow-right",

我一直犯这个错误,因为我通过搜索https://materialdesignicons.com/获取图标名称,而这些图标名称没有mdi-前缀,所以当我手动添加md-时,经常会出错。

0

有一些方法可以更好地控制轮播组件

要通过编程的方式控制箭头是否显示,您可以将其委托给一个变量

continuous=false将在元素列表的开头/结尾隐藏箭头

而要确定哪个元素将处于活动状态,您可以使用v-model

    <v-carousel
      :show-arrows=arrows
      :progress=false
      :continuous=false
      v-model="item"
      hide-delimiter-background
    >
      <v-carousel-item
        v-for="n in 15"
        :key="n"
      >
      <v-card>
            {{item}}
          <v-btn
            text
            @click="nextItem"
          >
            Next Item
          </v-btn>

          <v-btn
            text
            @click="showHideArrows"
          >
            showHideArrows
          </v-btn>

        </v-card>
      </v-carousel-item>
    </v-carousel>

nextItem(): 将更改当前活动项

showHideArrows(): 将切换箭头状态

   data: () => ({
      arrows: false,
      item: 0,
    }),

  methods: {
    nextItem() {
      console.log('next');
      this.item += 1;
    },
    showHideArrows() {
      this.arrows = !this.arrows;
      console.log(this.arrows);
    },
  },

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接