vue-news毕设笔记整理

用vue开发一个新闻项目的笔记整理

1、需要下载一个vue-cli,且是全局安装,在国内需要cnpm下载,所以在百度搜索淘宝镜像:

1
$ cnpm install vue-cli -g

什么是vue?什么是vue-cli?它们有什么作用?

vue与Angular、react的区别在哪里?

2、然后就开始编辑前端的静态页面,在这里就不加以解释了。

3、接下来就是 webpack的选择,那么什么是webpack?webpack的模板有哪些?它有什么作用?它的原理图。

4、在本次项目中,我选择的是webpack-simple来开发。下载的命令如下:

1
$ vue init webpack-simple 项目的名称

5、在我们做好上面的步骤之后,vue-cli已经为我们准备好了我们基础开发的东西,这样,我们就可以直接开始我们的项目了。

6、在运行项目之前需要下载项目所需要的依赖,这点很重要。就会自动生成node_modules

1
$ cnpm install
由于我们并不知道具体需要哪些依赖,可以直接使用上面的命令下载。如果后面再开发过程中我们仍然需要其他的依赖插件,直接使用上面的安装命令安装即可。

7、想看项目的结果,就直接运行:

1
$ npm run dev

8、在本次项目中的package.json,在里面已经为我们配置了热加载,在我们的项目中的代码改变之后,我们浏览器上的视图就会跟着变化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"name": "vue_news_002",##这里写的是项目的名称
"description": "A Vue.js project",##项目的描述
"version": "1.0.0", ##版本
"author": "lyx <2662361669@qq.com>",
"license": "MIT",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",##在开发过程中上运行时,webpack-dev-server --open 使得在多次打开同一个项目的时候,会重新开辟一个新的端口,项目开发者不用每次都去更改项目的端口;--hot这个配置使得项目随时处于热加载状态,代码改变,视图就会跟着改变
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules" ##这句是项目进行了打包,打包之后,就会选择这个,命令改为:npm run build,运行之后,就会生成dist目录和build.js(主要)
},
"dependencies": {##依赖
"axios": "^0.18.0",##配置路由时,是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
"vue": "^2.5.11",##本项目vue
"vue-router": "^3.0.2",##vue原生有的路由管理器
"vue_pageination": "^1.1.2"##分页插件
},
"browserslist": [ ##vue的2版本之后关于浏览器支持情况,IE低于版本8的不支持vue
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"devDependencies": {##开发依赖
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"file-loader": "^1.1.4",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"vue-loader": "^13.0.5",
"vue-template-compiler": "^2.4.4",
"vuex": "^3.1.0",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.9.1"
}
}

9、index.html文件主要放的静态资源

10、webpack.config.js,webpack的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
var path = require('path') ##模块化加载path
var webpack = require('webpack')
module.exports = {##导出模块
entry: './src/main.js',##配置入口文件
output: {##配置出口文件
path: path.resolve(__dirname, './dist'),##文件的路径,
publicPath: '/dist/',##公共的目录
// publicPath: config.build.assetsPublicPath,
filename: 'build.js'##文件名,这是打包之后才会生成的文件
},
module: {##模块
rules: [##模块遵循的规则
{##css文件需要遵循
test: /\.css$/,
use: [##下面这三个的顺序不能颠倒
'vue-style-loader',
'css-loader',
'less-loader'
],
}, {##vue文件
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {##将vue结尾的文件重命名为如下文件
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']##拓展到这几个文件,都打包为上面的文件
},
devServer: {##开发服务
historyApiFallback: true,##历史api回调
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}

11、在main.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
25
26
27
28
29
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import routes from './configRouter.js'//将路由的配置写到这个文件
import axios from 'axios' //使用之前需要先下载:cnpm i axios -s
import Vuex from 'vuex' //vue的状态管理器,使用之前需要下载
Vue.use(VueRouter);//必须
Vue.use(Vuex);
Vue.prototype.$ajax=axios;//在使用axios之前需要做的事,,,修改Vue的原型属性
const router=new VueRouter({
mode: 'history', //切换路径模式,变成history模式
scrollBehavior: () => ({ y: 0 }), // 滚动条滚动的行为,不加这个默认就会记忆原来滚动条的位置
routes
});
// 遍历所有导出的过滤器并添加到全局过滤器
Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[key]);
});
global.domain = domain;//定义一个全局属性,避免多次使用的时候,易于维护
new Vue({
router,
el: '#app',
render: h => h(App)
})

12、在本次项目中使用了一个自定义的时间过滤器

文件目录结构

index.js文件

时间过滤器的业务逻辑js代码

用法如下:管道法

1
<p>{{artiCleData.systemTimeStamp | normalTime }}</p>

13、page.vue分页的额逻辑代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<template>
<nav>
<ul class="pagination">
<li :class="{'disabled': current == 1}"><a href="javascript:;" @click="setCurrent(current - 1)"> « </a></li>
<li :class="{'disabled': current == 1}"><a href="javascript:;" @click="setCurrent(1)"> 首页 </a></li>
<li v-for="p in grouplist" :class="{'active': current == p.val}"><a href="javascript:;"
@click="setCurrent(p.val)"> {{ p.text }} </a>
</li>
<li :class="{'disabled': current == page}"><a href="javascript:;" @click="setCurrent(page)"> 尾页 </a></li>
<li :class="{'disabled': current == page}"><a href="javascript:;" @click="setCurrent(current + 1)"> »</a></li>
</ul>
</nav>
</template>
<script type="es6">
export default{
data(){
return {
current: this.currentPage
}
},
props: {
total: {// 数据总条数
type: Number,
default: 0
},
display: {// 每页显示条数
type: Number,
default: 5
},
currentPage: {// 当前页码
type: Number,
default: 1
},
pagegroup: {// 分页条数
type: Number,
default: 5,
coerce: function (v) {
v = v > 0 ? v : 5;
return v % 2 === 1 ? v : v + 1;
}
}
},
computed: {
page: function () { // 总页数
// alert(this.display)
return Math.ceil(this.total / this.display);
},
grouplist: function () { // 获取分页页码
var len = this.page, temp = [], list = [], count = Math.floor(this.pagegroup / 2), center = this.current;
if (len <= this.pagegroup) {
while (len--) {
temp.push({text: this.page - len, val: this.page - len});
}
;
return temp;
}
while (len--) {
temp.push(this.page - len);
}
;
var idx = temp.indexOf(center);
(idx < count) && ( center = center + count - idx);
(this.current > this.page - count) && ( center = this.page - count);
temp = temp.splice(center - count - 1, this.pagegroup);
do {
var t = temp.shift();
list.push({
text: t,
val: t
});
} while (temp.length);
if (this.page > this.pagegroup) {
(this.current > count + 1) && list.unshift({text: '...', val: list[0].val - 1});
(this.current < this.page - count) && list.push({text: '...', val: list[list.length - 1].val + 1});
}
return list;
}
},
methods: {
setCurrent: function (idx) {
if (this.current != idx && idx > 0 && idx < this.page + 1) {
this.current = idx;
this.$emit('pagechange', this.current);
}
}
}
};
</script>
<style lang="less">
.pagination {
overflow: hidden;
display: table;
margin: 0 auto;
/*width: 100%;*/
height: 50px;
li {
float: left;
height: 30px;
border-radius: 5px;
margin: 3px;
color: #666;
&
:hover {
background: #000;
a {
color: #fff;
}
}
a {
display: block;
width: 52px;
height: 30px;
text-align: center;
line-height: 20px;
font-size: 12px;
border-radius: 5px;
text-decoration: none;
vertical-align: middle;
}
}
.active {
background: #000;
a {
color: #fff;
}
}
}
</style>

14/路由配置的代码: component的值是需要导入的外面vue文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
path:'*',
redirect:'./home'
},
{
path: '/',
redirect:'/home'
},
{
path: '/nav/:id',
component: Home
},
{
path: '/home',
component: Home
},
{
path:'/article/:id',
component:ArticleNewsDetail
},
{
path: '/StuChuang',
component:StuChuang,
},

15、基本的配置已经做好了,先来编写home,首页的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<template>
<div v-cloak>
<UserLogin></UserLogin>
<UserReg></UserReg>
<ReleaseS></ReleaseS>
<!-- 内容开始 -->
<div class="content clear">
<ul class="list-group">
<li class="list-group-item" v-for="(newpager,index) in news">
<router-link :to="'/article/'+newpager.id">
<div class="h4">
{{index+1}} {{newpager.newsTitle}}
<p class="fr" style="font-size:10px;margin-right: 10px;margin-top: 4px;">
{{newpager.systemTimeStamp | normalTime}} &nbsp;&nbsp;来源:{{newpager.contentSource}}
</p>
</div>
</router-link>
</li>
</ul>
<!-- 分页开始 -->
<pagination v-show="this.news.length!=0" :total="total" :current-page='current' @pagechange="pagechange"></pagination>
<!-- 分页结束 -->
</div>
</div>
</template>
<script type="text/javascript">
import UserLogin from './User/User_login.vue'
...
export default{
data(){
return{
news:[],
imgsrc:domain.testUrl,
// total: 150, // 记录总条数
display: 5, // 每页显示条数
current: 1, // 当前的页数
len:11,
}
},
components:{
'pagination': pagination,
...
},
watch:{
$route(to){
//console.log(to);
var reg=/nav\/\d+/;
if(reg.test(to.path)){
// alert("yy"+this.$route.params.id)
var newsId=this.$route.params.id || 0;
this.fetchData(newsId);
}
}
},
methods: {
fetchData(newsId,current){
if(typeof(newsId)=="undefined"){//在newsId被定义之前,先执行这个,将newsId强制定义为1
newsId=1;
}
this.$ajax.post(this.imgsrc+'/news/listNews',{//这里的接口的本项目特有的,根据实际来
"menuId":newsId,
"pageNum":current,
"pageCount":this.display
}).then(res => {
if(res.data.code=='200'){
console.log(res.data)
this.news=res.data.contents.list;
this.len=res.data.contents.size;
// alert(this.artiCleData.id);
// console.log(this.news);
// alert(res.data);
}
if(res.data.code=='500'){
alert(res.data.message);
}
})
},
// 分页方法
pagechange:function(current){
// console.log(current);
// ajax请求, 向后台发送 currentPage, 来获取对应的数据
this.fetchData(this.$route.params.id,current);
// alert(Math.ceil(this.len/this.display))
}
},
computed:{
total(){
return this.len;
},
},
mounted(){
this.fetchData(this.$route.params.id,1);
//页码切换执行方法
},
};
</script>
<style>
</style>
路由配置1:
1
2
3
4
5
6
7
8
<router-link :to="'/article/'+newpager.id">
<div class="h4">
{{index+1}} {{newpager.newsTitle}}
<p class="fr" style="font-size:10px;margin-right: 10px;margin-top: 4px;">
{{newpager.systemTimeStamp | normalTime}} &nbsp;&nbsp;来源:{{newpager.contentSource}}
</p>
</div>
</router-link>
配置路由之后,需要在展示的地方设置,本项目在App.vue中
1
<router-view ></router-view>
*路由配置2
1
2
3
<router-link :to="{name:'zixun'}" tag="li" active-class="active">
<a href="javascript:;"> 分享咨讯展示</a>
</router-link>
*在路由配置的路径文件中,
1
2
3
4
5
{
name:'zixun',
path:'/zixun',
component:Displayzixun
}

16动画的写法:

A、动画的方法有哪些?

B、本次项目下载了animate.css

C、用法:

1
2
3
4
5
<div>
<transition enter-active-class="zoomInLeft" leave-active-class="zoomOutRight">
<router-view class="animated"></router-view>
</transition>
</div>

17、分页的用法

A、分页的插件:

B、本项目需要引入文件page.vue,此文件内容见13。

C、在需要分页的vue文件中:

1
<pagination v-show="this.news.length!=0" :total="total" :current-page='current' @pagechange="pagechange"></pagination>

D、需要data属性中定义:

1
2
3
4
5
6
7
data(){
return {
display: 5, // 每页显示条数
current: 1, // 当前的页数
len:11,
}
}

E、分页方法pagechange

1
2
3
4
5
6
// 分页方法
pagechange:function(current){
// console.log(current);
// ajax请求, 向后台发送 currentPage, 来获取对应的数据,逻辑代码需要写在这里
}

18、使用计算属性computed计算total的值

a、什么是vue的计算属性?
b、computed的用法?
c、本次项目中需要计算total的值
1
2
3
4
5
computed:{
total(){
return this.len;
},
},

19、打开弹出框,模态框:data-target的值须和下面的modal中的id值保持一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>

20、localStorage的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(1).
储存数据
localStorage.setItem('accessToken', 'Bearer ' + response.data.result.accessToken)
(2).取出数据
localStorage.getItem('accessToken')
(3).删除储存数据
 localStorage.removeItem('accessToken')
(4).更改数据
localStorage.setItem('accessToken', '更改后' + response.data.result.accessToken)

21、Cookie的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//设置cookie
setCookie(c_name,c_pwd,exdays) {
// alert("setCookie开始执行")
var exdate=new Date();//获取时间
exdate.setTime(exdate.getTime() + 24*60*60*1000*exdays);//保存的天数
//字符串拼接cookie
window.document.cookie="uEmail"+ "=" +c_name+";path=/;expires="+exdate.toGMTString();
window.document.cookie="uPassword"+"="+c_pwd+";path=/;expires="+exdate.toGMTString();
},
getCookie() {
// alert("getCookie开始调用");
if (document.cookie.length>0) {
// alert(document.cookie);
var arr=document.cookie.split('; ');//这里显示的格式需要切割一下自己可输出看下
for(var i=0;i<arr.length;i++){
var arr2=arr[i].split('=');//再次切割
//判断查找相对应的值
if(arr2[0]=='uEmail'){
this.loginForm.uEmail=arr2[1];//保存到保存数据的地方
}else if(arr2[0]=='uPassword'){
this.loginForm.uPassword=arr2[1];
}
}
}
},
clearCookie(){//清除
// alert("clearCookie开始执行");
this.setCookie('','',-1);
// this.setCookie( 'name' , this.loginForm.uEmail)
},

22、Vue.nextTick

说明:Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。

B、必须和vue1版本的created、vue2版本的mounted放在一起

1
2
3
4
5
6
mounted(){
// alert("页面加载调用获取cookie值");
this.$nextTick(() => {
this.getCookie();
})
}

23、数据监听,本项目中监听id的值

1
2
3
4
5
6
7
8
9
10
11
watch:{
$route(to){
//console.log(to);
var reg=/nav\/\d+/;
if(reg.test(to.path)){
// alert("yy"+this.$route.params.id)
var newsId=this.$route.params.id || 0;
this.fetchData(newsId);
}
}
},

24、判断用户登录、注册、注销

A、用户登录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<template>
<!-- 登录模态框开始 -->
<!-- 登录窗口 -->
<div id="login" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-title">
<h1 class="text-center">登录</h1>
</div>
<div class="modal-body">
<form class="form-group" :model="loginForm">
<div class="form-group">
<label for="">用户名/邮箱</label>
<input class="form-control" type="text" placeholder="请输入用户名或邮箱" v-model="loginForm.uEmail">
</div>
<div class="form-group">
<label for="">密码</label>
<input class="form-control" type="password" placeholder="请输入密码" v-model="loginForm.uPassword">
</div>
<div class="text-center">
<button class="btn btn-primary" type="submit" @click="login('loginForm')">登录</button>
<button class="btn btn-danger" data-dismiss="modal">取消</button>
</div>
<a href="" data-toggle="modal" data-dismiss="modal" data-target="#register">还没有账号?点我注册</a>
<input type="checkbox" name="" value="checked" v-model="loginForm.checked">七天免登录
<span style="cursor: pointer;color: #f19149;font-size: 0.75rem;margin-left: 5px;">忘记密码?</span>
</form>
</div>
</div>
</div>
</div>
<!-- 登录模态框结束 -->
</template>
<script type="text/javascript">
export default{
data(){
return{
imgsrc:domain.testUrl,
loginForm:{
uEmail:'',
uPassword:'',
checked:true
},
isLogin:false,
sessionId:'',
test:''
}
},
methods:{
login(formValue){
var Email = this.loginForm.uEmail;
var Pass = this.loginForm.uPassword;
if(Email == ''|| Email==null){
alert("请输入邮箱!");
return;
}
if(Pass == '' || Pass == null){
alert("请输入密码!")
return;
}
this.$ajax.post(this.imgsrc+'/user/login',{
"uEmail":Email,
"uPassword":Pass
}).then(res => {
if(res.data.code=='200'){
alert(res.data.message)
this.sessionId = res.data.contents[0].sessionId;
// alert(this.sessionId)
localStorage.setItem('sessionId',this.sessionId );//将sessionId保存到localStorage
localStorage.setItem('userEmail',Email);//将用户名保存到localStorage
this.isLogin=true;
// alert(this.isLogin);
localStorage.setItem('isLogin',this.isLogin);//islogin为true,
// console.log(this.test);
// this.test=localStorage.getItem('sessionId');
// console.log(this.test);
// console.log(res.data.status);
if(this.loginForm.checked == true){
this.setCookie(Email,Pass,7);
}else{
this.clearCookie();
}
// alert(res.data);
}
if(res.data.code=='500'){
alert(res.data.message)
}
})
},
//设置cookie
setCookie(c_name,c_pwd,exdays) {
// alert("setCookie开始执行")
var exdate=new Date();//获取时间
exdate.setTime(exdate.getTime() + 24*60*60*1000*exdays);//保存的天数
//字符串拼接cookie
window.document.cookie="uEmail"+ "=" +c_name+";path=/;expires="+exdate.toGMTString();
window.document.cookie="uPassword"+"="+c_pwd+";path=/;expires="+exdate.toGMTString();
},
getCookie() {
// alert("getCookie开始调用");
if (document.cookie.length>0) {
// alert(document.cookie);
var arr=document.cookie.split('; ');//这里显示的格式需要切割一下自己可输出看下
for(var i=0;i<arr.length;i++){
var arr2=arr[i].split('=');//再次切割
//判断查找相对应的值
if(arr2[0]=='uEmail'){
this.loginForm.uEmail=arr2[1];//保存到保存数据的地方
}else if(arr2[0]=='uPassword'){
this.loginForm.uPassword=arr2[1];
}
}
}
},
clearCookie(){//清除
// alert("clearCookie开始执行");
this.setCookie('','',-1);
// this.setCookie( 'name' , this.loginForm.uEmail)
},
},
//页面加载调用获取cookie值
mounted(){
// alert("页面加载调用获取cookie值");
this.$nextTick(() => {
this.getCookie();
})
}
}
//‘name’是你自己取得名字,后面的this.ruleForm2.name是我写的一个input内v-model的值
</script>
需要在登录所在的vue文件中定义isLogin
1
isLogin:localStorage.getItem('isLogin')

B、用户注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<template>
<!-- 注册模态框开始 -->
<!-- 注册窗口 -->
<div id="register" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<button class="close" data-dismiss="modal">
<span>&times;</span>
</button>
</div>
<div class="modal-title">
<h1 class="text-center">注册</h1>
</div>
<div class="modal-body">
<form class="form-group" action="" :model="RegForm">
<div class="form-group">
<label for="">用户名</label>
<input class="form-control" type="text" placeholder="6-11位字母或数字" v-model="RegForm.uName" @blur="checkuName" maxlength="11">
</div>
<div class="form-group">
<label for="">邮箱</label>
<input class="form-control" type="email" placeholder="例如:123@123.com" v-model="RegForm.uEmail" @blur="checkuEmail">
</div>
<div class="form-group">
<label for="">密码</label>
<input class="form-control" type="password" placeholder="至少6位字母或数字" v-model="RegForm.uPassword">
</div>
<div class="form-group">
<label for="">再次输入密码</label>
<input class="form-control" type="password" placeholder="至少6位字母或数字">
</div>
<div class="form-group">
<label for="">性别</label><br>
<input type="radio" id="sex0" name="uSex" v-model="RegForm.uSex" value="0" placeholder=""><label for="sex0">男</label>
<input type="radio" id="sex1" name="uSex" v-model="RegForm.uSex" value="1" placeholder=""><label for="sex1">女</label>
<input type="radio" id="sex2" name="uSex" v-model="RegForm.uSex" value="2" placeholder="" checked="checked"><label for="sex2">保密</label>
</div>
<div class="form-group">
<label for="">等级:</label><br>
<input type="radio" name="uRank" v-model="RegForm.uRank" id="rank1"><label for="rank1">1</label>
<input type="radio" name="uRank" v-model="RegForm.uRank" id="rank0"><label for="rank0">0</label>
</div>
<div class="form-group">
<label for="">状态:</label><br>
<input type="radio" name="uStatus" v-model="RegForm.uStatus" id="status1"><label for="status1">1</label>
<input type="radio" name="uStatus" v-model="RegForm.uStatus" id="status0"><label for="status0">0</label>
</div>
<div class="form-group">
<label for="">座右铭:</label>
<textarea name="" maxlength="100" placeholder="请输入一百以内的座右铭或自我介绍" rows="3" cols="78" v-model="RegForm.uMotto"></textarea>
</div>
<div class="text-right">
<button class="btn btn-primary" type="submit" @click="Register('RegForm')">提交</button>
<input type="reset" name="" class="btn btn-warning">
<button class="btn btn-danger" data-dismiss="modal">取消</button>
</div>
<a href="" data-toggle="modal" data-dismiss="modal" data-target="#login">已有账号?点我登录</a>
</form>
</div>
</div>
</div>
</div>
<!-- 注册模态框结束 -->
</template>
<script type="text/javascript">
export default{
data(){
return{
imgsrc:domain.testUrl,
RegForm:{
uName:'',
uEmail:'',
uPassword:'',
uMotto:'',
uSex:'2',
uRank:'0',
uStatus:'1'
// checked:true
}
}
},
methods:{
Register(regFormName){
var Name=this.RegForm.uName;
var Email = this.RegForm.uEmail;
var Pass = this.RegForm.uPassword;
var Motto = this.RegForm.uMotto;
var Sex = this.RegForm.uSex;
var Rank = this.RegForm.uRank;
var Status = this.RegForm.uStatus;
alert(Name);
if(Name =='' || Name == null){
alert("请输入用户名");
return;
}else if(Email == '' || Email == null){
alert("请输入邮箱")
return;
}else if(Pass == '' || Pass == null){
alert("请输入密码");
return;
}else if(Sex==''|| !(Sex == 0 || Sex==1 || Sex == 2)){
alert("请选择性别");
return;
}else if(Rank =='' || !(Rank == 0 || Rank == 1)){
alert("请选择等级!");
return;
}else if(Status == '' ||!(Status ==0 || Status == 1)){
alert("请选择状态!");
return;
}else if(Motto == '' || Motto == null){
alert("请输入座右铭");
return;
}
this.$ajax.post(this.imgsrc+'/user/register',{
'uName':'',
'uEmail':'',
'uPassword':'',
'uSex':'',
'uRank':'',
'uStatus':'',
'uMotto':''
}).then(res => {
if(res.data.code=='200'){
alert(res.data.contents)
// alert(res.data);
}
if(res.data.code=='500'){
alert(res.data.contents)
}
})
},
checkuName(){
this.$ajax.get(this.imgsrc+'/user/eaxmUserNameInSystem',{
'uName':''
}).then(res => {
if(res.data.code=='200'){
console.log(res.data.message);
}
if(res.data.code=='201'){
alert(res.data.message);
}
if(res.data.code=='500'){
alert(res.data.message);
}
})
},
checkuEmail(){
this.$ajax.get(this.imgsrc+'/user/eaxmUserEmailInSystem',{
'uEmail':''
}).then(res =>{
if(res.data.code=='200'){
console.log(res.data.message);
}
if(res.data.code=='201'){
alert(res.data.message);
}
if(res.data.code=='500'){
alert(res.data.message);
}
})
},
}
}
</script>

C、用户注销

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 用户注销
loginOut(){
this.$ajax.post(this.imgsrc+'/user/loginout',{
"sessionId":localStorage.getItem('sessionId')
}).then(res => {
if(res.data.code=='200'){
//删除,清空localStorage中的值
localStorage.removeItem('sessionId');
localStorage.removeItem('userEmail');
localStorage.removeItem('isLogin');
this.isLogin = false;//需要在data中定义
alert(res.data.message);
}
if(res.data.code=='500'){
alert(res.data.contents);
}
})
}

D、状态变换:v-if 和 v-else ,v-else必须写在v-if的后面,且不能单独出现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!-- v-if -->
<li class="reg_login" v-if="!isLogin">
<ul>
<li >
<a href="javascript:void(0)" @click="openReg()"><span class="glyphicon glyphicon-user" style="text-shadow: black 5px 3px 3px;width:20px;height:20px;"></span> 注册</a>
</li>
<li>
<a href="javascript:void(0)" @click="openLogin()" ><span class="glyphicon glyphicon-log-in" style="text-shadow: black 5px 3px 3px; margin-right: 3px;" ></span> 登录</a>
</li>
</ul>
</li>
<!-- v-else在下面使用到 -->
<li class="release_out" v-else>
<ul>
<li>
<div class="User-info dropdown " >
<!-- 下拉设置数据项 -->
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
<li>
<!-- <router-link :to="{name:'userDetail'}">个人中心</router-link> -->
</li>
<li role="separator" class="divider"></li>
<li><a href="javascript:void(0)" @click="loginOut()">
<span class="glyphicon glyphicon-off" style="text-shadow: black 5px 3px 3px; margin-right: 3px;" ></span>
注销</a>
</li>
</ul>
</div>
</li>
</ul>
</li>

25、

26、在实现某一需求后,关闭模态框

1
2
3
4
5
setTimeout(function(){
                $('#comm').modal('hide');
                $(".modal.fade").hide();
                // $("#myModal").trigger("click");
              },1000);

项目运行时报错规整:

1、

x


参考链接

jQuery操作Dom

虚拟DOM的原理

Vue.nextTick 的原理和用途

简单理解Vue中的nextTick

JS模块化工具requirejs教程(一):初识requirejs

axios中文说明

bootstrap3

vue2参考api

vue中cookie的用法

localStorage sessionStorage 和cookie的区别

[][]