最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to toggle Vuetify Carousel component rightleft arrows on and off - Stack Overflow

programmeradmin3浏览0评论

I want to dynamically control the visibility of the (<) and (>) arrows in the Vuetify carousel ponent.

For example, so that the final right arrow on the last item disappears, or so that I can use internal buttons or other interactivity within the carousel-item content to replace the buttons dynamically. (I know the continuous prop can do the simple end case).

The documentation for the next-icon and prev-icon prop is bool or string and the default says $next.

Name    next-icon
Type    boolean | string
Default $next
Description Icon used for the "next" button if show-arrows is true

I can make the icon button disappear by setting it to false, but true doesn't make it reappear.

I'm guessing the string value is the icon name (like md-arrow-right?) but the documentation doesn't say what the default is, and that doesn't work. I'm guessing that "off" is setting the prop to false and "on" is restoring it to the icon name.

I also don't understand what $next means, and this isn't explained in the page. It errors if you use that as a value. Everything else seems to evaluate to false.

I'm guessing it's something like this:

<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>

UPDATE

One of my mistakes was md-arrow-right should be mdi-arrow-right (missing the i), or actually mdi-chevron-right as noted by tony19. So I can now set it to a literal icon OK.

But setting it to $next or $prev still doesn't work - it displays either nothing, and empty circle, or a $ sign which is actually the word $next. And this seems to "break" the binding and setting it to a literal icon after this, fails until reloading the page.

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

I want to dynamically control the visibility of the (<) and (>) arrows in the Vuetify carousel ponent.

For example, so that the final right arrow on the last item disappears, or so that I can use internal buttons or other interactivity within the carousel-item content to replace the buttons dynamically. (I know the continuous prop can do the simple end case).

The documentation for the next-icon and prev-icon prop is bool or string and the default says $next.

Name    next-icon
Type    boolean | string
Default $next
Description Icon used for the "next" button if show-arrows is true

I can make the icon button disappear by setting it to false, but true doesn't make it reappear.

I'm guessing the string value is the icon name (like md-arrow-right?) but the documentation doesn't say what the default is, and that doesn't work. I'm guessing that "off" is setting the prop to false and "on" is restoring it to the icon name.

I also don't understand what $next means, and this isn't explained in the page. It errors if you use that as a value. Everything else seems to evaluate to false.

I'm guessing it's something like this:

<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>

UPDATE

One of my mistakes was md-arrow-right should be mdi-arrow-right (missing the i), or actually mdi-chevron-right as noted by tony19. So I can now set it to a literal icon OK.

But setting it to $next or $prev still doesn't work - it displays either nothing, and empty circle, or a $ sign which is actually the word $next. And this seems to "break" the binding and setting it to a literal icon after this, fails until reloading the page.

<i aria-hidden="true" class="v-icon notranslate material-icons theme--light" style="font-size: 36px;">$next</i>
Share Improve this question edited Feb 1, 2020 at 0:24 scipilot asked Jan 31, 2020 at 2:04 scipilotscipilot 7,4972 gold badges52 silver badges75 bronze badges 4
  • 1 I haven't used vuetify in a while but looking through the docs, have you tried setting the prop continuous to false? – Liang-Shih Lin Commented Jan 31, 2020 at 2:52
  • @Liang-ShihLin yes I have, and that does provide the example of turning next off at the end, but I needed more control over them, like when an interactive carousel-item contains a button instead. Perhaps it was a bad example! – scipilot Commented Jan 31, 2020 at 3:16
  • You want just to move next and prev if you press left and right arrow? Am I getting you right? – V. Sambor Commented Jan 31, 2020 at 5:58
  • @V.Sambor No, I want to toggle the visibility/display of the buttons on and off, from within the code depending on which item is displayed (or other rules). – scipilot Commented Jan 31, 2020 at 6:56
Add a ment  | 

4 Answers 4

Reset to default 2

I think that you can achieve the behavior you wanted without relying on documentation if it doesn't provide what you need.

Just inspect the left and right arrow of the carousel ponent and get the DOM Node by selector. Then you are ready to do what you want with the elements.

For exemple:

const nextButton = document.querySelector('.v-window__next button');

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

(Maybe instead of document you can use the $el inside your ponent)

Now you can do whatever you want with your elements.

To show/hide dynamically:

nextButton.style.display = 'None'; // Hide
nextButton.style.display = 'Block'; // Show

To navigate:

nextButton.click(); // Go next.
prevButton.click(); // Go prev.

Vue is just JavaScript at the end, no magic ;)

BTW, you could try this directly in the browser console on the link you provided for the carousel.

The icon visibility should be restored when setting it to $next (as seen in demo code snippet below).

About $next...

For all icons in the framework, Vuetify uses v-icon to render the icon specified by name. Icon names are mapped to an iconset (default is Material Design Icons). The mapped icon names are identified by the $ prefix, and remapped during icon rendering.

For instance, the mdi preset maps $prev to mdi-chevron-left and $next to mdi-chevron-right; and the fa (Font Awesome) preset maps $prev to fas fa-chevron-left and $next to fas fa-chevron-right.

Literal icon names (without the $ prefix) could also be explicitly used. For example, you could specify mdi-arrow-expand-right instead of $next in v-icon.

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./[email protected]/dist/vue.min.js"></script>
<script src="https://unpkg./[email protected]/dist/vuetify.min.js"></script>
<link rel="stylesheet" href="https://unpkg./@mdi/[email protected]/css/materialdesignicons.min.css">
<link rel="stylesheet" href="https://fonts.googleapis./css?family=Roboto:100,300,400,500,700,900|Material+Icons">
<link rel="stylesheet" href="https://unpkg./[email protected]/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>

A simple typo in the icon name:

nextArrow: "md-arrow-right",

should be

nextArrow: "mdi-arrow-right",

I keep making this mistake because I get the icon names by searching https://materialdesignicons./ where the icon names do not have the mdi- prefix and I so often get it wrong when manually adding md- for just material design.

There some ways to have more control over the carousel ponent

To programaticaly control if the arrows will be showed, you can delegate this to a variable

continuous=false will do the job hiding the arrows on the begining/end of the elements list

And to determine wich element will be active, you can use 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(): will change the current active item

showHideArrows(): will toggle the arrow's state

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

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

评论列表(0)

  1. 暂无评论