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

javascript - VanillaJS to VueJS Error: bad element for Flickity: carousel - Stack Overflow

programmeradmin1浏览0评论

I'm trying to get this Flickity example (CodePen) to work in a VueJS ponent.

HTML

<div class="carousel">
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
</div>

JS

 var flkty = new Flickity('.carousel');

    flkty.on( 'dragStart', function() {
      console.log('dragStart');
    });

I get this error:

bad element for Flickity: carousel

My not working version:

JS data ()

import Flickity from 'flickity'
var flkty = new Flickity('.carousel')
export default {
  data () {
    return {
      flickityOptions: {
        dragThreshold: 50,
        initialIndex: 1,
        prevNextButtons: false,
        pageDots: false,
        wrapAround: false,
        hash: true,
        percentPosition: false
      },

JS mounted ()

  mounted () {
    flkty.on('dragStart', function () {
      this.stageDragging = true
      console.log('stageDragging: ' + this.stageDragging)
    })
    flkty.on('dragEnd', function () {
      this.stageDragging = false
      console.log('stageDragging: ' + this.stageDragging)
    })

How to use this Flickity example in a VueJS ponent?

I'm trying to get this Flickity example (CodePen) to work in a VueJS ponent.

HTML

<div class="carousel">
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
  <div class="carousel-cell"></div>
</div>

JS

 var flkty = new Flickity('.carousel');

    flkty.on( 'dragStart', function() {
      console.log('dragStart');
    });

I get this error:

bad element for Flickity: carousel

My not working version:

JS data ()

import Flickity from 'flickity'
var flkty = new Flickity('.carousel')
export default {
  data () {
    return {
      flickityOptions: {
        dragThreshold: 50,
        initialIndex: 1,
        prevNextButtons: false,
        pageDots: false,
        wrapAround: false,
        hash: true,
        percentPosition: false
      },

JS mounted ()

  mounted () {
    flkty.on('dragStart', function () {
      this.stageDragging = true
      console.log('stageDragging: ' + this.stageDragging)
    })
    flkty.on('dragEnd', function () {
      this.stageDragging = false
      console.log('stageDragging: ' + this.stageDragging)
    })

How to use this Flickity example in a VueJS ponent?

Share Improve this question asked Feb 1, 2019 at 16:47 TomTom 6,03421 gold badges85 silver badges134 bronze badges 1
  • You would likely need to consider using ref to access the respective element/ponent or at minimum create an instance of Flickity in a lifecycle hook such as mounted() when the element is actually available in the DOM. That being said, there is libraries/ponents made for Vue that use Flickity. – Alexander Staroselsky Commented Feb 1, 2019 at 17:00
Add a ment  | 

3 Answers 3

Reset to default 3

In your <script> section, the JavaScript executes before the template has been rendered in the document, so Flickity wouldn't be able to find .carousel if called outside a hook. Vue instances have a mounted() lifecycle hook that gets called when its template has rendered, which is where you should create the Flickity carousel:

// const flkty = new Flickity(...) // DON'T DO THIS HERE
export default {
  mounted() {
    this.$nextTick(() => {
      const flkty = new Flickity(...)
      // ...
    });
  }
}

Also, instead of passing the .carousel classname to Flickity, pass a ref to the .carousel element in order to avoid grabbing an unexpected .carousel element in the document (e.g., if you had multiple ponent instances).

// template
<div ref="carousel">

// script
new Flickity(this.$refs.carousel)

demo

var app = new Vue({
  el: '#app',
  data() {
    return {
      options: {
        dragThreshold: 50,
        initialIndex: 1,
        prevNextButtons: false,
        pageDots: false,
        wrapAround: false,
        hash: true,
        percentPosition: false,
      },
      itemsCount: 5,
      flkty: null,
    }
  },
  mounted: function () {
    this.flkty = new Flickity(`#${this.$el.id} .carousel`);
    this.flkty.on( 'dragStart', function() {
      console.log('dragStart');
    });
  }
})

Vue.config.devtools = false;
Vue.config.productionTip = false;
* { box-sizing: border-box; }

body { font-family: sans-serif; }

.carousel {
  background: #FAFAFA;
}

.carousel-cell {
  width: 66%;
  height: 200px;
  margin-right: 10px;
  background: #8C8;
  border-radius: 5px;
  counter-increment: carousel-cell;
}

.carousel-cell:before {
  display: block;
  text-align: center;
  content: counter(carousel-cell);
  line-height: 200px;
  font-size: 80px;
  color: white;
}
<link href="https://npmcdn./flickity@2/dist/flickity.css" rel="stylesheet"/>
<script src="https://npmcdn./flickity@2/dist/flickity.pkgd.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="carousel">
    <div v-for="item in itemsCount" class="carousel-cell">{{ item }}</div>
  </div>
</div>

Specific Rails case :

the error Prompt because I had a double time the CDN script tag and JS code on my Javascript/Packs on the same layout.html.erb

<%= javascript_pack_tag 'flickity' %>
<script src="https://unpkg./flickity@2/dist/flickity.pkgd.min.js"></script>
发布评论

评论列表(0)

  1. 暂无评论