DEV Community

Cover image for Tutorial: Giphy gif picker (Vue3)
Sarin M
Sarin M

Posted on

Tutorial: Giphy gif picker (Vue3)

I hope you have a basic understanding of Vue3 and Tailwind CSS.

Step 1: Setup Vue 3 Project

Ensure you have a basic Vue 3 project set up. If not, you can create one using Vue CLI:

vue create my-project
cd my-project
Enter fullscreen mode Exit fullscreen mode

Step 2: Install Giphy Packages

Install the required Giphy packages using npm or yarn:

# Using npm
npm install @giphy/js-fetch-api @giphy/js-components

# Or using yarn
yarn add @giphy/js-fetch-api @giphy/js-components
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Home Page Component

Create a Home.vue component to serve as the main page for the GIF picker:

//Home.vue
<script setup>
import {ref} from 'vue'
import GifPicker from '@/components/giphy/GifPicker.vue';

let showGifPicker = ref(false);
let gifUrl = ref('');

const handleGifSelection = (gif) => {
    showGifPicker.value = false;
    gifUrl.value = gif;
}
</script>

<template>
    <div class="relative flex flex-col items-center justify-center w-full">

        <GifPicker v-if="showGifPicker"
            @handleGifSelect="handleGifSelection"
            class="absolute text-black bottom-14"/>
        <button @click="showGifPicker = !showGifPicker"
            class="bg-green-700 p-4 rounded-2xl text-white">Pick Gif</button>
        <img v-if="gifUrl"
            :src="gifUrl"
            class="w-40 h-auto rounded-2xl absolute top-20"/>

    </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the GifPicker Component

Create a GifPicker.vue component to handle GIF selection:

<script setup></script>
<template>
    <div class="flex flex-col items-center justify-center w-[280px] h-[350px] bg-white shadow-lg rounded-2xl border p-4">
        <div class="flex items-center justify-between w-full">
            <input
                type="text"
                v-model="searchTerm"
                @input="handleGifSearch"
                class="w-full text-xl p-2 border rounded-xl"
                placeholder="Search gif"/>
            <span @click="handleTrendingClick" class=" ml-2 text-xl p-2 bg-white border flex items-center justify-center rounded-xl hover:bg-gray-100 cursor-pointer">🔥</span>
        </div>

        <div class="flex flex-wrap items-center justify-center w-full h-full overflow-y-auto">
            <div class="mt-2" ref="gifs"/>
        </div>
    </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Let's work on the gif picker scripting

Setup Imports and Initialization
Import necessary modules and initialize required variables:

<script setup>
import {ref,onMounted} from 'vue'
import { renderGrid } from '@giphy/js-components'
import { GiphyFetch } from '@giphy/js-fetch-api'
import { debounce } from 'lodash';

const emit = defineEmits(['handleGifSelection'])

let gifs = ref(null),
    searchTerm = ref(''),
    grid = null;

const gf = new GiphyFetch('your Web SDK key') // update your giphy key

const fetchGifs = (offset) => {
    if (searchTerm.value) {
        return gf.search(searchTerm.value, { offset, limit: 25 })
    }
    return gf.trending({ offset, limit: 25 })
}
Create Grid Rendering Function
Define a function to render the GIF grid:

const makeGrid = (targetEl) => {
    const render = () => {
        return renderGrid(
            {
                width: 226,
                fetchGifs,
                columns: 2,
                gutter: 6,
                noLink: true,
                hideAttribution: true,
                onGifClick,
            },
            targetEl
        )
    }
    const remove = render()
    return {
        remove: () => {
            remove()
        },
    }
}
Enter fullscreen mode Exit fullscreen mode

Handle GIF Clicks
Define a function to handle GIF clicks and emit the selected GIF URL:

const onGifClick = (gif, e) => {
    e.preventDefault();
    emit('handleGifSelection', gif.images.fixed_height.url);
}
Handle Grid Refresh and Fetch New GIFs
Define functions to refresh the grid and fetch new GIFs based on search or trending clicks:

const clearGridAndFetchGifs = () => {
    grid.remove();
    grid=makeGrid(gifs.value)
}

const handleGifSearch = debounce(() => {
    clearGridAndFetchGifs();
},500)

const handleTrendingClick = () => {
    searchTerm.value = '';
    clearGridAndFetchGifs();
}
Enter fullscreen mode Exit fullscreen mode

Initialize Grid on Component Mount
Initialize the grid when the component is mounted:

onMounted(() => {
    grid = makeGrid(gifs.value)
})
Enter fullscreen mode Exit fullscreen mode

Final GifPicker Component
Combine all the pieces into the final GifPicker component:

<script setup>
import {ref,onMounted} from 'vue'
import { renderGrid } from '@giphy/js-components'
import { GiphyFetch } from '@giphy/js-fetch-api'
import { debounce } from 'lodash';

const emit = defineEmits(['handleGifSelection'])

let gifs = ref(null),
    searchTerm = ref(''),
    grid = null;

const gf = new GiphyFetch('your Web SDK key') // update your giphy key

onMounted(() => {
    grid = makeGrid(gifs.value)
})

const fetchGifs = (offset) => {
    if (searchTerm.value) {
        return gf.search(searchTerm.value, { offset, limit: 25 })
    }
    return gf.trending({ offset, limit: 25 })
}

const makeGrid = (targetEl) => {
    const render = () => {
        return renderGrid(
            {
                width: 226,
                fetchGifs,
                columns: 2,
                gutter: 6,
                noLink: true,
                hideAttribution: true,
                onGifClick,
            },
            targetEl
        )
    }
    const remove = render()
    return {
        remove: () => {
            remove()
        },
    }
}

const onGifClick = (gif, e) => {
    e.preventDefault();
    emit('handleGifSelection', gif.images.fixed_height.url);
}

const handleGifSearch = debounce(() => {
    clearGridAndFetchGifs();
},500)

const handleTrendingClick = () => {
    searchTerm.value = '';
    clearGridAndFetchGifs();
}

const clearGridAndFetchGifs = () => {
    grid.remove();
    grid=makeGrid(gifs.value)
}

</script>

<template>
    <div class="flex flex-col items-center justify-center w-[280px] h-[350px] bg-white shadow-lg rounded-2xl border p-4">
        <div class="flex items-center justify-between w-full">
            <input
                type="text"
                v-model="searchTerm"
                @input="handleGifSearch"
                class="w-full text-xl p-2 border rounded-xl"
                placeholder="Search gif"/>
            <span @click="handleTrendingClick" class=" ml-2 text-xl p-2 bg-white border flex items-center justify-center rounded-xl hover:bg-gray-100 cursor-pointer">🔥</span>
        </div>

        <div class="flex flex-wrap items-center justify-center w-full h-full overflow-y-auto">
            <div class="mt-2" ref="gifs"/>
        </div>
    </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Final gif picker result

Giphy gif picker final result image with a button to open gif picker, gif picker listing gifs with options to get trending gifs and search gifs.

GitHub Gist: https://gist.github.com/sarinmsari/e2a47f457a1b5924ba4e5791b954ca88

Top comments (0)