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
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
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>
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>
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()
},
}
}
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();
}
Initialize Grid on Component Mount
Initialize the grid when the component is mounted:
onMounted(() => {
grid = makeGrid(gifs.value)
})
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>
Final gif picker result
GitHub Gist: https://gist.github.com/sarinmsari/e2a47f457a1b5924ba4e5791b954ca88
Top comments (0)