小QA学习前端系列之vue实战3

接上节 我们继续学习

接下来我们要看看router

1
2
3
4
5
6
7
8
9
{
path: '/topic/:id',
name: 'topic',
component(resolve) {
require.ensure(['./views/topic.vue'], () => {
resolve(require('./views/topic.vue'));
});
}
}

topic router指向的是topic vue components

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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
{
<template>
<div>
<nv-head page-type="主题"
:show-menu="showMenu"
:need-add="true"
:fix-head="true">
</nv-head>
<div id="page"
:class="{'show-menu':showMenu}"
v-if="topic.title">
<h2 class="topic-title" v-text="topic.title"></h2>
<section class="author-info">
<img class="avatar" :src="topic.author.avatar_url" />
<div class="col">
<span>{{topic.author.loginname}}</span>
<time>
发布于:{{topic.create_at | getLastTimeStr(true)}}
</time>
</div>
<div class="right">
<span class="tag"
:class="getTabInfo(topic.tab, topic.good, topic.top, true)"
v-text="getTabInfo(topic.tab, topic.good, topic.top, false)">
</span>
<span class="name">{{topic.visit_count}}次浏览</span>
</div>
</section>
<section class='markdown-body topic-content' v-html="topic.content">
</section>
<h3 class="topic-reply">
<strong>{{topic.reply_count}}</strong> 回复
</h3>
<section class="reply-list">
<ul>
<li v-for="item in topic.replies">
<section class="user">
<router-link :to="{name:'user',params:{loginname:item.author.loginname}}" >
<img class="head" :src="item.author.avatar_url"/>
</router-link>
<div class="info">
<span class="cl">
<span class="name" v-text="item.author.loginname"></span>
<span class="name mt10">
<span></span>
发布于:{{item.create_at | getLastTimeStr(true)}}</span>
</span>
<span class="cr">
<span class="iconfont icon"
:class="{'uped':isUps(item.ups)}"
@click="upReply(item)">&#xe608;</span>
{{item.ups.length}}
<span class="iconfont icon" @click="addReply(item.id)">&#xe609;</span>
</span>
</div>
</section>
<div class="reply_content" v-html="item.content"></div>
<nv-reply :topic.sync="topic"
:topic-id="topicId"
:reply-id="item.id"
:reply-to="item.author.loginname"
:show.sync="curReplyId"
@close="hideItemReply"
v-if="userInfo.userId && curReplyId === item.id"></nv-reply>
</li>
</ul>
</section>
<nv-top></nv-top>
<nv-reply v-if="userInfo.userId"
:topic="topic"
:topic-id="topicId">
</nv-reply>
</div>
<div class='no-data' v-if="noData">
<i class="iconfont icon-empty">&#xe60a;</i>
该话题不存在!
</div>
</div>
</template>
<script>
import $ from 'webpack-zepto';
import utils from '../libs/utils.js';
import nvHead from '../components/header.vue';
import nvReply from '../components/reply.vue';
import nvTop from '../components/backtotop.vue';
import {
mapGetters
} from 'vuex';
export default {
data() {
return {
showMenu: false, // 是否展开左侧菜单
topic: {}, // 主题
noData: false,
topicId: '',
curReplyId: ''
};
},
computed: {
...mapGetters({
userInfo: 'getUserInfo'
})
},
mounted() {
// 隐藏左侧展开菜单
this.showMenu = false;
// 获取url传的tab参数
this.topicId = this.$route.params.id;
// 加载主题数据
$.get('https://cnodejs.org/api/v1/topic/' + this.topicId, (d) => {
if (d && d.data) {
this.topic = d.data;
} else {
this.noData = true;
}
});
},
methods: {
getTabInfo(tab, good = false, top, isClass) {
return utils.getTabInfo(tab, good, top, isClass);
},
getLastTimeStr(time, ago) {
return utils.getLastTimeStr(time, ago);
},
isUps(ups) {
return $.inArray(this.userInfo.userId, ups) >= 0;
},
addReply(id) {
this.curReplyId = id;
if (!this.userInfo.userId) {
this.$router.push({
name: 'login',
params: {
redirect: encodeURIComponent(this.$route.path)
}
});
}
},
hideItemReply() {
this.curReplyId = '';
},
upReply(item) {
if (!this.userInfo.userId) {
this.$router.push({
name: 'login',
params: {
redirect: encodeURIComponent(this.$route.path)
}
});
} else {
$.ajax({
type: 'POST',
url: 'https://cnodejs.org/api/v1/reply/' + item.id + '/ups',
data: {
accesstoken: this.userInfo.token
},
dataType: 'json',
success: (res) => {
if (res.success) {
if (res.action === 'down') {
let index = $.inArray(this.userInfo.userId, item.ups);
item.ups.splice(index, 1);
} else {
item.ups.push(this.userInfo.userId);
}
}
},
error: (res) => {
let error = JSON.parse(res.responseText);
this.$alert(error.error_msg);
return false;
}
});
}
}
},
components: {
nvHead,
nvReply,
nvTop
}
};
</script>
}

依然是有一个fix header 和list中一样
我们继续看看第二部分,构成了页面内容的只要部分

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
\\是否展示topic title
<div id="page"
:class="{'show-menu':showMenu}"
v-if="topic.title">
<h2 class="topic-title" v-text="topic.title"></h2>
\\author个人信息 照片等
<section class="author-info">
<img class="avatar" :src="topic.author.avatar_url" />
\\author 登录名
<div class="col">
<span>{{topic.author.loginname}}</span>
\\发布时间
<time>
发布于:{{topic.create_at | getLastTimeStr(true)}}
</time>
</div>
<div class="right">
<span class="tag"
:class="getTabInfo(topic.tab, topic.good, topic.top, true)"
v-text="getTabInfo(topic.tab, topic.good, topic.top, false)">
</span>
\\浏览量
<span class="name">{{topic.visit_count}}次浏览</span>
</div>
</section>
<section class='markdown-body topic-content' v-html="topic.content">
</section>
\\ 回复数
<h3 class="topic-reply">
<strong>{{topic.reply_count}}</strong> 回复
</h3>
\\ 回复列表
<section class="reply-list">
<ul>
<li v-for="item in topic.replies">
<section class="user">
<router-link :to="{name:'user',params:{loginname:item.author.loginname}}" >
<img class="head" :src="item.author.avatar_url"/>
</router-link>
<div class="info">
<span class="cl">
<span class="name" v-text="item.author.loginname"></span>
<span class="name mt10">
<span></span>
发布于:{{item.create_at | getLastTimeStr(true)}}</span>
</span>
<span class="cr">
<span class="iconfont icon"
:class="{'uped':isUps(item.ups)}"
@click="upReply(item)">&#xe608;</span>
{{item.ups.length}}
\\拿到relpyid 且判断用户是否登陆
<span class="iconfont icon" @click="addReply(item.id)">&#xe609;</span>
</span>
</div>
</section>
<div class="reply_content" v-html="item.content"></div>
<nv-reply :topic.sync="topic"
:topic-id="topicId"
:reply-id="item.id"
:reply-to="item.author.loginname"
:show.sync="curReplyId"
@close="hideItemReply"
v-if="userInfo.userId && curReplyId === item.id"></nv-reply>
</li>
</ul>
</section>
<nv-top></nv-top>
<nv-reply v-if="userInfo.userId"
:topic="topic"
:topic-id="topicId">
</nv-reply>
</div>
<div class='no-data' v-if="noData">
<i class="iconfont icon-empty">&#xe60a;</i>
该话题不存在!
</div>
</div>

非常简单主要是进行topic的展示 回复 更新等