首先祝大家1024程序员节节日快乐!写篇博客记录一下这个特别的节日!
相信有很多小伙伴写用户管理系统的项目都想实现这样一个功能,就是用户注册可以上传自己的头像,然后把用户信息和头像一起写入数据库,当用户登录成功后可以显示当前用户的头像。
我能想到的第一个方法是先把用户选择的图片通过base64
转码,然后把用户信息和转码后的一大串字符串一起写入数据库,用户登录成功后再取出来并交给img
标签解析。这个方法的缺点也很明显,性能肯定是大打折扣的,而且转码后的文件会占用很多存储空间,无法存储大图片。第二个办法就是配置一个图床,把图片的网络地址存进数据库里面,通过这个地址来访问图片。
下面我写一下第一个方法吧(主要是不会第二个),先上一张登录后的效果图:
一、注册页面
这个大家根据自己的需求设计注册页面,我写的就比较简单,只需要上穿头像,填写同户名和手机号码,给大家展示一下我写的
页面代码如下:
<template>
<div>
<div class="backbtn">
<i class="el-icon-arrow-left" @click="goBack()"></i>
</div>
<el-form :model="userForm" ref="userForm" label-width="15vw">
<el-form-item label="头像">
<label for="img_upload"> <!-- 通过label标签触发选择文件的输入框 -->
<el-avatar v-if="!userForm.imgbase" icon="el-icon-user-solid"></el-avatar>
<el-avatar v-if="userForm.imgbase" :src="userForm.imgbase"></el-avatar>
</label>
<input type="file" id="img_upload"/> <!-- 可以把这个标签隐藏,因为它丑... -->
</el-form-item>
<el-form-item label="用户名" prop="uname">
<el-input v-model="userForm.uname"></el-input>
</el-form-item>
<el-form-item label="手机号码" prop="phonenum">
<el-input v-model="userForm.phonenum"></el-input>
</el-form-item>
<div class="regbtn">
<div class="zhuce" @click="onSubmit()">立即注册</div>
</div>
</el-form>
</div>
</template>
二、设计用户数据库(重点)
我们要设计一张用户表来存放用户的信息,因为我是以用户名和手机号码注册的,所以表结构也很简单,里面的imgbase
字段用来存放图片转码后的字符串,注意这个类型要选择blob
或者text
,因为我们要存放一个超级长的字符串。
三、node连接和操作数据库(重点)
1.编写db.js文件,用来连接数据库
const mysql = require('mysql');
const pool = mysql.createPool({
host: '',
port: 3306,
user: '',
password: '',
database: ''
})
// promise 控制对象
module.exports = (sql, params) => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) throw err;
connection.query(sql, params, (err, result, fields) => {
connection.release(); // 释放连接
if (err) reject(err);
resolve(result)
})
})
})
}
2.编写routes.js文件,用来操作数据库
const express = require('express');
const router = express.Router();
const sql = require('../db.js');
router.post('/register', (req, res) => {
if (req.body) {
sql('insert into users (uname, phonenum, imgbase) values (?, ?, ?)',
[req.body.uname, req.body.phonenum, req.body.imgbase])
.then((result) => {
if (result.affectedRows > 0) {
res.json({ code: 200, data: '新增成功' })
} else {
res.json({ code: 400, data: '新增失败' })
}
})
.catch(() => {
res.json({ code: 500, data: '程序错误' })
})
}
})
四、图片转码并回显
先在data
里写一个表单对象,在mounted
函数里添加一个监听事件,通过FileReader()
读取文件信息,如果不熟悉的话可以先打印出来康康是什么
data() {
return {
userForm: {
uname: '',
phonenum: '',
imgbase: ''
}
}
},
mounted() {
let _this = this;
let img_upload = document.getElementById("img_upload"); // 获取文件框
img_upload.addEventListener('change', function readFile() {
let file = this.files[0];
if(!/image\/\w+/.test(file.type)) {
alert("请确保文件为图像类型");
return false;
}
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
_this.userForm.imgbase = this.result;
}
},false);
}
注意这里需要定义一个_this
,让它代表vue全局变量,从而把vue和监听事件中的this
区分开。
五、发送post请求
通过点击注册按钮触发请求
methods: {
onSubmit() {
if (this.userForm.uname !== '' && this.userForm.phonenum !== '') {
this.$http.post('/api/register', this.userForm)
.then(({data, config}) => {
console.log(data, config)
if (data.code == 200) {
this.$message({
message: '注册成功',
type: 'success'
});
this.$router.push('/login')
} else {
this.$message({
message: '注册失败',
type: 'warning'
})
}
})
} else {
this.$message({
message: '请输入用户名和手机号码!',
type: 'warning'
})
}
}
}
开启node服务,然后运行项目,成功!
如果选择的头像文件太大就会报错,这个时候换一张小点儿的就OK!
好啦,以上就是所有内容,如有疑惑或者意见欢迎大家提出!一起进步!