This project is built using Node and Vue.
The target is learning Vue framework and technique of backend to implement a SPA website.
All right of picture and sign is reserved for Twitter.
Used techniques, tools and packages by this project are not actually used by Twitter.
Welcome technical exchange, if this project has mistake of code or concept of programming, let me know, thanks:thumbsup:
- express
- mongoose
- jsonwebtoken
- vue
- vuex
- vue-router
- axios
- Sign up
- Login
- Post
- Comment
- Follow
You have to has installed Docker.
docker-compose up
Custom configurations can be set at /server/config/config.json
Official document
Use RESTful routes to handle http request.
const app = require('expess')
app.get('/', (req, res, next) => {
res.json({
res: 'This is GET method'
})
})
app.post('/', (req, res, next) => {
res.json({
res: 'This is POST method'
})
})
app.delete('/', (req, res, next) => {
res.json({
res: 'This is DELETE method'
})
})
app.update('/', (req, res, next) => {
res.json({
res: 'This is UPDATE method'
})
})
Official document
Use relational database.
This project has three models:
- Users
- Posts
- Comments
Schema setting:
const userSchema = mongoose.Schema({
posts: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Posts'
}],
//...
})
const postSchema = mongoose.Schema({
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comments'
}],
//...
})
const commentSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Users'
},
target: {
model: String,
id: mongoose.Schema.Types.ObjectId()
},
//...
})
const userModel = mongoose.Model('Users', userSchema)
const postModel = mongoose.Model('Posts', postSchema)
const commentModel = mongoose.Model('Comments', commentSchema)
Get populated data:
userModel.findById(USER_ID)
.then(user => {
if (!user) {
//...
}
let opt = {
path: 'posts',
populate: {
path: 'comments'
}
}
user.populate(opt).execPopulate()
.then(populatedUser => {
// Do what tou want to do
}).
catch(e => {
//...
})
})
.catch(e => {
//...
})
Official document
Create an token and it will be invalid after 1 hour.
You can put some data into token to let server know this token's owner and information.
const jwt = require('jsonwebtoken')
const token = jwt.sign({
id: USER_ID,
access: 'auth',
exp: Math.floor(Date.now() / 1000) + (60 * 60 * 1)
}, 'YOUR_SECRET_KEY')
Token verification:
try {
let data = jwt.verify(RECEIVED_TOKEN, 'YOUR_SECRET_KEY')
} catch (e) {
// Verify fail
}
Official document
The following picture shows the life cycle of a instance component.
I think it is the most important thing to understand each event when will be invoked.
If we have the component needs props of 'userID' to get user's info async.
When the components is instanced, function of created
will be invoked and get user's information by current 'userID'.
But if the next route also has this component and has different props of 'userID', this component is reused rather than
instance a new component again. At this time the created
function is not invoked, so the other method is using watch
property to monitor the 'userID' props change or not, if the indicated target change, the function you set will be invoked.
Vue.component('your-component', {
props:['userID'],
data: function () {
return {
user: null
}
},
created() {
this.getUserInfo()
},
watch: {
// here is important
'userID': 'getUserInfo'
},
method: {
getUserInfo() {
// Some http Request to get user information from server
}
},
template: '<div v-if="user">{{ user.name }}</div>'
})