Utilisez Isotope (isotope) pour filtrer et trier les artefacts de mise en page magiques dans les projets Vue2 ou Vue3, exclusivement mis en œuvre sur l'ensemble du réseau !

avant-propos

Isotope est une bibliothèque JavaScript pour la disposition de la grille qui vous aide à créer de belles dispositions de grille dynamiques. Isotope prend en charge les effets de filtrage, de tri et d'animation, ce qui peut rendre votre site Web plus vivant et intéressant. À l'heure actuelle, non seulement JQuery prend en charge Isotope, mais également des frameworks tels que Vue, React et Angular l'ont encapsulé et transformé en composants, ce qui est pratique pour importer des projets et les utiliser. Cependant, avec la mise à niveau des versions de framework telles que Vue, bon nombre de ces composants n'ont pas continué à être mis à jour et ne prennent pas en charge les frameworks frontaux de haute version. C'est-à-dire que lorsque des composants introduits il y a de nombreuses années sont introduits dans le projet du framework frontal haute version, plus ou moins d'erreurs seront signalées et il sera inutilisable. Par conséquent, UP réalise ici comment utiliser l'artefact Isotope (isotope) dans le projet Vue2 ou Vue3, qui est assez simple et exclusivement implémenté sur l'ensemble du réseau.

Isotope官网:Isotope · Filtrer et trier les mises en page magiques

1. Exemple de code

1. Méthode d'écriture Vue2.X

(1)/src/views/Example/Isotope/index_vue2.vue

<template>
  <div class="isotope_container">
    <div class="isotope_filter_navbar">
      <span data-filter="*" class="actived">All</span>
      <span data-filter=".Vue">Vue</span>
      <span data-filter=".React">React</span>
      <span data-filter=".Angular">Angular</span>
    </div>

    <div class="isotope_filter_grid">
      <div class="isotope_filter_grid_item Vue">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 1</h1>
      </div>
      <div class="isotope_filter_grid_item Vue">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 2</h1>
      </div>
      <div class="isotope_filter_grid_item Vue React">
        <img src="/images/404.png" alt="" /> 
        <h1>HelloWorld! 3</h1>
      </div>
      <div class="isotope_filter_grid_item Vue React">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 4</h1>
      </div>
      <div class="isotope_filter_grid_item React">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 5</h1>
      </div>
      <div class="isotope_filter_grid_item React">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 6</h1>
      </div>
      <div class="isotope_filter_grid_item Angular">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 7</h1>
      </div>
      <div class="isotope_filter_grid_item Angular">
        <img src="/images/404.png" alt="" />
        <h1>HelloWorld! 8</h1>
      </div>
    </div>
  </div>
</template>

<script>
import Isotope from 'isotope-layout'

export default {
  data() {
    return {
      // ...
    }
  },
  mounted() {
    this.handleInitIsotope()
  },
  methods: {
    /**
     * 初始化 Isotope 组件
     */
    async handleInitIsotope() {
      // 1.获取 isotope 导航条
      const navbar = await document.querySelector('.isotope_filter_navbar')

      // 2.实例化 isotope 对象
      const isotope = await new Isotope(
        '.isotope_filter_grid', // 容器
        {
          layoutMode: 'fitRows', // 布局模式
          itemSelector: '.isotope_filter_grid_item', // 元素
        }
      )

      // 3.为导航条注册点击事件
      navbar.addEventListener('click', (e) => {
        const { target } = e
        const filterOption = target.getAttribute('data-filter') // 筛选的类别
        if (filterOption) {
          // 给元素移除 actived 样式
          navbar
            .querySelectorAll('span')
            .forEach(
              (btn) => btn.classList.remove('actived')
            )

          // 给目标元素加上 actived 样式
          target.classList.add('actived')

          // 筛选
          isotope.arrange({ filter: filterOption })
        }
      })
    },
  },
}
</script>

<style lang="less" scoped>
.isotope_container {
  position: relative;

  .isotope_filter_navbar {
    display: flex;
    align-items: center;
    padding: 20px 20px 10px 20px;

    span {
      display: inline-block;
      color: #999999;
      font-family: gotham-book;
      font-size: 24px;
      font-weight: bold;
      text-transform: uppercase;
      margin: 0px 30px 0 0;
      text-decoration: none;
      transition: all 0.4s ease-in-out;
      text-transform: capitalize; // 首字母大写
      cursor: pointer;

      &.actived {
        color: #000;
      }

      &:hover {
        color: #000;
      }
    }
  }

  .isotope_filter_grid {

    .isotope_filter_grid_item {
      display: flex;
      width: 25vw;
      height: 20vw;

      img {
        display: block;
        flex: 1;
        margin: 20px;
        object-fit: cover;
        background-color: #000;
      }

      h1 {
        display: grid;
        align-items: center;
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        margin: auto;
        color: #fff;
        font-weight: lighter;
      }
    }
  }
}
</style>

2. Méthode d'écriture Vue3.X

(1)/src/views/Example/Isotope/index_vue3.vue

<template>
  <div class="isotope_container">
    <div class="isotope_filter_navbar">
      <span data-filter="*" class="actived">All</span>
      <span data-filter=".Vue">Vue</span>
      <span data-filter=".React">React</span>
      <span data-filter=".Angular">Angular</span>
    </div>

    <div class="isotope_filter_grid">
      <div class="isotope_filter_grid_item Vue">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 1</h1>
      </div>
      <div class="isotope_filter_grid_item Vue">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 2</h1>
      </div>
      <div class="isotope_filter_grid_item Vue React">
        <img src="/images/clients/404.png" alt="" /> 
        <h1>HelloWorld! 3</h1>
      </div>
      <div class="isotope_filter_grid_item Vue React">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 4</h1>
      </div>
      <div class="isotope_filter_grid_item React">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 5</h1>
      </div>
      <div class="isotope_filter_grid_item React">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 6</h1>
      </div>
      <div class="isotope_filter_grid_item Angular">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 7</h1>
      </div>
      <div class="isotope_filter_grid_item Angular">
        <img src="/images/clients/404.png" alt="" />
        <h1>HelloWorld! 8</h1>
      </div>
    </div>
  </div>
</template>

<script>
import Isotope from 'isotope-layout'

export default {
  data() {
    return {
      // ...
    }
  },
  mounted() {
    this.handleInitIsotope()
  },
  methods: {
    async handleInitIsotope() {
      // 1.获取 isotope 导航条
      const navbar = await document.querySelector('.isotope_filter_navbar')
      console.log('navbar =>', navbar)

      // 2.实例化 isotope 对象
      const isotope = await new Isotope(
        '.isotope_filter_grid', // 容器
        {
          layoutMode: 'fitRows', // 布局模式
          itemSelector: '.isotope_filter_grid_item', // 元素
        }
      )
      console.log('isotope =>', isotope)

      // 3.为导航条注册点击事件
      navbar.addEventListener('click', (e) => {
        const { target } = e
        console.log('target =>', target)
        const filterOption = target.getAttribute('data-filter') // 筛选的类别
        if (filterOption) {
          // 给元素移除 actived 样式
          navbar
            .querySelectorAll('span')
            .forEach(
              (btn) => btn.classList.remove('actived')
            )

          // 给目标元素加上 actived 样式
          target.classList.add('actived')

          // 筛选
          isotope.arrange({ filter: filterOption })
        }
      })
    },
  },
}
</script>

<style lang="less" scoped>
.isotope_container {
  position: relative;

  .isotope_filter_navbar {
    display: flex;
    align-items: center;
    padding: 20px 20px 10px 20px;

    span {
      display: inline-block;
      color: #999999;
      font-family: gotham-book;
      font-size: 24px;
      font-weight: bold;
      text-transform: uppercase;
      margin: 0px 30px 0 0;
      text-decoration: none;
      transition: all 0.4s ease-in-out;
      text-transform: capitalize; // 首字母大写
      cursor: pointer;

      &.actived {
        color: #000;
      }

      &:hover {
        color: #000;
      }
    }
  }

  .isotope_filter_grid {

    .isotope_filter_grid_item {
      position: relative;
      display: flex;
      width: 25vw;
      height: 25vw;
      text-align: center;

      img {
        display: block;
        flex: 1;
        margin: 20px;
        object-fit: cover;
        background-color: #000;
      }

      h1 {
        display: grid;
        align-items: center;
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        margin: auto;
        color: #fff;
        font-weight: lighter;
      }
    }
  }
}
</style>

2. Effet de l'opération

(1) Les effets ci-dessus sont les mêmes

Guess you like

Origin blog.csdn.net/Cai181191/article/details/131901834