Vue
Learn how to configure Vue for use with Filebase.
Last updated
Was this helpful?
Learn how to configure Vue for use with Filebase.
Last updated
Was this helpful?
Vue is an open-source JavaScript framework used for building user interfaces and single-page applications (SPAs). Vue is designed to be incrementally adoptable, which means that it can be integrated into an existing project or used to build a new project from scratch. It is also highly modular, with a core library that focuses on the view layer of an application and a set of optional libraries that can be used to add more functionality.
Read below to learn how to use Vue with Filebase.
mkdir filebase-vue-app
cd filebase-vue-app
npm init
Accept the default options when prompted.
npm install --save express multer dotenv cors body-parser mongodb multer-s3 aws-sdk
.env
file with the following environment variables:DATABASE=mongodb://127.0.0.1:27017/
PORT=5005
AWSAccessKeyId=FILEBASE_ACCESS_KEY
AWSSecretKey=FILEBASE_SECRET_KEY
AWSRegion=us-east-1
AWSBucket=filebase-bucket-name
Replace the environment variable values with the values that match your Filebase account and MongoDB configuration.
index.js
that contains the following code:const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const dotenv = require('dotenv')
const aws = require('aws-sdk')
const multer = require('multer')
const multerS3 = require('multer-s3')
const mongodb = require('mongodb')
dotenv.config()
const app = express()
//middleWare
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(cors())
aws.config.update({
apiVersion: "2006-03-01",
accessKeyId: process.env.AWSAccessKeyId,
secretAccessKey: process.env.AWSSecretKey,
region: process.env.AWSRegion
endpoint: "https://s3.filebase.com",
})
const s3 = new aws.S3()
const upload = multer({
storage: multerS3({
s3: s3,
bucket: process.env.AWSBucket,
acl: "public-read",
contentType: multerS3.AUTO_CONTENT_TYPE,
metadata: (req, file, cb) => {
cb(null, { fieldName: file.fieldname})
},
key: (req, file, cb) => {
cb(null, Date.now().toString() + file.originalname)
}
})
})
app.get('/', async (req, res) => {
res.status(200).send('S3 Upload Backend')
})
app.post('/', upload.single('photo'), async (req, res) => {
try {
const users = await loadUsersCollection();
await users.insertOne({
first_name: req.body.first_name,
last_name: req.body.last_name,
phone: req.body.phone,
email: req.body.email,
gender: req.body.gender,
photo: req.file.location,
})
res.status(201).send('success')
}
catch (err) {
res.status(500).send({
error: 'error occured creating user'
})
}
})
async function loadUsersCollection () {
const client = await mongodb.MongoClient.connect(process.env.DATABASE, {
useNewUrlParser: true,
useUnifiedTopology: true
})
return client.db('vue-multers3').collection('users')
}
const port = process.env.PORT || 5000
app.listen(port, () => {
console.log(server started on port ${port})
});
node index.js
npm install -g @vue/cli
vue create filebase-vue-app
cd vue-multers3-frontend
vue add vuetify
npm run serve
localhost:8080
address to view the Vue app:register.vue
in the components folder. Insert the following code into this file:<template>
<v-container fluid class="my-3">
<v-row align="center" justify="center">
<v-col cols="12">
<v-card style="width: 100%" flat>
<div class="text-center pt-6"><h1 class="font-weight-light display-2 primary--text">Register!</h1></div>
<v-row class="pa-4">
<v-col cols="12" md="6">
<v-img src="@/assets/contactus.jpg" class="d-block ml-auto mr-auto" max-width="350px" />
</v-col>
<v-col cols="12" md="6">
<v-form ref="forma" v-model="form1" lazy-validation>
<v-row>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="first_name"
label="First Name"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="last_name"
label="Last Name"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="phone"
label="Phone"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="email"
label="Email"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="age"
type="number"
label="Age"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-file-input
v-model="photo"
:rules="photoRules"
accept="image/png, image/jpeg"
label="Pick a Picture"
outlined
dense
prepend-icon=""
prepend-inner-icon="mdi-camera"
hide-details
>
</v-file-input>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="password"
:append-icon="show1 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="passwordRules"
:type="show1 ? 'text' : 'password'"
hint="At least 6 characters"
@click:append="show1 = !show1"
outlined
dense
hide-details
>
</v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="confirmPassword"
:append-icon="show1 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="passwordConfirmation"
:type="show1 ? 'text' : 'password'"
hint="At least 6 characters"
@click:append="show1 = !show1"
outlined
dense
hide-details
>
</v-text-field>
</v-col>
<v-col
cols="12"
md="12"
>
<v-text-field
v-model="address"
label="Address"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
>
<v-btn
color="primary"
rounded
block
class="mt-3"
@click="onSubmit"
:disabled="!form1"
>
Submit
</v-btn>
</v-col>
</v-row>
</v-form>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-snackbar
v-model="snackbar"
:timeout="timeout"
color="success"
top
>
{{ message }}
</v-snackbar>
</v-container>
</template>
<script>
export default {
data () {
return {
message: 'success',
snackbar: false,
timeout: 2000,
show1: false,
form1: false,
submitSuccess: false,
first_name: '',
last_name: '',
phone: '',
email: '',
age: '',
photo: null,
address: '',
password: '',
confirmPassword: '',
photoRules: [v => !v || v.size < 5000000 || 'Image should be less than 5MB'],
passwordRules: [v => !!v || 'Password is required',
v => (v && v.length >= 6) || 'password should be 6 characters'],
passwordConfirmation: [v => !!v || 'Password is required',
v => (v === this.password) || 'password should match'],
required: [value => !!value || 'Required.']
}
}
}
</script>
<style>
</style>
app.vue
file:<template>
<v-app>
<v-app-bar
app
color="primary"
dark
>
<div class="d-flex align-center">
<v-img
alt="Vuetify Logo"
class="shrink mr-2"
contain
src="<https://cdn.vuetifyjs.com/images/logos/vuetify-logo-dark.png>"
transition="scale-transition"
width="40"
/>
<v-img
alt="Vuetify Name"
class="shrink mt-1 hidden-sm-and-down"
contain
min-width="100"
src="<https://cdn.vuetifyjs.com/images/logos/vuetify-name-dark.png>"
width="100"
/>
</div>
<v-spacer></v-spacer>
<v-btn
href="<https://github.com/vuetifyjs/vuetify/releases/latest>"
target="_blank"
text
>
<span class="mr-2">Latest Release</span>
<v-icon>mdi-open-in-new</v-icon>
</v-btn>
</v-app-bar>
<v-main>
<Register/>
</v-main>
</v-app>
</template>
<script>
import Register from './components/Register'
export default {
name: 'App',
components: {
Register
},
data: () => ({
//
})
}
</script>
npm install axios
registeraxios.vue
in the components folder and insert the following code:<template>
<v-container fluid class="my-3">
<v-row align="center" justify="center">
<v-col cols="12">
<v-card style="width: 100%" flat>
<div class="text-center pt-6"><h1 class="font-weight-light display-2 primary--text">Register!</h1></div>
<v-row class="pa-4">
<v-col cols="12" md="6">
<v-img src="@/assets/contactus.jpg" class="d-block ml-auto mr-auto" max-width="350px" />
</v-col>
<v-col cols="12" md="6">
<v-form ref="forma" v-model="form1" lazy-validation>
<v-row>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="first_name"
label="First Name"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="last_name"
label="Last Name"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="phone"
label="Phone"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="email"
label="Email"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="age"
type="number"
label="Age"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-file-input
v-model="photo"
:rules="photoRules"
accept="image/png, image/jpeg"
label="Pick a Picture"
outlined
dense
prepend-icon=""
prepend-inner-icon="mdi-camera"
hide-details
>
</v-file-input>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="password"
:append-icon="show1 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="passwordRules"
:type="show1 ? 'text' : 'password'"
hint="At least 6 characters"
@click:append="show1 = !show1"
outlined
dense
hide-details
>
</v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
v-model="confirmPassword"
:append-icon="show1 ? 'mdi-eye' : 'mdi-eye-off'"
:rules="passwordConfirmation"
:type="show1 ? 'text' : 'password'"
hint="At least 6 characters"
@click:append="show1 = !show1"
outlined
dense
hide-details
>
</v-text-field>
</v-col>
<v-col
cols="12"
md="12"
>
<v-text-field
v-model="address"
label="Address"
outlined
dense
hide-details
></v-text-field>
</v-col>
<v-col
cols="12"
>
<v-btn
color="primary"
rounded
block
class="mt-3"
@click="onSubmit"
:disabled="!form1"
>
Submit
</v-btn>
</v-col>
</v-row>
</v-form>
</v-col>
</v-row>
</v-card>
</v-col>
</v-row>
<v-snackbar
v-model="snackbar"
:timeout="timeout"
color="success"
top
>
{{ message }}
</v-snackbar>
</v-container>
</template>
<script>
import axios from 'axios'
const url = '<http://localhost:5005/>'
export default {
data () {
return {
message: 'submission success',
snackbar: false,
timeout: 4000,
show1: false,
form1: false,
submitSuccess: false,
first_name: '',
last_name: '',
phone: '',
email: '',
age: '',
photo: null,
address: '',
password: '',
confirmPassword: '',
photoRules: [v => !v || v.size < 5000000 || 'Image should be less than 5MB'],
passwordRules: [v => !!v || 'Password is required',
v => (v && v.length >= 6) || 'password should be 6 characters'],
passwordConfirmation: [v => !!v || 'Password is required',
v => (v === this.password) || 'password should match'],
required: [value => !!value || 'Required.']
}
},
computed: {
photoValidation () {
if (this.photo) {
return true
} else return false
}
},
methods: {
clearForm () {
this.$refs.forma.reset()
},
async onSubmit () {
if (this.$refs.forma.validate() && this.photoValidation) {
const blob = this.photo
const formData = new FormData()
formData.append('first_name', this.first_name)
formData.append('last_name', this.last_name)
formData.append('photo', blob)
formData.append('phone', this.phone)
formData.append('email', this.email)
formData.append('age', this.age)
formData.append('password', this.password)
formData.append('address', this.address)
axios.post(url, formData).then((res) => {
if (res.status === 201) {
console.log(res)
this.clearForm()
this.snackbar = true
}
}).catch((err) => {
console.log(err.response)
})
}
}
}
}
</script>
<style>
</style>