vue+nodejs+express+mysql 建立一个在线网盘程序

vue+nodejs+express+mysql 建立一个在线网盘程序

目录

  • vue+nodejs+express+mysql 建立一个在线网盘程序

    • 第一章 开发环境准备

      • 1.1 开发所用工具简介
      • 1.2 安装 MySQL
        • 1.2.1 下载安装 MySQL
        • 1.2.2 可能出现的问题和解决方案
      • 1.3 安装 vue-cli
      • 1.4 安装 express
    • 第二章 数据库设计和创建
      • 2.1 数据库和表设计
      • 2.2 user 表
      • 2.3 file 表
      • 2.4 创建数据库和表所用 sql 语句参考
    • 第三章 后台模块开发
      • 3.1 创建数据库连接
      • 3.2 创建表模型
      • 3.3 编写接口
        • 3.3.1 定义接口
        • 3.3.2 编写控制器文件
      • 3.4 接口测试
    • 第四章 前端模块开发
      • 4.1 安装并引入前端开发所需外部模块
      • 4.2 建立路由
      • 4.3 编写组件

代码戳这里--> code

第一章 开发环境准备

1.1 开发所用工具简介

主要开发所用工具:

  • MySQL、Express、NodeJS、Vue
  • 其他工具: element-ui、axios

1.2 安装 MySQL

1.2.1 下载安装 MySQL

参照: MySQL 安装 | 菜鸟教程

1.2.2 可能出现的问题和解决方案

1.提示:Found option without preceding group in config file:XXX; Fatal error in defaults handling.
解决方法:用电脑的记事本打开my.ini文件,将其另存为 ANSI 编码格式并替换原来的my.ini文件

2.提示:you must reset your password using ALTER USER statement before executing this statement.
解决方法:重新设置密码
在 mysql 环境下,输入alter user user() identified by "123456";退出 sql 重新登录即可。

1.3 安装 vue-cli

  1. 新建一个文件夹cloud-drive,在该文件下中使用 webpack 生成一个 vue 项目

参考代码如下:

mkdir cloud-drive
cd cloud-drive

cnpm install vue-cli -g
vue init webpack "client" //建立一个名称为client的前端项目
cnpm install // 安装依赖
npm run dev
  1. 在执行npm run dev后,在浏览器中输入http://localhost:8080/#后显示以下界面,则 client 项目生成完毕!

1.4 安装 express

1.在cloud-drive下建立一个文件夹,名称为 server,用于存放服务端的代码。

mkdir server
cd server
  1. server文件夹下利用npm init -f生成一个package.json文件.
  2. package.json文件添加启动项目代码
...
"scripts": {
    "start": "node src/app.js", // 加入这一条用于启动程序
    "test": "echo \"Error: no test specified\" && exit 1"
  },

...

4.在server文件夹下创建src文件夹,在src文件夹下创建app.js文件,在app.js写入以下信息用于测试

console.log('Hello World!');
  1. 执行npm start命令,输出信息如以下代表成功
Hello World!
  1. 安装 express 框架
npm install express --save
  1. 安装其他的依赖
npm install body-parser cors morgan nodemon multer md5 --save
  • body-parser 解析
  • cors 跨域
  • morgan 日志记录
  • nodemon 程序调试自启
  • multer 文件上传中间件
  • md5 生成 md5 码模块 8.将src/app.js用以下内容替代,该内容创建了一个运行于 8081 接口的服务器,建立了一个测试用接口,名称为 posts
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const morgan = require('morgan')

const app = express()
app.use(morgan('combined'))
app.use(bodyParser.json())
app.use(cors())

app.get('/posts', (req, res) => {
  res.send(
    [{
      title: "Hello World!",
      description: "Hi there! How are you?"
    }]
  )
})

app.listen(process.env.PORT || 8081)

9.修改package.json文件,采用 nodemon 启动

"scripts": {
    "start": "nodemon src/app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

10.使用npm start启动应用,在浏览器中访问localhost:8081/posts地址,如若成功,应该看到以下信息

至此,后端环境准备完毕

第二章 数据库设计和创建

2.1 数据库和表设计

  • 数据库名称:cloud_drive
  • 数据库表: user 表和 file 表

2.2 user 表

user 表:管理网盘注册用户信息

字段 中文释义 类型 是否为空 默认值 其他
uid 用户 id int(10) unsigned NO 主键 null auto_increment
username 用户名 varchar(20) NO null
password 密码 varchar(20) NO null

2.3 file 表

file 表:管理用户上传文件信息

字段 中文释义 类型 是否为空 默认值 其他
id 文件 id int(10) unsigned NO 主键 auto_increment
file_name 文件名称 varchar(255) NO null
hash_name 使用 hash 算法生成的文件名称 varchar(255) NO null
upload_time 上传时间 varchar(255) No null
type 文件类型 varchar(255) No null
size 文件大小 varchar(255) No null
download 下载次数 varchar(255) No null
uid 上传用户 id int(10) unsigned No 外键 null

2.4 创建数据库和表所用 sql 语句参考

  1. 创建数据库cloud_drive和表user语句
DROP DATABASE IF EXISTS cloud_drive;
CREATE DATABASE cloud_drive;
use cloud_drive;
DROP TABLE IF EXISTS user;
CREATE TABLE IF NOT EXISTS `user`(
   `uid` INT UNSIGNED AUTO_INCREMENT COMMENT '用户id',
   `username` VARCHAR(20) NOT NULL COMMENT '用户名',
   `password` VARCHAR(20) NOT NULL COMMENT '密码',
   PRIMARY KEY ( `uid` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '用户表';
  1. 创建用户上传文件表
use cloud_drive;
DROP TABLE IF EXISTS file;
CREATE TABLE `file`
(
    id int(10) AUTO_INCREMENT COMMENT '文件id',
    file_name varchar(200) NOT NULL COMMENT '文件名称',
    hash_name varchar(200) NOT NULL COMMENT '文件hash名称',
    upload_time DateTime NOT NULL COMMENT '上传时间',
    type varchar(20) NOT NULL COMMENT '文件类型',
    size varchar(20) NOT NULL COMMENT '文件大小',
    download varchar(50) NOT NULL COMMENT '下载次数',
    uid int unsigned COMMENT '用户id',
    PRIMARY KEY (id),
    foreign key(uid) references user(uid)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '上传文件表';

第三章 后台模块开发

3.1 创建数据库连接

  1. 创建/server/config/env.js文件
//  数据库连接参数
const env = {
  database: 'cloud_drive',
  username: 'root',
  password: '123456',
  host: 'localhost',
  dialect: 'mysql',
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};
module.exports = env;
  1. 创建/server/config/db.config.js文件
const env = require('./env.js');

const Sequelize = require('sequelize');
const sequelize = new Sequelize(env.database, env.username, env.password, {
  host: env.host,
  dialect: env.dialect,
  operatorsAliases: false,

  pool: {
    max: env.max,
    min: env.pool.min,
    acquire: env.pool.acquire,
    idle: env.pool.idle
  }
});

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

// 引入表模型
db.user = require('../model/user.model')(sequelize, Sequelize);
db.file = require('../model/file.model')(sequelize, Sequelize);

module.exports = db;

3.2 创建表模型

  1. 安装sequelize-auto模块,利用sequelize-auto模块自动生成 user 表模型和 file 表模型
npm install -g sequelize-auto
sequelize-auto -h localhost -d cloud_drive -u root -x 123456 -p 3306 -t user
sequelize-auto -h localhost -d cloud_drive -u root -x 123456 -p 3306 -t file

注意:此处生成的表模型需要根据实际进行调整

2.复制生成的/models/book.js文件,粘贴至/model目录下,并修改文件名后缀为.model.js,删除生成的models目录

3.3 编写接口

3.3.1 定义接口

  1. /server/route/user.route.js文件
//  用户
module.exports = function(app) {
  const user = require('../controller/user.controller');

  //  新增用户
  app.post('/user/add', user.create);

  //  根据用户名和密码查询用户
  app.post('/user/validate', user.validate);

  //  修改密码
  app.put('/user/update/:userId', user.updatePassWord);
};

  1. /server/route/file.route.js文件
//  文件
module.exports = function(app) {
  const file = require('../controller/file.controller');

  //  新增文件
  app.post('/file/add', file.create);

  //  删除文件
  app.delete('/file/delete/:fileName/:fileId', file.delete);

  // 下载文件
  app.get('/file/download/:fileName/:fileId', file.download);

  // 获取文件信息列表
  app.post('/file/list', file.findAll);
};

3.3.2 编写控制器文件

  1. /server/controller/user.controller.js文件
const db = require('../config/db.config.js');
const User = db.user; //  引入表模型
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
//  新增用户
exports.create = (req, res) => {
  if (req.body.username && req.body.password) {
    User.create(req.body)
      .then(user => {
        let msg = {};
        if (user) {
          msg = {
            flag: 1,
            msg: '注册成功!',
            uid: user.uid,
            username: user.username
          };
        } else {
          msg = {
            flag: 0,
            msg: '注册失败,请稍后注册'
          };
        }
        res.status(200).json(msg);
      })
      .catch(err => {
        res.status(500).json('Error -> ' + err);
      });
  } else {
    let msg = {
      flag: 0,
      msg: '用户名或者密码不能为空!'
    };
    res.status(200).json(msg);
  }
};

//  验证用户名和密码
exports.validate = (req, res) => {
  if (req.body.username && req.body.password) {
    User.findOne({
      where: {
        [Op.and]: [
          {
            username: req.body.username
          },
          [
            {
              password: req.body.password
            }
          ]
        ]
      },
      attributes: ['uid', 'username']
    })
      .then(user => {
        let msg = {};
        if (user) {
          msg = {
            flag: 1,
            msg: '用户名和密码正确!',
            uid: user.uid,
            username: user.username
          };
        } else {
          msg = {
            flag: 0,
            msg: '用户名或密码错误!'
          };
        }

        res.status(200).json(msg);
      })
      .catch(err => {
        res.status(500).json('Error -> ' + err);
      });
  } else {
    let msg = {
      flag: 0,
      msg: '用户名或者密码不能为空!'
    };
    res.status(200).json(msg);
  }
};

//  修改密码
exports.updatePassWord = (req, res) => {
  User.findOne({
    where: {
      [Op.and]: [
        {
          uid: req.params.userId
        },
        {
          password: req.body.oldPassword
        }
      ]
    }
  }).then(user => {
    if (user) {
      User.update(
        {
          password: req.body.newPassword
        },
        {
          where: {
            uid: req.params.uid
          }
        }
      ).then(() => {
        let msg = {
          flag: 1,
          msg: '修改密码成功!'
        };
        res.status(200).json(msg);
      });
    } else {
      let msg = {
        flag: 0,
        msg: '密码不正确!'
      };
      res.status(200).json(msg);
    }
  });
};

  1. /server/controller/file.controller.js文件
const db = require('../config/db.config.js');
const File = db.file; //  引入表模型
const Sequelize = require('sequelize');
const Op = Sequelize.Op;
const path = require('path');
const fs = require('fs');

//  添加文件
exports.create = (req, res) => {
  let params = {
    file_name: req.files[0].originalname,
    hash_name: req.files[0].filename,
    upload_time: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString(),
    type: path.parse(req.files[0].originalname).ext,
    size: req.files[0].size,
    download: 0,
    uid: req.body.uid
  };
  File.create(params)
    .then(file => {
      if (file) {
        let msg = {
          flag: 1,
          msg: '文件上传成功!'
        };
        res.status(200).json(msg);
      } else {
        let msg = {
          flag: 0,
          msg: '文件上传失败,请稍后重新上传!'
        };
        res.status(500).json(msg);
      }
    })
    .catch(err => {
      res.status(500).json('Error->' + err);
    });
};

//  删除文件
exports.delete = (req, res) => {
  const id = req.params.fileId;
  File.destroy({
    where: { id: id }
  })
    .then(_ => {
      //  从资源文件夹从删除
      let fileName = req.params.fileName;
      let path = `${__dirname}/../resource/${fileName}`;
      fs.unlink(path, err => {
        if (err) {
          let msg = {
            flag: 0,
            msg: '删除失败!'
          };
          res.status(200).json(msg);
        } else {
          let msg = {
            flag: 1,
            msg: '删除成功!'
          };
          res.status(200).json(msg);
        }
      });
    })
    .catch(err => {
      res.status(500).json('Error=>', err);
    });
};

//  下载文件
exports.download = (req, res) => {
  let fileId = req.params.fileId;
  File.findById(fileId).then(file => {
    file
      .increment('download')
      .then(file => {
        let fileName = req.params.fileName;
        let path = `${__dirname}/../resource/${fileName}`;
        res.download(path, fileName);
      })
      .catch(err => {
        res.status(500).json('Error=>', err);
      });
  });
};

//  获取文件列表信息
exports.findAll = (req, res) => {
  File.findAll({
    where: { uid: req.body.uid }
  })
    .then(file => {
      res.status(200).json(file);
    })
    .catch(err => {
      res.status(500).json('Error=>', err);
    });
};

3.4 接口测试

使用 postman 进行测试(略)

第四章 前端模块开发

4.1 安装并引入前端开发所需外部模块

  1. 安装axios模块
  • npm install axios --save
  • 编写文件src/utils/http.js,并引入封装好的 axios 类
import axios from 'axios'

let httpInstance = axios.create()

httpInstance.defaults.baseURL = 'http://localhost:8081/'
httpInstance.defaults.timeout = 5000

httpInstance.formurl = (url, data, config) => {
  return httpInstance.post(url, data, {
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    ...config
  })
};

//  request拦截器
httpInstance.interceptors.request.use(
  config => {
    console.log(config)
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
//  reponse拦截器
httpInstance.interceptors.response.use(
  response => {
    if (response.status === 200) {
      return Promise.resolve(response)
    }
  },
  error => {
    return Promise.reject(error)
  }
)
export default httpInstance
  • main.js中引入http.js文件,并将其注册为 vue 全局变量
import http from './utils/http'
Vue.prototype.$http = http;
  1. 安装element-ui模块
  • npm install element-ui --save
  • main.js中引入element-ui模块
  import ElementUI from 'element-ui'
  import 'element-ui/lib/theme-chalk/index.css'
  Vue.use(ElementUI)

4.2 建立路由

  1. 建立文件 在components 下新建文件如下,并删除原有的HelloWorld.vue文件。
  • file-list.vue: 已上传文件列表界面
  • file-upload.vue:上传文件界面
  • index.vue:登录注册界面
  • tab-list.vue:tab 页
  • user-set.vue:用户设置界面
  1. 修改路由 在 router/main.js 中将路由修改如下
import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index'
import list from '@/components/tab-list'

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: index
    },
    {
      path: '/tab-list',
      name: 'tab-list',
      component: list
    }
  ]
})
//  校验登录
router.beforeEach((to, from, next) => {
  if (to.name === 'tab-list') {
    if (!sessionStorage.username) {
      window.alert('您的登录信息无效或过期,请重新登录')
      return window.location.replace('/')
    } else {
      next()
    }
  } else {
    next()
  }
})
export default router
  1. 删除App.vue文件中以下代码
<img src="./assets/logo.png">
  1. index.vue中写入以下代码:
<template>
  <div>
    Hello World!
  </div>
</template>
<script>
export default {}
</script>
<style scoped>
</style>
  1. 使用npm start运行项目,在浏览器中访问,则会出现npm start的文字

4.3 编写组件

1.index.vue登录注册界面
(1)界面预览


(2)代码编写

<template>
  <div class="index">
    <div class="title">
      在线网盘系统
    </div>
    <div class="label">
      Cloud Driver
    </div>
    <div class="btn">
      <el-button type="primary"
        @click="dialogFormVisible = true">登录/注册</el-button>
    </div>
    <el-dialog title="登录/注册"
      :visible.sync="dialogFormVisible"
      width="400px">
      <el-form :model="form">
        <el-form-item label="用户名"
          :label-width="formLabelWidth">
          <el-input v-model="form.username"
            autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="密码"
          :label-width="formLabelWidth">
          <el-input v-model="form.password"
            autocomplete="off"
            type="password"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer"
        class="dialog-footer">
        <el-button @click="signUp">注 册</el-button>
        <el-button type="primary"
          @click="signIn">登 录</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  name: 'index',
  data () {
    return {
      dialogFormVisible: false,
      form: {
        username: '',
        password: ''
      },
      formLabelWidth: '120px'
    }
  },
  methods: {
    // 登录
    signIn () {
      this.dialogFormVisible = false
      this.$http
        .post('/user/validate', this.form)
        .then(res => {
          if (res.data.flag === 0) {
            this.$message.error(res.data.msg)
          } else {
            this.$message.success(res.data.msg)
            sessionStorage.setItem('uid', res.data.uid)
            sessionStorage.setItem('username', res.data.username)

            //  跳转到其他页面
            this.$router.push('tab-list')
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    //  注册
    signUp () {
      this.dialogFormVisible = false
      this.$http
        .post('/user/add', this.form)
        .then(res => {
          if (res.data.flag === 0) {
            this.$message.error(res.data.msg)
          } else {
            this.$message.success(res.data.msg)
            this.$router.push('tab-list')
          }
        })
        .catch(err => {
          console.log(err)
        })
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.index {
  margin-top: 80px;
  text-align: center;
}
.title {
  font-size: 60px;
}
.label {
  font-size: 40px;
  margin-top: 10px;
}
.btn {
  margin-top: 10px;
}
.dialog-footer {
  text-align: center;
}
</style>
  1. tab-list.vue选项卡切换界面
    (1)界面预览

    (2)代码
<template>
  <div class="show">
    <base-header></base-header>
    <el-tabs v-model="tabActivedName"
      class="tab"
      @tab-click="handleClick">
      <el-tab-pane v-for="(item, index) in componentList"
        :key="index"
        :label="item.tabLabel"
        :name="item.tabName">
        <component :is="item.compoName"
          v-if="tabActivedName===item.tabName"></component>
      </el-tab-pane>
    </el-tabs>
    <base-footer></base-footer>
  </div>
</template>

<script>
import BaseHeader from '../layout/header';
import BaseFooter from '../layout/footer';
import UploadFile from './file-upload';
import FileList from './file-list';
import userSet from './user-set';
export default {
  name: 'show',
  components: {
    BaseHeader,
    BaseFooter,
    UploadFile,
    FileList,
    userSet
  },
  data () {
    return {
      tabActivedName: 'second',
      componentList: [
        {
          tabName: 'first',
          compoName: 'upload-file',
          tabLabel: '上传文件'
        },
        {
          tabName: 'second',
          compoName: 'file-list',
          tabLabel: '文件列表'
        },
        {
          tabName: 'third',
          compoName: 'user-set',
          tabLabel: '用户设置'
        }
      ]
    }
  },
  methods: {
    handleClick (tab, event) {
      console.log(tab, event)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.tab {
  min-height: 400px;
  padding: 20px 40px;
}
</style>

3.file-upload文件上传组件
(1)界面预览

(2)代码

<template>
  <el-upload drag
    multiple
    action="http://localhost:8081/file/add"
    :data="userInfo"
    :on-success="dealSuccess"
    :on-error="dealError">
    <i class="el-icon-upload"></i>
    <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  </el-upload>
</template>
<script>
export default {
  data () {
    return {
      userInfo: {
        uid: sessionStorage.getItem('uid')
      }
    }
  },
  methods: {
    dealSuccess () {
      this.$message.success('上传文件成功!')
    },
    dealError () {
      this.$message.error('上传文件失败,请重新上传!')
    }
  }
}
</script>
<style scoped>
</style>
  1. file-list.vue文件上传列表组件
    (1)界面预览

    (2)代码
<template>
  <div>
    <el-table :data="tableData"
      :cell-style="{'text-align':'center'}"
      :header-cell-style="{'text-align':'center'}"
      style="width: 100%">
      <el-table-column type="index">
      </el-table-column>
      <el-table-column prop="file_name"
        label="文件名"
        width="180px">
      </el-table-column>
      <el-table-column prop="size"
        label="文件大小"
        width="180px"
        :formatter="dealSize">
      </el-table-column>
      <el-table-column prop="upload_time"
        label="上传时间"
        width="180px"
        :formatter="dealTime">
      </el-table-column>
      <el-table-column prop="download"
        label="下载次数"
        width="180px">
      </el-table-column>
      <el-table-column prop="type"
        label="类型"
        width="180px">
      </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <a :href="getFile(scope.row)">
            <el-button size="mini"
              type="info"
              @click="handleDownload">下载</el-button>
          </a>
          <el-button size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data () {
    return {
      tableData: []
    }
  },
  methods: {
    handleDelete (index, row) {
      this.$http
        .delete(`/file/delete/${row.hash_name}/${row.id}`)
        .then(res => {
          this.$message.success(res.data.msg)
          this.refreshFileList()
        })
        .catch(err => {
          console.log('Error=>', err)
        })
    },
    handleDownload () {
      setTimeout(() => {
        this.refreshFileList()
      }, 1000)
    },
    refreshFileList () {
      this.getFileList()
    },
    getFileList () {
      let params = {
        uid: sessionStorage.getItem('uid')
      }
      this.$http
        .post('/file/list', params)
        .then(res => {
          if (res.data.code === 0) {
            this.$message.error(res.data.msg)
          } else {
            this.tableData = res.data
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    getFile (data) {
      let url = `http://localhost:8081/file/download/${data.hash_name}/${
        data.id
      }`
      return url
    },
    dealSize (row, column) {
      let fileSize = (row.size / 1024).toFixed(2)
      return `${fileSize}kb`
    },
    dealTime (row, column) {
      return this.formatTime(row.upload_time)
    },
    formatTime (value) {
      var date = new Date(value)
      var Y = date.getFullYear()
      var M =
        date.getMonth() + 1 < 10
          ? `0${date.getMonth() + 1}`
          : date.getMonth() + 1
      var D = date.getDate() < 10 ? `0${date.getDate()}` : date.getDate()
      var h = date.getHours() < 10 ? `0${date.getHours()}` : date.getHours()
      var m =
        date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes()
      var s =
        date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds()
      return `${Y}-${M}-${D} ${h}:${m}:${s}`
    }
  },
  mounted () {
    this.getFileList()
  }
}
</script>
  1. user-set.vue用户设置组件
<template>
  <div>
    <el-form :model="ruleForm"
      status-icon
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="change-password">
      <el-form-item label="原密码"
        prop="oldPass">
        <el-input type="password"
          v-model="ruleForm.oldPass"
          autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="新密码"
        prop="newPass">
        <el-input type="password"
          v-model="ruleForm.newPass"
          autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="确认新密码"
        prop="checkNewPass">
        <el-input type="password"
          v-model="ruleForm.checkNewPass"
          autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary"
          @click="submitForm('ruleForm')">提交</el-button>
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  data () {
    //  验证原密码
    let validateOldPass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入密码'))
      } else {
        if (this.ruleForm.oldPass !== '') {
          this.$refs.ruleForm.validateField('newPass')
        }
        callback()
      }
    }
    //  验证新密码
    var validateNewPass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入新密码'))
      } else if (value === this.ruleForm.oldPass) {
        callback(new Error('新旧密码不能相同!'))
      } else {
        callback()
      }
    }
    //  验证再次输入密码

    var validateCheckNewPass = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请再次输入密码'))
      } else if (value !== this.ruleForm.newPass) {
        callback(new Error('两次输入密码不一致!!'))
      } else {
        callback()
      }
    }

    return {
      ruleForm: {
        oldPass: '',
        newPass: '',
        checkNewPass: ''
      },
      rules: {
        oldPass: [{ validator: validateOldPass, trigger: 'blur' }],
        newPass: [{ validator: validateNewPass, trigger: 'blur' }],
        checkNewPass: [{ validator: validateCheckNewPass, trigger: 'blur' }]
      }
    }
  },
  methods: {
    submitForm (formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          let params = {
            oldPassword: this.ruleForm.oldPass,
            newPassword: this.ruleForm.newPass
          }
          this.$http
            .put(`/user/update/${sessionStorage.uid}`, params)
            .then(res => {
              this.$message.success('修改密码成功!请重新登录')
              sessionStorage.clear()
              setTimeout(() => {
                this.$router.push({ path: '/' })
              }, 1000)
            })
            .catch(err => {
              console.log('Error=>', err)
            })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    resetForm (formName) {
      this.$refs[formName].resetFields()
    }
  }
}
</script>
<style scoped>
.change-password {
  width: 400px;
  margin: 10px auto;
}
</style>

原文地址:https://www.cnblogs.com/yejingping/p/10436522.html

时间: 2024-07-28 14:32:12

vue+nodejs+express+mysql 建立一个在线网盘程序的相关文章

Nodejs+express+mysql+百度BAE部署node后台

转载请注明出处:http://www.cnblogs.com/shamoyuu/p/node_bae.html 百度有一个应用引擎,价格非常便宜,Java的tomcat每天4毛钱,node每天2毛钱,我以前在上面搭建过一个JavaWeb的项目,今天来说说怎么搭建nodejs+express+mysql的后台. 首先打开console.bce.baidu.com,注册登录完成,然后新建一个应用引擎BAE如下图进行设置 目前基础版的BAE只支持node4.4.4,不过应该已经足够了.如果是用koa2

NodeJS+Express+MySQL开发小记(2):服务器部署

http://borninsummer.com/2015/06/17/notes-on-developing-nodejs-webapp/ NodeJS+Express+MySQL开发小记(1)里讲过在本地搭建 NodeJS 网站的若干细节.本人最近在阿里云服务器上面按最低配租了4个月的云服务器,所以想试着把这个项目部署到云上.云服务器操作系统是Ubuntu 14.04 LTS.之前一直在Windows下做开发,对于Linux下的环境搭建.配置还不是很熟悉,搭建的过程中学到很多东西. 本文简单记

nodejs+express+mysql 增删改查

之前,一直使用的是nodejs+thinkjs来完成自己所需的项目需求,而对于nodejs中另外一中应用框架express却了解的少之又少,这两天就简单的了解了一下如何使用express来做一些数据库的增删改查. 准备工作: 所需工具:电脑上要安装好nodejs(官网https://nodejs.org/en/),下载并安装好nodejs之后,需要在cmd中再安装好express框架: npm install express-generator -g 安装完毕之后,检查一下是否安装成功: 还有一

进入全屏 nodejs+express+mysql实现restful风格的增删改查示例

首先,放上项目github地址:https://github.com/codethereforam/express-mysql-demo 一.前言 之前学的java,一直用的ssm框架写后台.前段时间接触到node.js,于是花了两天时间学了一下node.js并写了一个CRUD简单示例.由于前几天一直学用github pages搭建博客,一直没时间写README,今天有空补了上来. 下面来内容自于项目的README. 二.项目介绍 基于node.js + express + mysql实现的re

Eclipse 建立一个简单地JAVA程序

第一步 建立一个JAVA工程 File->New->JAVA Project 图1 点击 Finish 第二步 建立一个类文件 右击工程文件名 Myjava->New->Class 图2 点击Finish 出现编辑界面 如图 第三步 编辑代码 如图 第四步 执行工程 右击工程文件 Myjava->Run as->JAVA Application 弹出图 点击OK,显示输出如下

基于nodejs+express+mysql+webstorm+html的 增删改查

一.工具准备 Nodejs框架,WebStorm.Mysql服务.Navicat.此篇文章只讲项目的搭建过程,至于Nodejs,WebStorm.Mysql的下载.安装与配置网上资源很多,请自行查阅,本文重点讲述 增删改查,此文为学习笔记,我也是初学者,很多代码没有做过多解释,以免误导他人. Github 地址:https://github.com/Spqin/Nodejs_Websto_Mysql_CRUD 二.打开WebStorm创建项目-项目名称自定义,这里我按年月日做项目名称. 1.选怎

最新的chart 聊天功能( webpack2 + react + router + redux + scss + nodejs + express + mysql + es6/7)

请表明转载链接:http://www.cnblogs.com/zhangkunweb/p/6853728.html 我是一个喜欢捣腾的人,没事总喜欢学点新东西,可能现在用不到,但是不保证下一刻用不到. 我一直从事的是依赖angular.js 的web开发,但是我怎么能一直用它呢?看看最近火的一塌糊涂的reactjs ,我的天啊,不学会它,怎么能睡好觉. 今天我分享一个依赖最新版本的webpack + react + router + redux + scss + nodejs + mysql +

nodeJS+express+Jade写一个局域网聊天应用(node基础)

为了复习一下nodeJS, 而且socketIO这东西听起来就好高端有木有, 而且有人写过了open, 也可以作为自己的参考有木有, 点击下载源代码: express是4.x的版本, 跟以前的配置有些区别, 我才不管呢, 好用就好>﹏<; 按照正常的流程通过 node install 安装项目依赖, 项目的依赖如下; "dependencies": { "body-parser": "~1.8.4", "cookie-par

nodejs+express+mysql 之 简单的在线HTML编辑器

1.从原网站下载源码:http://kindeditor.net/demo.php 2.将kindeditor放到项目内,使其能够完成基本功能 1).将plugins.themes.lang.kindeditor-min.js放到public/kindeditor/下 2).在views下创建文件editor.ejs,内容为 <script src="/kindeditor/kindeditor-min.js" type="text/javascript"&g