1、方法一(图片与表单分开,请求2次)

1.1 前台代码

  1. // elementUI表单
  2. <el-form ref="form" class="forms" :model="form">
  3. <div class="title">
  4. <el-input
  5. type="text"
  6. placeholder="请在这里输入标题"
  7. v-model="form.formtitle"
  8. maxlength="48"
  9. show-word-limit
  10. >
  11. </el-input>
  12. </div>
  13. <div class="con">
  14. <div class="toolbar clearfix">
  15. <div class="toolbar-tip"></div>
  16. <ul class="toolbar-group">
  17. <el-upload
  18. action="http://localhost:5000/newtravel/upload"
  19. :before-upload="beforeupload"
  20. :on-change="handleChange"
  21. :show-file-list="false"
  22. :data="form"
  23. >
  24. <li>图片</li>
  25. </el-upload>
  26. </ul>
  27. </div>
  28. <div class="inputcon">
  29. <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar" />
  30. <el-input
  31. type="textarea"
  32. :rows="5"
  33. placeholder="请输入内容"
  34. v-model="form.formconent"
  35. >
  36. </el-input>
  37. </div>
  38. <div class="btns">
  39. <div class="user_accept">
  40. <el-checkbox v-model="isaccept"
  41. >我已阅读并同意
  42. <a href="" title="《马蜂窝游记协议》">《马蜂窝游记协议》</a>
  43. </el-checkbox>
  44. </div>
  45. <el-button type="submit" class="btn_submit" @click="onSumbit"
  46. >发表</el-button
  47. >
  48. <span class="cont">或者</span>
  49. <span class="btn_save">保存草稿</span>
  50. <div class="sync">
  51. <span>同步到:</span>
  52. <ul class="clearfix">
  53. <li>
  54. <a href="javascript:void(0);" title="微博"></a>
  55. </li>
  56. <li>
  57. <a href="javascript:void(0);" title="空间"></a>
  58. </li>
  59. <li>
  60. <a href="javascript:void(0);" title="人人"></a>
  61. </li>
  62. <li>
  63. <a href="javascript:void(0);" title="腾讯"></a>
  64. </li>
  65. </ul>
  66. </div>
  67. </div>
  68. </div>
  69. </el-form>
  70. // elementUI表单方法:
  71. data() {
  72. return {
  73. form: {
  74. formtitle: "",
  75. formconent: "",
  76. imageUrl: "",
  77. },
  78. };
  79. },
  80. methods: {
  81. handleChange(file) {
  82. if (file) {
  83. this.form.imageUrl = URL.createObjectURL(file.raw);
  84. }
  85. },
  86. beforeupload(file) {
  87. const isImage = file.type.includes("image");
  88. if (!isImage) {
  89. this.$message.error("上传文件类型必须是图片!");
  90. }
  91. const isLt2M = file.size / 1024 / 1024 < 2;
  92. if (!isLt2M) {
  93. this.$message.error("上传图片大小不能超过 2MB!");
  94. }
  95. return isImage && isLt2M;
  96. },
  97. onSumbit() {
  98. function settime(time = +new Date()) {
  99. var date = new Date(time + 8 * 3600 * 1000);
  100. return date.toJSON().substr(0, 19).replace("T", " ");
  101. }
  102. let formData = {
  103. formtitle: this.form.formtitle,
  104. formconent: this.form.formconent,
  105. createtime: settime()
  106. };
  107. this.$axios.post("/newtravel", formData).then((res) => {
  108. console.log(res);
  109. });
  110. },
  111. },

1.2 node 后台代码

  1. // app.js
  2. const express = require('express');
  3. const path = require("path");
  4. const travelnotes_query = require('./query/travelnotes_query');
  5. const app = express();
  6. app.all('*', function (req, res, next) {
  7. res.header("Access-Control-Allow-Origin", "*");
  8. res.header("Access-Control-Allow-Headers", "X-Requested-With");
  9. res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
  10. res.header("X-Powered-By", ' 3.2.1')
  11. //方便返回json
  12. res.header("Content-Type", "application/json;charset=utf-8");
  13. if (req.method == 'OPTIONS') {
  14. //让options请求快速返回
  15. res.sendStatus(200);
  16. } else {
  17. next();
  18. }
  19. });
  20. app.use(express.urlencoded({ extended: true }));

  21. app.use(express.static(path.join(__dirname, 'static')));
  22. // 定义写游记接口

  23. app.post('/newtravel', (req, res, next) => {

  24. let data = req.body

  25. travelnotes_query.addNewTravelData(data, function (rec) {

  26. res.json(rec).end();

  27. });

  28. })
  29. // 定义写游记上传图片接口

  30. var multer = require('multer')

  31. var fs = require('fs')

  32. const upload = multer({ dest: __dirname + '/static/upload' }) // 定义图片文件存储位置

  33. app.post('/newtravel/upload', upload.single('file'), async (req, res) => {

  34. let file = req.file;

  35. let basePath = __dirname + '/static/upload/'; // 设置初始路径

  36. let oldFileName = file.filename // 获取文件名

  37. let newFileName = Date.now() + '.png' // 将文件名设置成时间戳png格式

  38. let filePath = basePath + oldFileName; // 源文件路径

  39. let newFilePath = basePath + newFileName; // 新文件路径

  40. if (fs.existsSync(basePath)) { // 判断该目录是否存在,若存在执行文件重命名操作

  41. fs.rename(filePath, newFilePath, (err) => {

  42. if (err) throw err

  43. })

  44. }

  45. let imgurl = 'static/upload/' + newFileName // 设置文件相对路径用于存入数据库

  46. let data2 = {

  47. imgurl: imgurl

  48. }

  49. travelnotes_query.addNewTravelImage(data2, function (rec) {

  50. res.json(rec).end();

  51. });

  52. })
  53. const port = process.env.PORT || 5000;

  54. app.listen(port, function () { console.log(监听端口: ${port}) });
  55. // travelnotes_query.js

  56. const query = require("../dbconn.js");

  57. // 写游记添加数据

  58. exports.addNewTravelData = function (data, callback) {

  59. console.log('获取的数据:', data);

  60. var arr = [];

  61. arr.push(data.formtitle);

  62. arr.push(data.formconent);

  63. arr.push(data.createtime);

  64. query('INSERT INTO travelnotes (formtitle,formconent,createtime) VALUES (?,?,?)', arr, function (err, results, fields) {

  65. if (err) throw err;

  66. callback(results);

  67. });

  68. }
  69. // 写游记添加图片

  70. exports.addNewTravelImage = function (data, callback) {

  71. console.log('获取的数据:', data);

  72. var arr = [];

  73. arr.push(data.imgurl);

  74. query('INSERT INTO travelnotes (imgurl) VALUES (?)', arr, function (err, results, fields) {

  75. if (err) throw err;

  76. callback(results);

  77. });

  78. }
  79.  
  80.  
  81. // dbconn.js

  82. //定义连接池

  83. const mysql = require('mysql2');

  84. const pool = mysql.createPool({

  85. host: '',

  86. user: '',

  87. password: '',

  88. database: '',

  89. dateStrings: true,

  90. waitForConnections: true,

  91. connectionLimit: 50,

  92. queueLimit: 0

  93. });

  94. //定义通用的查询接口并将其导出

  95. var query=function(sql,values,callback){

  96. pool.getConnection(function(err,conn){

  97. if(err){

  98. console.log(err);

  99. callback(err,null,null);

  100. }else{

  101. conn.query(sql,values,function(qerr,results,fields){

  102. //释放连接

  103. conn.release();

  104. //事件驱动回调

  105. callback(qerr,results,fields);

  106. });

  107. }

  108. });

  109. };

  110. module.exports=query;

  111.  

2、方法二(把表单放在图片里,请求1次)

2.1 vue 前台

  1. // vue 的dom内容
  2. <el-form ref="form" class="forms" :model="form">
  3. <div class="title">
  4. <el-input
  5. type="text"
  6. placeholder="请在这里输入标题"
  7. v-model="form.formtitle"
  8. maxlength="48"
  9. show-word-limit
  10. >
  11. </el-input>
  12. </div>
  13. <div class="con">
  14. <div class="toolbar clearfix">
  15. <div class="toolbar-tip"></div>
  16. <ul class="toolbar-group">
  17. <el-upload
  18. ref="upload"
  19. action="http://localhost:5000/newtravel"
  20. :auto-upload="false"
  21. :before-upload="beforeupload"
  22. :on-change="handleChange"
  23. :show-file-list="false"
  24. :data="form"
  25. >
  26. <li>图片</li>
  27. </el-upload>
  28. </ul>
  29. </div>
  30. <div class="inputcon">
  31. <img v-if="form.imageUrl" :src="form.imageUrl" class="avatar" />
  32. <el-input
  33. type="textarea"
  34. :rows="5"
  35. placeholder="请输入内容"
  36. v-model="form.formconent"
  37. >
  38. </el-input>
  39. </div>
  40. <div class="btns">
  41. <div class="user_accept">
  42. <el-checkbox v-model="isaccept"
  43. >我已阅读并同意
  44. <a href="" title="《马蜂窝游记协议》">《马蜂窝游记协议》</a>
  45. </el-checkbox>
  46. </div>
  47. <el-button type="submit" class="btn_submit" @click="onSumbit('form')"
  48. >发表</el-button
  49. >
  50. <span class="cont">或者</span>
  51. <span class="btn_save">保存草稿</span>
  52. <div class="sync">
  53. <span>同步到:</span>
  54. <ul class="clearfix">
  55. <li>
  56. <a href="javascript:void(0);" title="微博"></a>
  57. </li>
  58. <li>
  59. <a href="javascript:void(0);" title="空间"></a>
  60. </li>
  61. <li>
  62. <a href="javascript:void(0);" title="人人"></a>
  63. </li>
  64. <li>
  65. <a href="javascript:void(0);" title="腾讯"></a>
  66. </li>
  67. </ul>
  68. </div>
  69. </div>
  70. </div>
  71. </el-form>
  72.  
  73.  
  74. // vue 的data和methods

  75. data() {

  76. return {

  77. form: {

  78. formtitle: "",

  79. formconent: "",

  80. imageUrl: "",

  81. },

  82. uploadFile: [],

  83. };

  84. },

  85. methods: {

  86. handleChange(file) {

  87. if (file) {

  88. this.form.imageUrl = URL.createObjectURL(file.raw);

  89. this.uploadFile.push(file.raw);

  90. }

  91. },

  92. beforeupload(file) {

  93. const isImage = file.type.includes("image");

  94. if (!isImage) {

  95. this.$message.error("上传文件类型必须是图片!");

  96. }

  97. const isLt2M = file.size / 1024 / 1024 < 2;

  98. if (!isLt2M) {

  99. this.$message.error("上传图片大小不能超过 2MB!");

  100. }

  101. return isImage && isLt2M;

  102. },

  103. onSumbit(form) {

  104. let vm = this;

  105. this.$refs[form].validate((valid)=>{

  106. if(valid){

  107. vm.$refs.upload.submit();

  108. }else{

  109. return false

  110. }

  111. })

  112. },

  113. },

2.2 node 后台

  1. //app.js
  2. // 定义写游记接口
  3. var multer = require('multer')
  4. var fs = require('fs')
  5. const upload = multer({ dest: __dirname + '/static/upload' })
  6. app.post('/newtravel', upload.single('file'), async (req, res) => {
  7. let file = req.file;
  8. let basePath = __dirname + '/static/upload/';
  9. let oldFileName = file.filename
  10. let newFileName = Date.now() + '.png'
  11. let filePath = basePath + oldFileName;
  12. let newFilePath = basePath + newFileName;
  13. if (fs.existsSync(basePath)) {
  14. fs.rename(filePath, newFilePath, (err) => {
  15. if (err) throw err
  16. })
  17. }
  18. let imgurl = 'static/upload/' + newFileName
  19. function settime(time = +new Date()) {
  20. var date = new Date(time + 8 * 3600 * 1000);
  21. return date.toJSON().substr(0, 19).replace("T", " ");
  22. }
  23. let formdata = {
  24. imgurl: imgurl,
  25. formtitle: req.body.formtitle,
  26. formconent: req.body.formconent,
  27. formtitle: req.body.formtitle,
  28. createtime: settime()
  29. }
  30. travelnotes_query.addNewTravelNote(formdata, function (rec) {
  31. res.json(rec).end();
  32. });
  33. })
  34.  
  35.  
  36. //travelnotes_query.js

  37. exports.addNewTravelNote = function (data, callback) {

  38. var arr = [];

  39. arr.push(data.formtitle);

  40. arr.push(data.imgurl);

  41. arr.push(data.formconent);

  42. arr.push(data.createtime);

  43. query('INSERT INTO travelnotes (formtitle,imgurl,formconent,createtime) VALUES (?,?,?,?)', arr, function (err, results, fields) {

  44. if (err) throw err;

  45. callback(results);

  46. });

  47. }

其他的内容一样

3、效果预览

vue使用elementUI组件提交表单(带图片)到node后台的更多相关文章

  1. java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例

    java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例HttpClient 测试类,提供get post方法实例 package com.zdz.httpclient; i ...

  2. java模拟post方式提交表单实现图片上传【转】

     转自:http://blog.csdn.net/5iasp/article/details/8669644 模拟表单html如下:   <form action="up_result ...

  3. vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单

    参考: ElementUI多个子组件表单的校验管理:https://www.jianshu.com/p/541d8b18cf95 Vue 子组件调用父组件方法总结:https://juejin.im/ ...

  4. vue 中跨组件的表单验证

    使用的是element写的,里面提供了表单验证. 子组件是这样的 <template> <div> <el-form :model="value" r ...

  5. Vue基础-自定义事件的表单输入组件、自定义组件的 v-model

    Vue 测试版本:Vue.js v2.5.13 学习 Vue 的自定义事件的表单输入组件,觉得文档讲的不太细致,所以这里再细化一下: 如果不用 v-model,代码应该是这样: <myinput ...

  6. 26.VUE学习之--提交表单不刷新页面,事件修饰符之使用$event与prevent修复符操作表单

    提交表单不刷新页面 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  7. Element-ui中为上传组件添加表单校验

    vue所依赖的Element的UI库在使用其中的upload组件时,可能很大几率会遇到这个题,需要给upload组件添加表单校验 大家这里直接看代码就可以 <el-form-item class ...

  8. vue.js中 ,回车键实现登录或者提交表单!

    vue的功能非常强大,但是我们作为一个后端开发人员,前端的东西不一定都弄的很明白,今天就给大家介绍一个回车提交表单的真实案例,达到回车登录的效果! @ keyup.enter 实现的效果 <in ...

  9. C#的提交表单方式主要有两种WebClient与HttpWebRequest

    根据黄聪:C#模拟网站页面POST数据提交表单(转) using System; using System.Collections.Generic; using System.IO; using Sy ...

随机推荐

  1. 查看 npm 的全局安装依赖包

    在控制台中输入以下指令可以直接查看 npm 全局安装的依赖包: npm list -g --depth 0

  2. NOI 2019 省选模拟赛 T1【JZOJ6082】 染色问题(color) (多项式,数论优化)

    题面 一根长为 n 的无色纸条,每个位置依次编号为 1,2,3,-,n ,m 次操作,第 i 次操作把纸条的一段区间 [l,r] (l <= r , l,r ∈ {1,2,3,-,n})涂成颜色 ...

  3. 2020牛客NOIP赛前集训营-提高组(第二场)- B.包含 (FWT)

    题面 题解 这题就是个快速沃尔什变换的模板题,输入ai时,令s[ai]=1,对s[]做一遍DWT_AND(s)(快速沃尔什正变换,按位与),然后直接访问s[x]完事. #include<map& ...

  4. 【java】学习路径41-使用缓冲输入输出复制文件

    结论:Buffered+数组 这种方式速度是最快的. public void testBufferedIO(String source,String target){ BufferedInputStr ...

  5. 牛客练习赛99—C

    数的和与积 https://ac.nowcoder.com/acm/contest/34330/C 思路: 2和4是不可以的,除了3意外其他的都可以用三项解决,其中一项为1,剩余两项分别设为x,y.  ...

  6. Linux虚拟机破解密码步骤

    Linux破解密码 重启系统 到达logo界面快速 按 e 编辑当前条目 将光标移至以 linux 开头的行,此为内核命令行 在UTF-8(RHEL7):ro(RHEL8)后添加 rd.break ( ...

  7. 聊聊 asp.net core 认证和授权

    使用asp.net core 开发应用系统过程中,基本上都会涉及到用户身份的认证,及授权访问控制,因此了解认证和授权流程也相当重要,下面通过分析asp.net core 框架中的认证和授权的源码来分析 ...

  8. byte[]数组转换string类型

    byte[] OutData = new byte[2048];//交易返回数据 string pBusiCardInfoStr = Encoding.Default.GetString(OutDat ...

  9. 第一个Java代码的编写 :HelloWorld代码的编写

    HelloWorld代码的编写 创建一个新的文件夹,通过Notepad++编写第一个Java程序 , 文件名为"Hello.java" 在文件中编写,如下代码: public cl ...

  10. 10. Fluentd部署:高可用配置

    对于高访问量的web站点或者服务,可以采用Fluentd的高可用配置模式. 消息分发语义 Fluentd设计初衷主要是用作事件日志分发系统的.这类系统支持几种不同的分发模式: 至多一次.消息被立即发送 ...