说明

vue2 学习项目仓库地址

里面有两个 vue2 项目,一个匹配的 javaee 项目。

vue2_websocket_project 是一个网页聊天室,实现了及时聊天。后端是波波老师写的,部署到服务器时用的是他的数据库,貌似被他删了,现在没有功能了。

点击查看效果 vue2_websocke_project

vue2_music_web_project 是基于上面项目修改的,扩展了不少东西,javaee_music_web 就是它配套的后端项目。

这个项目是暑假实训的作业,后端项目是基本的 javaee 写的,主要由另外一位同学实现。封装了数据库的操作与 dao 层,为了前后端分离,处理了 serlvet 接受和发送 json 数据。

我只写了用户歌单和音乐评分,这里用户和音乐涉及到一个多对多的关系,所以自己想实现一下。

部署了,现在还阔以使用,后端放在森林老师的服务器上的,9 月可能就挂了…

对了,安全性很差,也涉及到了管理员。(真是教科书版的学生项目,啥都要来个管理员…)

话说写了好几次增删改查了,虽然不至于每次都是重复之前做的事,但是确实没有太大的进步,这次仍然没尝试对密码加密,做下后端验证码。(因为没时间了,我写了个前端验证码。囧)

多说两句。前后端通过 api 来请求,好在开始前考虑到了 api 设计,/api/song/xxxx/api/user/xxxx/api/manager/xxxx

后端写拦截器的时候(fillter,森林老师写的),还是实现了后台管理的拦截。(前端也要写路由拦截!!这个先不提。)

但是写的时候为了复用,搞了个通用的 /api/user/getUserInfo ,导致随便 get 请求一下,就能看到别人的密码,以及其他信息…

所以下次做的时候,涉及到 get 隐私信息,后端应该判断下权限,而且不能再这样偷懒“复用”了。

另外在封装 jdbc 操作时没处理好。写了一个通用的方法,传参 sql 的参数与 sql 语句,这样减少了不少重复步骤,但是 select 只能返回对象的集合。我在写评分的时候,需要 select 评分人数,本来可以 count() 统计,但是用这个方法就必须先获取集合,再用 size() 取数目…

点击查看 vue2_websocke_project

对了,实现了头像上传。

图片在本地储存和服务器端储存有很大变化,本地不提,储存到服务器是通过在 tomcat 新开一个文件夹,专门储存图片,然后这里的图片就能被外部访问了。

前端快速搭建

下面就是快速搭建前端项目的步骤…

一堆名词

node.js

webpack(打包工具)

npm,yarn(包管理工具)

es6

vue

单页应用

前言

如果能够对上面的几个名词有了解(不需要深入,知道它们是用来干啥的就阔以了),就可以以下面的过程快速搭建一个 vue 单页应用了。

下面只是很简单的步骤,作为一个备份方便以后使用。

PS:使用的是 vue-cli2,没想到放个暑假就出 3 了…嘛也

vue-cli 简单搭建一个应用

确保环境下有 node,安装 vue-cli,

npm 安装npm install -g vue-cli

-g 表示全局安装

初始化一个项目

vue init webpack my-project

配置一下项目相关信息

不确定的东西百度一下是啥意思

cd 该目录 install 相关依赖,就是安装 package.json 里面的相关东西

yarn 可以执行 yarn install 或者 直接 yarn

npm 同理可以 npm install

现在已经有一个默认项目了,终端下执行 yarn run dev 就可以运行(下面以 yarn 作为工具),打开即是 vue 默认页面。

准备

PS:具体直接看项目代码勒…

主要看 config/index.js 里面的配置内容

npm run xxx 是啥意思

在默认的项目里面

npm run build 才会打包生成网页文件

在 config/index.js 配置相关信息

如配置打包的文件全都存放到到某个文件夹(这里以路径 /dist 为例)下(部署时直接把这个文件夹拿走就好了)

在 config/index.js 的 build 内配置

1
2
3
4
5
6
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/dist/',

执行 yarn run build ,会打包网页文件到 dist/ 下(如果没有会自己建立),静态文件到 dist/static/ 下

其他可以不用修改

一般 dev 代表开发环境

build 代表生产环境

热更新

config/index.js

dev 里

poll 默认为 false

调整 poll : 1000

这个是设置监听时间

目录结构

没啥代表性

1
2
3
4
5
6
build
config
dist//打包文件存放目录
node_modules
src//主要代码
...

src 结构

1
2
3
4
5
assets//静态文件
componets//组件
page//页面
router//路由
style//样式

完了

到这就差不多了

需要啥再添加…

vue-router 的使用

vue-cli 初始化的项目默认安装了 vue-router

main.js 代码

先导入 router,然后加入到 Vue 里

vue-router 的配置在 router/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)
export default new Router({
//mode: 'history', // 访问路径不带井号 貌似加上这个路由才配置成功
routes: [
{
path: '/',
component: r => require.ensure([], () => r(require('../page/index/index')), 'chatRoom'), // 使用懒加载 加快访问速度
}
]
})

vue 是一层层加载的,先加载 index.html,再由 main.js 去加载内容,然后根据 router 去加载组件。

在需要使用路由的地方使用 <router-view></router-view>

到时候网页会根据路由去加载网页里的 <router-view></router-view> (加载对应的组件)

嵌套路由

具体看 vue2_music_web_project/src/router/index.js

对比一下 vue2_websocket_project/src/router/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
path: '/user',
component: r => require.ensure([], () => r(require('../page/user/index')), 'user'), // 使用懒加载 加快访问速度
meta: {
isUser: true
},
children: [
{
path: '/user/',
component: r => require.ensure([], () => r(require('../components/user/info')), 'info'), // 使用懒加载 加快访问速度
},
{
path: '/user/info',
component: r => require.ensure([], () => r(require('../components/user/info')), 'info'), // 使用懒加载 加快访问速度
},
}

路由过滤(前端过滤)

注意上面的

1
2
3
meta:{
isUser:true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//user filter
router.beforeEach((to, from, next) => {
if (to.matched.some(res => res.meta.isUser)) {// 判断是否需要登录权限
// if (localStorage.getItem('username')) {// 判断是否登录
if (getCookie("username") != "" || getCookie("username") != undefined) {// 判断是否登录
next();
} else {// 没登录则跳转到首页
next({
path: '/',
})
}
} else {
next()
}
})

使用 less, sass….

没用过还

axios

安装

npm install aios

每个 vue 组件都有独立的作用域,挂载到 vue 的原型上,就可以在组件内通过 this 访问了。

在 main.js 中配置

1
2
3
import Vue from 'vue'
import axios from 'axios'
Vue.prototype.$ajax = axios;

之后就可以在 vue 组件中通过 this.$ajax 调用。

比如

1
2
3
4
5
6
7
this.$ajax({
method: "get",
url: "/api/chatRoom/addMessage",
params: {
word: "你好"
}
});

前后端分离时解决跨域

这里更详细诶

例子:

后端 api :locahost:8089/api/chatRoom/addMessage

前端运行在 localhost:8080

在 config/index.js 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
proxyTable: {
'/api': { //使用"/api"来代替"http://localhost:8089"
target: 'http://localhost:8089', //源地址
changeOrigin: true, //改变源
pathRewrite: {
'^/api': '/api'
//路径重写 因为原来的api路径含有 /api
//http://localhost:8089/api/chatRoom/addMessage
//不重写的话 使用就是 /api/api/chatRoom/addMEssage
//因为 使用"/api"来代替"http://localhost:8089"
//重写 就可以 用 /api/chatRoom/addMEssage
}
}
}

配置过后要重启项目,不然不起作用!!!

cookie 操作

新建了一个 util/util.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//获取cookie、
export function getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = document.cookie.match(reg))
return (arr[2]);
else
return null;
}

//设置cookie,增加到vue实例方便全局调用
export function setCookie(c_name, value, expiredays) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + expiredays);
document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
};

//删除cookie
export function delCookie(name) {
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = getCookie(name);
if (cval != null)
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
};

全局注册

main.js

1
2
3
4
5
6
import { getCookie, setCookie, delCookie } from "@/util/util";
Vue.prototype.$cookieStore = {
getCookie,
setCookie,
delCookie
}

然后就可以使用this.$cookieStore.getCookie 等…

也可以在单个 vue 文件里引入,使用…(只在那个 vue 文件里生效)

直接

1
import { getCookie, setCookie, delCookie } from "@/util/util";

然后使用 getCookie…

其他的注册引入的

ElementUI, Vuex 之类的…

main.js

vuex 状态刷新就失效,处理

localStorage

使用 websocket

引入 Stomp, SockJS

使用 SockJS 要引 sockjs-client 哟!百度一下…

总结

菜单由权限控制显隐(管理员首页才显示后台管理):cookie,vuex

固定左栏,右边内容动态变化:嵌套路由(之前我还打算通过参数,动态加载组件来实现…)

路由传参

keep-alive