美文网首页
Vue + Express实现一个表单提交

Vue + Express实现一个表单提交

作者: 九旬大爷的梦 | 来源:发表于2019-05-24 18:25 被阅读0次

    最近在折腾一个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存放后端文件。


    161558680390_.pic.jpg

    配置vue环境

    在client文件下使用vue-cli工具,快速生成一个vue项目,
    输入vue-cli安装命令:
    npm install vue-cli -g
    输入初始化命令(回车默认即可):
    vue init webpack
    启动:
    npm start
    然后打开浏览器http://localhost:8080/#/看到:

    171558680667_.pic.jpg

    表示安装成功

    配置express环境

    打开server文件夹,安装express,我们使用express 生成器,来快速生成一个express环境。
    安装express-generator:
    npm install express-generator -g
    然后生成Express 应用:
    express --view=ejs
    之后下载依赖:
    npm i
    然后启动项目:
    npm start
    浏览器打开http://localhost:8080/#/看到:

    181558680955_.pic.jpg
    就说明安装成功了!

    然后在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,显示如图,表示成功。

    191558681652_.pic.jpg

    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>
    
    

    之后打开浏览器发现报错,

    201558683480_.pic.jpg
    这是因为跨域,我们使用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了,

    211558684671_.pic.jpg
    参考:不要再问我跨域的问题了

    使用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看到

    221558686564_.pic.jpg
    表示成功。

    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)
    

    然后重启后端服务器;
    在前端中提交表单,就可以在后端的命令行工具上看到提交的信息了.


    231558687197_.pic.jpg

    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)
    

    然后重启服务器,然后去前端提交表单(包括图片)。
    在后端显示这样表示成功了!


    251558691887_.pic.jpg

    下一章 :把提交的数据的插入到mongoDB数据库里

    相关文章

      网友评论

          本文标题:Vue + Express实现一个表单提交

          本文链接:https://www.haomeiwen.com/subject/dfigzqtx.html