最近在折騰一個cms系統,用的vue+express,但是就一個表單提交就弄了好久,記錄一下。
環境:
Node10+
前端:Vue
服務端:Express
依賴包:
- vue
- express
- axios
- express-formidable
- element-ui(可選)
前言:
axios get 請求參數是: params
axios post 請求參數是: data
express get 接受參數 是 req.query
express post 接受參數是:req.fields, 接受文件地址是:req.files.file.path
文件目錄:
新建blog-cms文件。在blog-cms文件下新建client文件夾存放前端文件,在blog-cms文件下新建server存放后端文件。
配置vue環境
在client文件下使用vue-cli工具,快速生成一個vue項目,
輸入vue-cli安裝命令:
npm install vue-cli -g
輸入初始化命令(回車默認即可):
vue init webpack
啟動:
npm start
然后打開瀏覽器http://localhost:8080/#/
看到:
表示安裝成功
配置express環境
打開server文件夾,安裝express,我們使用express 生成器,來快速生成一個express環境。
安裝express-generator:
npm install express-generator -g
然后生成Express 應用:
express --view=ejs
之后下載依賴:
npm i
然后啟動項目:
npm start
瀏覽器打開http://localhost:8080/#/
看到:
就說明安裝成功了!
然后在server目錄下新建models,在models下新建get_article_list.js文件寫入:
/* 目錄:server/models/get_article_list.js */
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.send('文章列表 響應成功!')
});
module.exports = router;
然后在server/app.js中添加代碼:
var app=express();//這個一定要在上面
var getArticleList = require('./models/get_article_list')
app.use('/get_article_list', getArticleList)
然后我們重啟服務,在瀏覽器打開:http://localhost:3000/get_article_list
,顯示如圖,表示成功。
axios
然后在client下,下載axios,用于ajax請求:
npm i axios --save
然后更改client/src/components/HelloWorld.vue:
<template>
<div>
<h1>{{this.msg}}</h1>
</div>
</template>
<script>
import axios from "axios"
export default {
name: 'HelloWorld',
data () {
return {
msg: ''
}
},
created() {
axios.get('http://localhost:3000/get_article_list')
.then(res=>{
this.mas= res.data
}).catch(err=>{
console.log(err);
})
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
</style>
之后打開瀏覽器發現報錯,
這是因為跨域,我們使用cros解決。
直接在server/app.js添加:
var app = express()//在他的下面
// 以下 配置允許跨域請求; **********一定要放在上面**********
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With')
res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
res.header('X-Powered-By', ' 3.2.1')
if(req.method=="OPTIONS") res.send(200);/*讓options請求快速返回*/
else next();
})
// api
var getArticleList = require('./models/get_article_list')
app.use('/get_article_list', getArticleList)
然后重啟服務器(在server下)執行npm start
,然后再看了前端。就OK了,
參考:不要再問我跨域的問題了
使用elementUI
elementUI官網
client下使用命令npm i element-ui --save
下載
然后在main.js里使用:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
get 前端
在 client/src/components下新建GetForm.vue:
<template>
<div>
<h2>get請求</h2>
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="文章標題">
<el-input v-model="form.title"></el-input>
</el-form-item>
<el-form-item label="文章內容">
<el-input type="textarea" v-model="form.content"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'App',
data () {
return {
form:{
title: 'title',
content: 'content'
}
}
},
methods: {
onSubmit(){
axios.get('http://127.0.0.1:3000/get_form',{
params: this.form
},{
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
}
}
}
</script>
然后在client/src/router/index.js下添加GetForm的路由:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import GetForm from '@/components/GetForm.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path:'/get_form',
name: 'GetForm',
component: GetForm
}
]
})
然后更改client/src下的App.vue,添加一個GetForm跳轉按鈕:
<template>
<div id="app">
<div class="nav">
<router-link to='/'>HelloWold</router-link>
<router-link to='/get_form'>get form</router-link>
</div>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
之后打開http://localhost:8080/#/get_form
看到
表示成功。
get 后端
在server/models下新建get_form.js,輸入:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
console.log(req.query)
});
module.exports = router;
在server/app.js新增get_from的接口:
// api
var getForm = require('./models/get_form.js')
app.use('/get_form', getForm)
然后重啟后端服務器;
在前端中提交表單,就可以在后端的命令行工具上看到提交的信息了.
post 前端
在client/src/components下添加PostForm.vue:
<template>
<div>
<h2>post請求</h2>
<div>
<form>
<input type="text" value="" v-model="name" placeholder="請輸入用戶名">
<input type="text" value="" v-model="age" placeholder="請輸入年齡">
<input type="file" @change="getFile($event)">
<button @click="submitForm($event)">提交</button>
</form>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'PostForm',
data () {
return {
age: '19',
file: ''
}
},
methods: {
// post文件上傳
getFile(event){
this.file = event.target.files[0];
console.log(this.file);
},
submitForm(event){
event.preventDefault();
let formData = new FormData();
formData.append('name', this.name);
formData.append('age', this.age);
formData.append('file', this.file);
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
axios.post('http://127.0.0.1:3000', formData, config)
.then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
}
}
}
</script>
同理,給PostForm添加路由和導航:
client/src/router/index.js里:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import GetForm from '@/components/GetForm.vue'
import PostForm from '@/components/PostForm.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path:'/get_form',
name: 'GetForm',
component: GetForm
},
{
path: '/post_form',
name: PostForm,
component: PostForm
}
]
})
APP.vue中;
<template>
<div id="app">
<div class="nav">
<router-link to='/'>HelloWold</router-link>
<router-link to='/get_form'>get form</router-link>
<router-link to="/post_form">post form</router-link>
</div>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
post 后端
post 提交的表單里有圖片文件,這里需要借助一個插件express-formidable
在sever下 使用命令npm install express-formidable --save
在server/models下新建post_form.js
var express = require('express');
var router = express.Router();
let formidableMiddleware = require('express-formidable');
router.use(formidableMiddleware({
encoding: 'utf-8',
uploadDir: 'public/images',//保存圖片的目錄
multiples: true, // req.files to be arrays of files
keepExtensions: true//保留后綴
}))
/* POST home page. */
router.post('/', function(req, res, next) {
console.log('圖片地址:'+req.files.file.path);
console.log(req.fields);
});
module.exports = router;
照舊;在server/app.js里添加:
var postForm = require('./models/post_form.js')
app.use('/post_form', postForm)
然后重啟服務器,然后去前端提交表單(包括圖片)。
在后端顯示這樣表示成功了!
下一章 :把提交的數據的插入到mongoDB數據庫里