使用js实现一个全栈的项目:向我提问,以前使用html静态页面实现的(https://github.com/AprilJoy/bulma),这次使用vue实现前端代码,效果如下
创建vue cli 工程
vue create example
启动vue 的server
npm run serve
安装vue 依赖
npm install axios vue-router vue-axios --save
npm install bootstrap --save
在main.js 里引入bootstrap 4 的css文件
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import "bootstrap/dist/css/bootstrap.min.css";
Vue.config.productionTip = false;
new Vue({
router,
store,
render: h => h(App)
}).$mount("#app");
创建 vue component
在src > components 文件夹下创建文件
- HomeComponent.vue
- CreateComponent.vue
- EditComponent.vue
- IndexComponent.vue
在 HomeComponent.vue 文件中添加如下代码
//Home
Home Component
I'm the Home Component component.
在 App.vue 中引入 HomeComponent.vue 文件
其他几个component文件类似
配置 vue-router
在router.js 文件中添加以下内容
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
import HomeComponent from "./components/HomeComponent.vue";
import CreateComponent from "./components/CreateComponent.vue";
import IndexComponent from "./components/IndexComponent.vue";
import EditComponent from "./components/EditComponent.vue";
const routes = [
{
name: "home",
path: "/",
component: HomeComponent
},
{
name: "create",
path: "/create",
component: CreateComponent
},
{
name: "posts",
path: "/posts",
component: IndexComponent
},
{
name: "edit",
path: "/edit/:id",
component: EditComponent
}
];
export default new Router({
mode: "history",
routes: routes
});
在App.vue中添加 ,这样就回根据路由的地址渲染出对应的component
可以通过下列地址验证一下效果
- http://localhost:8080/create
- http://localhost:8080/posts
- http://localhost:8080/edit/21
创建导航栏
在 App.vue 中添加如下代码
// App.vue
创建想我提问的表单
// CreateComponent.vue
Create A Post
创建nodejs的后台server
安装插件
npm install nodemon --save-dev
body-parser:用于解析数据
core: 用于解决跨域的问题
nodemon:实时更新后台server代码,不用每次更改代码后刷新
在api目录下新建server.js文件
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.listen(PORT, function(){
console.log('Server is running on Port:',PORT);
});
新建mongo数据库并连接
新建DB.js,存放数据库配置
module.exports = {
DB: "mongodb://localhost:8900/test"
}
server.js文件添加如下内容
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const PORT = 4000;
const cors = require("cors");
const mongoose = require("mongoose");
const config = require("./DB.js");
mongoose.Promise = global.Promise;
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
() => {
console.log("Database is connected");
},
err => {
console.log("Can not connect to the database" + err);
}
);
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.listen(PORT, function() {
console.log("Server is running on Port:", PORT);
});
创建Mongoose的schema
在文件post.model.js file中新建如下内容,用于定义数据库中的数据结构。这部分定义的Post会在下面的路由文件中用到
// post.model.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Define collection and schema for Post
let Post = new Schema(
{
title: {
type: String
},
body: {
type: String
}
},
{
collection: "posts"
}
);
module.exports = mongoose.model("Post", Post);
定义node server 的路由
创建CRUD的操作代码在路由文件post.route.js中
const express = require("express");
let postRoutes = express.Router();
// Require Post model in our routes module
let Post = require("./post.model");
// Defined store route
postRoutes.post("/add", function(req, res) {
let post = new Post(req.body);
console.log(post);
post
.save()
.then(() => {
res.status(200).json({ business: "business in added successfully" });
})
.catch(() => {
res.status(400).send("unable to save to database");
});
});
// Defined get data(index or listing) route
postRoutes.route("/").get(function(req, res) {
console.log("erro");
Post.find(function(err, posts) {
if (err) {
res.json(err);
} else {
res.json(posts);
}
});
});
// Defined edit route
postRoutes.route("/edit/:id").get(function(req, res) {
let id = req.params.id;
Post.findById(id, function(err, post) {
if (err) {
res.json(err);
}
res.json(post);
});
});
// Defined update route
postRoutes.route("/update/:id").post(function(req, res) {
Post.findById(req.params.id, function(err, post) {
if (!post) res.status(404).send("data is not found");
else {
post.title = req.body.title;
post.body = req.body.body;
post
.save()
.then(() => {
res.json("Update complete");
})
.catch(() => {
res.status(400).send("unable to update the database");
});
}
});
});
// Defined delete | remove | destroy route
postRoutes.route("/delete/:id").delete(function(req, res) {
Post.findByIdAndRemove({ _id: req.params.id }, function(err) {
if (err) res.json(err);
else res.json("Successfully removed");
});
});
module.exports = postRoutes;
在文件server.js中添加
app.use("/posts", postRoute);
至此,server端内容搭建完毕,下面通过引入axios插件,实现前端向后端发起请求的功能
引入axios发送网络请求
import VueAxios from 'vue-axios';
import axios from 'axios';
Vue.use(VueAxios, axios);
现在一共有3个server正在运行
- Vue development server
- Node.js server
- MongoDB server
现在route.js文件的内容入下
import Vue from "vue";
import Router from "vue-router";
Vue.use(Router);
import VueAxios from "vue-axios";
import axios from "axios";
Vue.use(VueAxios, axios);
import HomeComponent from "./components/HomeComponent.vue";
import CreateComponent from "./components/CreateComponent.vue";
import IndexComponent from "./components/IndexComponent.vue";
import EditComponent from "./components/EditComponent.vue";
const routes = [
{
name: "home",
path: "/",
component: HomeComponent
},
{
name: "create",
path: "/create",
component: CreateComponent
},
{
name: "posts",
path: "/posts",
component: IndexComponent
},
{
name: "edit",
path: "/edit/:id",
component: EditComponent
}
];
export default new Router({
mode: "history",
routes: routes
});
实现后台数据在前端展示/删除的功能
在IndexComponent.vue文件中的代码如下
Posts
Create Post
Title
Body
Actions
{{ post.title }}
{{ post.body }}
Edit