本文是基于koa2+vue+mongodb搭建的留言板项目,koa2作为后端框架,vue+ui-element作为前端框架,mongodb提供数据库服务,目前尚未写完,敬请期待
https://molunerfinn.com/Vue+Koa/#JSON-WEB-TOKEN
说明:以上依赖导入的时候,有些是项目搭建的时候自带,有些是npm i 安装自己选择的版本,有些是npm install xxx 时候自带的版本,且我列出的是较为重要的依赖!
使用koa-generator来搭建后端koa2框架
输入:
npm install -g koa-generator
输入:
koa2 mydemo
这里的mydemo你可以换成你自己的项目名
创建完项目之后初始化
cd mydemo
npm install
npm start
或者
npm run dev
打开浏览器访问localhost:3000显示“welcome to koa2” 则说明创建成功
输入:
npm install -g vue-cli
输入:
vue init webpack vue-demo
一路回车
这里的mydemo你可以换成你自己的项目名
创建完项目之后初始化
cd vue-demo
npm install
npm run dev
打开浏览器访问localhost:8080显示出页面 则说明创建成功
在mydemo下新建一个文件夹db用于存放连接数据库的相关文件,分别创建db.js,db_connect.js
db_connect.js:中写入以下代码
const conn={
dbUrl:'mongodb://ip:端口/数据库'
}
db.js
const mongodb=require('mongodb')
const MongoC=mongodb.MongoClient
const config=require(./db_connect)
//关键连接代码如下
connect(){
const that=this
return new Promise((resolve,reject)=>{
if(!that.dbClient){
MongoC.connect(config.dbUrl,async(err,client)=>{
if(err){}
else{
that.dbClient.db(Config.dbName)
resolve(that.dbClient)
}
})
}
else{
resolve(that.dbClient)
}
})
}
接下来写你想写的查询方法
基础写法为:
//name:要查询的集合
//json:查询的条件
async find(name,json){
const db=await this.connect()
const result=await db.cpllection(name).find(json)
}
要注意的是这些都在一个class里面
async find(sql){
const result=await db.find('user',sql)
return await result
}
const user=requir(../domain/user)
const login=async(ctx,next)=>{
const user=new user()
const username={username:ctx.request.body.username}
.
.
//查找用户
const userinfo=await user.find(username)
.
.
//返回内容
ctx.body={
.
.
}
}
const r=require('koa-router')()
const u=导入user_controller.js
r.post('/api/login',u.login);
app.use(index.routes(),index.allowedMethods())
app.use(router.routes(),router.allowedMethods())
我们都知道用户信息包括密码都是存储在数据库中的,那么如果这个数据库不小心被攻破,那么用户信息便会被一览无余。但是如果我们将保存在数据库中的密码进行加密,那么即使数据库被攻破,用户信息也可以得到保护
const bcrypt=require('bcryptjs')
const encrypt=password =>{
let salt=bcrypt.genSaltSync(5)
let hash=bcrypt.hashSync(password,salt)
return hash
}
const decrypt =(password,hash) =>{
return bcrypt.compareSync(password,hash)
}
module.exports ={
encrypt:encrypt,
decrypt :decrypt
}
import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
Vue.use(ElementUI) // Vue全局使用
<template>
<el-row class="content">
<el-col :span="12">
<el-row >
<el-input
v-model="username"
placeholder="用户名"
type="text">
</el-input>
<el-input
v-model="password"
placeholder="密码"
type="password">
</el-input>
<el-button type="primary">登录</el-button>
</el-row>
</el-col>
</el-row>
</template>
<script>
export default {
data () {
return {
username: '',
password: ''
};
},
methods:{
//这里写处理的方法
}
};
</script>
这里需要注意的是,整个中只能有一个子元素。我的常用解决办法是把整个用div包裹起来!
首先安装vue-router
npm install vue-router
在main.js中挂载路由
import VueRouter from 'vue-router'
Vue.use(VueRouter);
import Login from `./components/Login`
const router = new VueRouter({
base: __dirname,
routes: [
{
path: '/', // 设置打开的第一页为Login
component: Login
},
{
path: '*',
redirect: '/' // 输入其他错误的地址直接返回到Login即首页
}
]
})
接着在App.vue中改写内容,添加路由视图
<template>
<div id="app">
<router-view></router-view> //注册路由视图
</div>
</template>
<script>
export default {
name: 'app'
}
</script>
在浏览器的端口后加上/Login即可跳转到登录页面,不过我们设置了首页即是登录界面,所以这里不会有声明效果。此时你可以创建一个登陆成功的界面,按照上述步骤配置路由,然后在Login中增加一个按钮。具体如下:
<el-button type="primary" @click="LoginSuccess">登录</el-button>
methods: {
LoginSuccess() {
this.$router.push('/LoginSuccess') // 这个方法可以跳转页面,还可以传递参数,这个后面讲。
}
}
为什么要登录拦截,假设我们以上的LoginSuccess页面没有设置登录拦截的话,我们可以在浏览器的地址栏中输入ip:端口/LoginSuccess来进行访问,非常的不安全。很多框架都会有登录拦截的功能实现。那么在vue中如何实现呢!具体步骤如下:
//在main.js中将之前的路由代码改动一下
routes: [
{
name:'LoginSuccess',
path: 'LoginSuccess',
meta:{
requireAuth:true //需要进行登录判断
}
}
]
//在全局钩子函数中进行登录拦截
router.beforeEach((to,from,next) =>{
const token = sessionStorage.getItem('username');
if(to.meta.requireAuth ){ // 如果是需要进行登录判断的
if(token != 'null' && token != null){
next() // 如果有token就按照页面规则跳转
}
next({path:'/Login'}); // 否则跳转回登录页
}else{
next()
}
})
前端和后端的服务器并不在同一个域内,也就是服务端服务跑在3000端口,客户端(vue)端口跑在8080端口就会产生跨域问题,前端无法请求到后端!
解决办法:
打开根目录下的config/index.js-dev-proxyTable,改写这个proxyTable,够将跨域请求变成同域请求。
proxyTable: {
'/api':{
target: 'http://localhost:3000',
changeOrigin: true
}
}
这样讲/api/Login的请求转发到http://localhost:3000/Login,实现跨域!
前端的
将图像发到后端解析,将图片保存到后端存储,前端采取ip+img地址进行展示。
UI-Element开发文档
待续(有人看就写!)主键,
表名:msg
字段 | 含义 |
---|---|
msgid | 这里使用koa的uuid自动生成 msgid |
msgtime | 这里使用koa的silly-datatime 生成时间 |
PID | 父亲留言的msgid |
toWho | 这条留言是给谁的 |
fromWho | 这条留言是来自于谁的 |
RootID | 最原始的msgid,在主留言下留言则PID和RootID都为主留言的msgid |
UnReadMsg | 未读消息 |
待续
首先导入koa-history-api-fallback依赖,然后在app.js中引入依赖,然后app.use()
需要注意的是在app.js中对koa-history-api-fallback的使用和静态文件的引入都需要放在路由声明之后
声明在前,这个方法是我自己尝试出来的,目前我测试暂无问题。 实现方法如下:
在页面加载的时候他会执行几个默认的函数,这里我们用到其中一个created方法,也就是在页面加载的时候进行的动作
created: function(){
这里对你这个页面要用到的数据进行初始化,比如
this.msgid=...
this.mymsg=存储在sessionStorage里面的值等等
}