带有Vue 3和TypeScrip的Flickity API [英] Flickity API with Vue 3 and Typescript

查看:33
本文介绍了带有Vue 3和TypeScrip的Flickity API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在我的Vue 3应用程序中使用Flickity,当我使用带有静态单元格的硬编码的HTML旋转木马时,它工作得很好。然而,我需要在运行时以编程方式添加单元格,并且我无法使Flickity API正常工作。

我正在尝试遵循append()示例,但收到错误:

flickity.js?1385:72 Bad element for Flickity: .carousel

运行时在我的检查器中。我尝试遵循herehere的解决方案,但都无法成功运行。它看起来像是由于Flickity库上的打字错误。我还安装了@types/flickity,仅供参考。

我可以做些什么来修复下面的append逻辑?

<template>
        <div class="row">
          <div class="col d-block m-auto payment-option">
            <flickity ref="carousel" :options="flickityOptions">
            </flickity>
          </div>
      </div>
</template>

<script lang="ts">
import {defineComponent} from "vue";
//import Flickity from 'vue-flickity/src/flickity.vue';
import Flickity from 'flickity'
export default defineComponent({
  name: "PageName",
  components: {
    Flickity
  },
  data() {
    return {
      flickityOptions: {
        initialIndex: 3,
        prevNextButtons: false,
        pageDots: true,
        wrapAround: true
      }
    };
  },
  methods: {
    createBankAccountCarousel(flkty: Flickity) {
      flkty.append(this.makeFlickityCell())
    },
    makeFlickityCell() {
      const cell = document.createElement('div');
      cell.className = 'carousel-cell'
      cell.textContent = "Hi"
      return cell
    }
  },
  mounted() {
    let flkty = new Flickity(this.$refs.carousel)
    this.createBankAccountCarousel(flkty)
  }
});
</script>

推荐答案

看起来您可能在第3版中尝试vue-flickity,但that component was built for Vue 2

您可以在Vue 3中创建自己的Flickity组件:

  1. 使用以下模板和脚本创建Flickity.vue,该脚本对根元素应用template ref,并包含slot以接收.carousel-cell元素:

    <template>
      <!-- 👇 template ref -->
      <div ref="root" class="flickity">
        <slot />
      </div>
    </template>
    
    <script lang="ts">
    import { defineComponent, ref } from 'vue'
    
    export default defineComponent({
      setup() {
        const root = ref<HTMLElement | null>(null) // reference to template ref named "root"
        return {
          root,
        }
      }
    })
    </script>
    
  2. 声明一个optionsprop,我们稍后将其传递给Flickity构造函数。

    <script lang="ts">
    import { defineComponent } from 'vue'
    
    export default defineComponent({
      props: {
        options: Object,
      }
    })
    </script>
    
  3. 在组件的mounted hook中,使用"root"模板ref和options道具实例化Flickity;在unmounted中,销毁Flickity实例:

    <script lang="ts">
    import { defineComponent, onMounted, onUnmounted } from 'vue'
    import Flickity from 'flickity'
    
    export default defineComponent({
      setup(props) {
        let flickity: typeof Flickity | null = null
        onMounted(() => flickity = new Flickity(root.value as HTMLElement, props.options))
        onUnmounted(() => flickity?.destroy())
      }
    })
    </script>
    
  4. 添加名为"append"的方法以允许将新元素追加到旋转木马:

    <script lang="ts">
    import { defineComponent } from 'vue'
    import Flickity from 'flickity'
    
    export default defineComponent({
      setup() {
        let flickity: typeof Flickity | null = null
        return {
          append(element: HTMLElement) {
            flickity?.append(element)
            flickity?.select(-1)
          }
        }
      }
    })
    </script>
    
  5. 使用以下类型声明创建src/flickity.d.ts(如果使用VS Code,则必须重新启动IDE才能对这些类型建立索引):

    declare module 'flickity' {
      const Flickity: {
        new (el: string | HTMLElement, options?: Record<string, unknown>): this
        append(element: HTMLElement)
        destroy()
        select(id: string | number)
      }
      export = Flickity
    }
    
  6. 添加以下<style>块,该块引入flickity默认样式,并设置将在插槽中接收的.carousel-cell元素的样式:

    <style scoped>
    @import '~flickity/dist/flickity.css';
    
    .flickity .carousel {
      background: #EEE;
      margin-bottom: 40px;
    }
    /* use ::v-deep to get at slot elements */
    .flickity::v-deep .carousel-cell {
      height: 200px;
      width: 25%;
      margin: 0 10px;
      background: #6C6;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 8px;
    }
    </style>
    

用法示例:

<template>
  <div class="app">
    <flickity ref="flickity" :options="flickityOptions">
      <div class="carousel-cell">1</div>
      <div class="carousel-cell">2</div>
      <div class="carousel-cell">3</div>
    </flickity>
    <div class="actions">
      <button @click="addElement">Append element</button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import Flickity from './components/Flickity.vue'

export default defineComponent({
  name: 'App',
  components: {
    Flickity
  },
  data() {
    return {
      flickityOptions: {
        pageDots: true,
        wrapAround: true,
      }
    }
  },
  methods: {
    addElement() {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      (this.$refs.flickity as any).append(this.makeFlickityCell())
    },
    makeFlickityCell() {
      const cell = document.createElement('div')
      cell.className = 'carousel-cell'
      cell.textContent = 'Hi'
      return cell
    }
  }
})
</script>

<style scoped>
.app {
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  height: 50vh;
}
</style>

demo

这篇关于带有Vue 3和TypeScrip的Flickity API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆