Home > Net >  How can I use chips like a tag sorter in Vue?
How can I use chips like a tag sorter in Vue?

Time:02-03

I will need more help, because I only have basic knowledge in JavaScript and I have been worried about it for 3 days and I can't put it together. I know I ask a lot but I am stuck and I have no idea how to make it works. I want the following:

<div >
  <div >
    <!-- here i want display all used tags -->
  </div>
  <div >
   <img />
   <!-- here i want display all images which contains selected tags -->
  </div>
</div>

Defined in code I have this as follows

data: function () {
  return {
    images: [
        {
          tags: ["art"],
          url: "url of image",
          name: "my image name",
        },
        {
          tags: ["chipmunk", "art"],
          url: "url of image",
          name: "my image name",
        },
        {
          tags: ["ship"],
          url: "url of image",
          name: "my image name",
        },
        {
          tags: ["art", "ship"],
          url: "url of image",
          name: "my image name",
        },
      ],
    };
  },
};

I want:

1. A feature that automatically searches for this images Array and finds all tags and displays them in .tags as <li> each. Selectable and each only once and sorted alphabet) without having to write them in my own Array.

2. A feature that automatically displays all images that contain a selected tag

CodePudding user response:

If I understood you correctly, try like following snippet:

const app = Vue.createApp({
  name: 'size guide app',
  data() {
    return {
      images: [
          {
            tags: ["art"],
            url: "https://picsum.photos/200",
            name: "my image name",
          },
          {
            tags: ["chipmunk", "art"],
            url: "https://picsum.photos/201",
            name: "my image name",
          },
          {
            tags: ["ship"],
            url: "https://picsum.photos/199",
            name: "my image name",
          },
          {
            tags: ["art", "ship"],
            url: "https://picsum.photos/202",
            name: "my image name",
          },
        ],
        tags: [],
        selected: []
     }
  },
  mounted() {
    const set = new Set([])
    this.images.forEach(i => {
      set.add(...i.tags)
    })
    this.tags = [...set]
  },
  computed: {
    getItems() {
      return this.images.filter(i => {
        return this.selected.some(s => i.tags.includes(s) )
      })
    }
  },
  methods: {
    selectTag(tag) {
      !this.selected.includes(tag) && this.selected.push(tag)
    }
  }
})
app.mount('#demo')
.tags, .container {
  display: flex;
  column-gap: 1em;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <div >
    <template  v-for="tag in tags">
      <button @click="selectTag(tag)">{{ tag }}</button>
    </template>
  </div>
  <div  v-if="selected.length">
    <template v-for="sel in selected">
      <p>{{ sel }}</p>
    </template>
  </div>
  <div >
    <div v-for="img in getItems">
      <p>{{ img.name }}</p>
      <img :src="img.url" />
      <p>{{ img.tags }}</p>
    </div>
  </div>
</div>

CodePudding user response:

this code: ( use syntax sfc vue 3 ) https://sfc.vuejs.org/#eNqlVUtz0zAQ/iuLOZDMYKc8DyYNcODAFbjVPQh7E4vakkeSE0LH/51dSYmdpDxm2pnG0u7q28e3Wt0nH7su2/aY5MnSlkZ2Diy6voNGqM11kThbJKtCybbTxsF9oQAMrp/zt9Rt1zus/MbWomn07guK0sktkmyAtdEtPCPwZ4UqVKmVdSBbsUEL14wyu/F4AE5sbA43RSKMK5JbDwjQmyaHIqEP6HU4CC KJGqVaJHV7T6qWBC1g/89By9r2bW9uiMjOvdPVy8f4cqSq7 jv3oEug dc/i3m9f/7eZ2PpLEnoiiA8Gz2RyuVyGMYEBcfws2CnfwFd3SOiPVZjUjFAD D0RnW9H0mK21 STKeiYdtkcosqFtxs6OBrRhfcTPRFWxaO5RhyO2oQ416sL3R2PEPuOumx0AvHs7m88zS/1LX rLCDOm hUbLClPSuesjWcX6dHhda9IqRVdFD5HfjjGHILNPCQn18DSI3ZWCxtSOXGZVbRw6DV8DBuLpwaHElDg07hDeSeRP0RWrNMJnpW/EFZwBe/PKJKNQ3NkaKTG6tbHx9KHM5pDfoIVarxchHlC04M2BNc1wiHtAJaV3ELZCGtpwlA TkiFxg8abgtmLg/LE0v2fjQi3ZM0hRoNgoSdUA4qacnHnrsHektV8X2cpuMJ2wkKJmwAtim1HeH6nGWoU5GM vwO91E9FX8oG1nekWLkn03mU5tJyCeIB3m8AOEv9Fp Wd0Ae7QcplDbtMVWE9TNw8duJ5UCeHp/7ymFwXeRL8aCqxFtlgsqdFx/9lQ REAgeQT2DBikopdI1d/CTro6jpex7B7ivNan/Vskp8VexXAzHmbDMI3u77TH52VXy7LmWcWdZeNFvWiIEfawWi4mfUpb6/YNgi11h5U35CtxmF6lbrTJ4Tt1/LsgaYXZSJXT5XrT/Yyysjc0enLotFR0wbzUc8BQWaD DNFgFQ vKYN0h3JTuxzeXl0dThN3HNkqeU6c8MuctqLLflit6B33YEwWK4it/ABfJPQW875Iauc6my8Wdl3y6//DZtpsFrTKTK cbDFD26bfjd5ZNAR8fEY8xoKEWzSpQVUREXRz/4x5ZnqBGzMakuE3vUvFyA==

  • Related