EE
Ekene Eze 5 years ago
Hi, @Kate T I just added this bit to the article. I missed it and someone pointed it o
- How to build an e-commerce site with Strapi, Vue.js, and Flutterwave
- Tooling
- Prerequisites
- Getting started
- Create a Strapi project
- Start the project
- Vue app setup
- Styling
- Fetch the products
- Update the App component
- Add Navbar
- Implement payments with Flutterwave
- Conclusion
Tooling
Prerequisites
Getting started
yarn create strapi-app VueStrap --quickstart
#OR
npx create-strapi-app VueStrap --quickstart
yarn develop
#OR
npm run develop
Vue app setup
npm install -g @vue/cli-service-global
#OR
yarn global add @vue/cli-service-global
#create a new Vue project:
vue create vue-strapi
#navigate into the newly created app and start the dev server:
cd vue-strapi && npm run serve
Styling
npm i bootstrap bootstrap-vue
// main.js
import Vue from "vue";
import App from "./App.vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
import BootstrapVue from "bootstrap-vue";
Vue.config.productionTip = false;
Vue.use(BootstrapVue);
new Vue({
render: (h) => h(App),
}).$mount("#app");
Fetch the products
# src/components/Meals.vue
<script>
export default {
data() {
return {
meals: [],
};
},
mounted() {
fetch("http://localhost:1337/products")
.then((res) => res.json())
.then((data) => {
this.meals = data;
});
}
};
</script>
# src/components/Meals.vue
<template>
<b-container>
<div v-if="meals.length">
<b-row>
<div v-bind:key="meal.index" v-for="meal in meals">
<b-col l="4">
<b-card
v-bind:img-src="`http://localhost:1337/uploads/beef_b538baa14d.png`"
v-bind:title="meal.title"
img-alt="Image"
img-top
tag="article"
style="max-width: 20rem;"
class="mb-2"
>
<b-card-text>{{ `${meal.description}` }}</b-card-text>
<span>
<strong>Price: ${{ `${meal.price}` }} </strong>
</span>
<b-button @click="placeOrder" variant="primary">Order meal</b-button>
</b-card>
</b-col>
</div>
</b-row>
</div>
<div v-else>
<h5>Fetching meals . . .</h5>
</div>
</b-container>
</template>
// src/App.vue
<template>
<div>
<br />
<Meals />
</div>
</template>
<script>
import Meals from "./components/Meals";
export default {
name: "App",
components: {
Meals,
},
};
</script>
<style>
#styles here
</style>
Add Navbar
#src/components/navbar.vue
<template>
<div>
<b-navbar toggleable="lg" type="dark" variant="info">
<b-navbar-brand href="#">MealsHub</b-navbar-brand>
<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
<b-collapse id="nav-collapse" is-nav>
<b-navbar-nav class="ml-auto">
<b-nav-form>
<b-form-input
size="sm"
class="mr-sm-2"
placeholder="Search"
></b-form-input>
<b-button size="sm" class="my-2 my-sm-0" type="submit"
>Search</b-button
>
</b-nav-form>
<b-nav-item-dropdown right>
<template v-slot:button-content>
<em>User</em>
</template>
<b-dropdown-item href="#">Profile</b-dropdown-item>
<b-dropdown-item href="#">Sign Out</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav>
</b-collapse>
</b-navbar>
</div>
</template>
<script></script>
Implement payments with Flutterwave
// src/components/Meals.vue
<script>
export default {
data() {
return {
meals: [],
};
},
mounted() {
//Fetch products
},
created() {
const script = document.createElement("script");
script.src = "https://ravemodal-dev.herokuapp.com/v3.js";
document.getElementsByTagName("head")[0].appendChild(script);
},
};
</script>
// src/components/Meals.vue
<script>
export default {
data() {
return {
meals: [],
};
},
methods: {
placeOrder() {
window.FlutterwaveCheckout({
public_key: "INSERT YOUR PUBLIC KEY",
tx_ref: "new-sale"+ new Date(),
amount: 29.99,
currency: "USD",
country: "NG",
payment_options: "card",
customer: {
email: "ekene@gmail.com",
phone_number: "+234702909304",
name: "Ekene Eze",
},
callback: function(data) {
console.log(data);
},
onclose: function() {},
customizations: {
title: "MealsHub",
description: "Payment for selected meal",
logo: "http://localhost:1337/uploads/beef_b538baa14d.png",
},
});
},
},
mounted() {
fetch("http://localhost:1337/products"){
// Fetch products
});
},
created() {
// Install Flutterwave
},
};
</script>
Conclusion