社区详情页面 review by lea.guo
Showing
9 changed files
with
423 additions
and
230 deletions
@@ -24,12 +24,12 @@ | @@ -24,12 +24,12 @@ | ||
24 | </template> | 24 | </template> |
25 | 25 | ||
26 | <script> | 26 | <script> |
27 | -import { get } from "lodash"; | ||
28 | -import videojs from "video.js"; | ||
29 | -import { getArticleImageSize, processImage } from "utils/image-handler"; | 27 | +import { get } from 'lodash'; |
28 | +import videojs from 'video.js'; | ||
29 | +import { getArticleImageSize, processImage } from 'utils/image-handler'; | ||
30 | 30 | ||
31 | export default { | 31 | export default { |
32 | - name: "VideoPlayer", | 32 | + name: 'VideoPlayer', |
33 | props: { | 33 | props: { |
34 | source: String, | 34 | source: String, |
35 | cover: String, | 35 | cover: String, |
@@ -41,7 +41,7 @@ export default { | @@ -41,7 +41,7 @@ export default { | ||
41 | return { | 41 | return { |
42 | muted: true, | 42 | muted: true, |
43 | controls: true, | 43 | controls: true, |
44 | - aspectRatio: "1:1" | 44 | + aspectRatio: '1:1' |
45 | }; | 45 | }; |
46 | } | 46 | } |
47 | } | 47 | } |
@@ -68,45 +68,45 @@ export default { | @@ -68,45 +68,45 @@ export default { | ||
68 | 2, | 68 | 2, |
69 | imgSize.width, | 69 | imgSize.width, |
70 | imgSize.height, | 70 | imgSize.height, |
71 | - get(this.yoho, "window.supportWebp") | 71 | + get(this.yoho, 'window.supportWebp') |
72 | ); | 72 | ); |
73 | } else { | 73 | } else { |
74 | - return this.cover.split("?")[0]; | 74 | + return this.cover.split('?')[0]; |
75 | } | 75 | } |
76 | } else { | 76 | } else { |
77 | - return ""; | 77 | + return ''; |
78 | } | 78 | } |
79 | }, | 79 | }, |
80 | sourceType() { | 80 | sourceType() { |
81 | - let type = "video/mp4"; | 81 | + let type = 'video/mp4'; |
82 | 82 | ||
83 | if (this.source) { | 83 | if (this.source) { |
84 | - let source = this.source.split("?")[0]; | 84 | + let source = this.source.split('?')[0]; |
85 | 85 | ||
86 | - source = source.split("."); | 86 | + source = source.split('.'); |
87 | 87 | ||
88 | switch (source[source.length - 1]) { | 88 | switch (source[source.length - 1]) { |
89 | - case "opus": | ||
90 | - case "ogv": | ||
91 | - type = "video/ogg"; | 89 | + case 'opus': |
90 | + case 'ogv': | ||
91 | + type = 'video/ogg'; | ||
92 | break; | 92 | break; |
93 | - case "mkv": | ||
94 | - type = "video/x-matroska"; | 93 | + case 'mkv': |
94 | + type = 'video/x-matroska'; | ||
95 | break; | 95 | break; |
96 | - case "m3u8": | ||
97 | - type = "application/x-mpegURL"; | 96 | + case 'm3u8': |
97 | + type = 'application/x-mpegURL'; | ||
98 | break; | 98 | break; |
99 | - case "m4a": | ||
100 | - type = "audio/mp4"; | 99 | + case 'm4a': |
100 | + type = 'audio/mp4'; | ||
101 | break; | 101 | break; |
102 | - case "mp3": | ||
103 | - type = "audio/mpeg"; | 102 | + case 'mp3': |
103 | + type = 'audio/mpeg'; | ||
104 | break; | 104 | break; |
105 | - case "aac": | ||
106 | - type = "audio/aac"; | 105 | + case 'aac': |
106 | + type = 'audio/aac'; | ||
107 | break; | 107 | break; |
108 | - case "oga": | ||
109 | - type = "audio/ogg"; | 108 | + case 'oga': |
109 | + type = 'audio/ogg'; | ||
110 | break; | 110 | break; |
111 | default: | 111 | default: |
112 | break; | 112 | break; |
@@ -131,7 +131,6 @@ export default { | @@ -131,7 +131,6 @@ export default { | ||
131 | }, | 131 | }, |
132 | methods: { | 132 | methods: { |
133 | async parentHandleclick() { | 133 | async parentHandleclick() { |
134 | - // await this.delay(1000); | ||
135 | this.player.play(); | 134 | this.player.play(); |
136 | 135 | ||
137 | const timeId = setTimeout(() => { | 136 | const timeId = setTimeout(() => { |
@@ -155,37 +154,37 @@ export default { | @@ -155,37 +154,37 @@ export default { | ||
155 | }); | 154 | }); |
156 | }, | 155 | }, |
157 | initPlayer() { | 156 | initPlayer() { |
158 | - const noVioceClass = "vjs-yoho-novoice"; | 157 | + const noVioceClass = 'vjs-yoho-novoice'; |
159 | 158 | ||
160 | this.player = videojs(this.$refs.videoPlayer, this.options); | 159 | this.player = videojs(this.$refs.videoPlayer, this.options); |
161 | 160 | ||
162 | - this.voiceBtn = this.player.addChild("button"); | ||
163 | - this.voiceBtn.addClass("vjs-yoho-voice"); | 161 | + this.voiceBtn = this.player.addChild('button'); |
162 | + this.voiceBtn.addClass('vjs-yoho-voice'); | ||
164 | this.voiceBtn.addClass(noVioceClass); | 163 | this.voiceBtn.addClass(noVioceClass); |
165 | - this.backBtn = this.player.addChild("button"); | ||
166 | - this.backBtn.addClass("vjs-yoho-back"); | ||
167 | - this.voiceBtn.on("touchend", () => { | 164 | + this.backBtn = this.player.addChild('button'); |
165 | + this.backBtn.addClass('vjs-yoho-back'); | ||
166 | + this.voiceBtn.on('touchend', () => { | ||
168 | this.player.muted(!this.voiceBtn.hasClass(noVioceClass)); | 167 | this.player.muted(!this.voiceBtn.hasClass(noVioceClass)); |
169 | }); | 168 | }); |
170 | - this.backBtn.on("touchend", () => { | 169 | + this.backBtn.on('touchend', () => { |
171 | this.player.exitFullscreen(); | 170 | this.player.exitFullscreen(); |
172 | }); | 171 | }); |
173 | 172 | ||
174 | - this.player.on("play", () => { | 173 | + this.player.on('play', () => { |
175 | this.player._yohoPlayTime = this.getTime(); | 174 | this.player._yohoPlayTime = this.getTime(); |
176 | }); | 175 | }); |
177 | - this.player.on("pause", () => { | 176 | + this.player.on('pause', () => { |
178 | this.player._yohoPauseTime = this.getTime(); | 177 | this.player._yohoPauseTime = this.getTime(); |
179 | }); | 178 | }); |
180 | - this.player.on("ended", () => { | 179 | + this.player.on('ended', () => { |
181 | this.player._yohoEndedTime = this.getTime(); | 180 | this.player._yohoEndedTime = this.getTime(); |
182 | }); | 181 | }); |
183 | 182 | ||
184 | - this.player.on("fullscreenchange", () => { | 183 | + this.player.on('fullscreenchange', () => { |
185 | this.player._yohoPlayTime = this.getTime(); | 184 | this.player._yohoPlayTime = this.getTime(); |
186 | }); | 185 | }); |
187 | 186 | ||
188 | - this.player.on("volumechange", () => { | 187 | + this.player.on('volumechange', () => { |
189 | const soundOff = this.player.muted() || this.player.volume() === 0; | 188 | const soundOff = this.player.muted() || this.player.volume() === 0; |
190 | 189 | ||
191 | if (soundOff) { | 190 | if (soundOff) { |
@@ -205,7 +204,7 @@ export default { | @@ -205,7 +204,7 @@ export default { | ||
205 | <style lang="scss" scoped> | 204 | <style lang="scss" scoped> |
206 | .video-js { | 205 | .video-js { |
207 | width: 100%; | 206 | width: 100%; |
208 | - height: auto; | 207 | + height: 750px; |
209 | 208 | ||
210 | video { | 209 | video { |
211 | width: 100%; | 210 | width: 100%; |
apps/components/widget-avatar.vue
0 → 100644
1 | +<template> | ||
2 | + <div class="avatar-wrap"> | ||
3 | + <ImageFormat class="img-avatar" :lazy="true" :src="imageSrc" :width="width" :height="height" @error="errorHandle"></ImageFormat> | ||
4 | + </div> | ||
5 | +</template> | ||
6 | + | ||
7 | +<script> | ||
8 | +export default { | ||
9 | + name: 'WidgetAvatar', | ||
10 | + props: { | ||
11 | + src: { | ||
12 | + type: String, | ||
13 | + default: '' | ||
14 | + }, | ||
15 | + width: { | ||
16 | + type: Number, | ||
17 | + default: 35 | ||
18 | + }, | ||
19 | + height: { | ||
20 | + type: Number, | ||
21 | + default: 35 | ||
22 | + }, | ||
23 | + lazy: { | ||
24 | + type: Boolean, | ||
25 | + default: false | ||
26 | + }, | ||
27 | + small: { | ||
28 | + type: Boolean, | ||
29 | + default: false | ||
30 | + }, | ||
31 | + group: [Number, String] | ||
32 | + }, | ||
33 | + data() { | ||
34 | + return { | ||
35 | + imgSrc: this.src, | ||
36 | + defaultSrc: 'https://img12.static.yhbimg.com/article/2019/02/26/16/02456ade977d8dfdbc4ca548b196c1d62b.png?imageView/2/w/{width}/h/{height}' | ||
37 | + }; | ||
38 | + }, | ||
39 | + computed: { | ||
40 | + imageSrc() { | ||
41 | + return this.imgSrc || this.defaultSrc; | ||
42 | + } | ||
43 | + }, | ||
44 | + watch: { | ||
45 | + src(val) { | ||
46 | + this.imgSrc = val; | ||
47 | + } | ||
48 | + }, | ||
49 | + methods: { | ||
50 | + errorHandle() { | ||
51 | + this.imgSrc = this.defaultSrc; | ||
52 | + } | ||
53 | + } | ||
54 | +}; | ||
55 | +</script> | ||
56 | + | ||
57 | +<style lang="css" scoped> | ||
58 | +.avatar-wrap { | ||
59 | + display: inline-block; | ||
60 | + position: relative; | ||
61 | + | ||
62 | + > img { | ||
63 | + width: 100%; | ||
64 | + height: 100%; | ||
65 | + } | ||
66 | +} | ||
67 | + | ||
68 | +.img-avatar { | ||
69 | + border-radius: 50%; | ||
70 | + overflow: hidden; | ||
71 | +} | ||
72 | +</style> |
apps/pages/article/articleDetail.vue
0 → 100644
1 | +<template> | ||
2 | + <LayoutApp :show-back="true" title="社区详情"> | ||
3 | + <div class="detail-container"> | ||
4 | + | ||
5 | + <div class="author-container"> | ||
6 | + <ArticleAuthor :userHeadIco="userHeadIco" :userName="userName"></ArticleAuthor> | ||
7 | + </div> | ||
8 | + | ||
9 | + <div class="source-container"> | ||
10 | + <ArticleVideo v-if="showVideo" :videoUrl="videoUrl" :coverUrl="coverUrl"></ArticleVideo> | ||
11 | + <ArticleImage v-else :imageList="imageList"></ArticleImage> | ||
12 | + </div> | ||
13 | + | ||
14 | + <div class="slide-container"> | ||
15 | + <HorizontalSlide :value="imageList"></HorizontalSlide> | ||
16 | + </div> | ||
17 | + | ||
18 | + <div class="note-container"> | ||
19 | + <div class="note-header">Nike 旗下大热鞋款 Air Max 95</div> | ||
20 | + <div class="note-content">Nike 旗下大热鞋款 Air Max 95 一直以来在街头造型当中的能见度都算高,凭藉其舒适脚感与百搭外型 @NIKE官方 Max 95 也轻松成为许多鞋迷的心头好紧接「Triple White」之后,备受期待的 Nike 全新鞋款 SF-AF1 Mid 又有一双鞋的「Tiger Camo」配色率先现身网络。</div> | ||
21 | + <div class="note-date">2019-01-02</div> | ||
22 | + <div class="praise-wrapper" ></div> | ||
23 | + </div> | ||
24 | + | ||
25 | + <div class="recommend-container"> | ||
26 | + <div class="recommend-text">推荐阅读</div> | ||
27 | + <div class="recommend-list">list</div> | ||
28 | + </div> | ||
29 | + | ||
30 | + </div> | ||
31 | + </LayoutApp> | ||
32 | +</template> | ||
33 | + | ||
34 | +<script> | ||
35 | +import ArticleAuthor from './components/article-author'; | ||
36 | +import ArticleVideo from './components/article-video'; | ||
37 | +import ArticleImage from './components/article-image'; | ||
38 | +import HorizontalSlide from './components/horizontalSlide'; | ||
39 | + | ||
40 | +export default { | ||
41 | + name: 'articleDetail', | ||
42 | + components: { | ||
43 | + ArticleAuthor, | ||
44 | + ArticleVideo, | ||
45 | + ArticleImage, | ||
46 | + HorizontalSlide | ||
47 | + }, | ||
48 | + data() { | ||
49 | + return { | ||
50 | + imageList: [ | ||
51 | + {image_url: 'http://img11.static.yhbimg.com/goodsimg/2019/07/02/16/0191aa70fd1f46d75e5ff974dfe0cdac1c.jpg?imageMogr2/thumbnail/{width}x{height}/background/d2hpdGU=/position/center/quality/80'}, | ||
52 | + {image_url: 'http://img11.static.yhbimg.com/goodsimg/2018/11/06/14/01bbabe3eb9597d5a36f51a0a29c23e441.jpg?imageMogr2/thumbnail/{width}x{height}/background/d2hpdGU=/position/center/quality/80'}, | ||
53 | + {image_url: 'http://img11.static.yhbimg.com/goodsimg/2018/11/06/14/016c59b642d25a92049003c318ea7b97ff.jpg?imageMogr2/thumbnail/{width}x{height}/background/d2hpdGU=/position/center/quality/80'}, | ||
54 | + {image_url: 'http://img11.static.yhbimg.com/goodsimg/2018/11/06/14/012df38fe6117ea9467a01919a4b4c2f3c.jpg?imageMogr2/thumbnail/{width}x{height}/background/d2hpdGU=/position/center/quality/80'} | ||
55 | + ], | ||
56 | + showVideo: false, | ||
57 | + videoUrl: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', | ||
58 | + coverUrl: 'http://file02.16sucai.com/d/file/2015/0408/779334da99e40adb587d0ba715eca102.jpg', | ||
59 | + userHeadIco: 'https://img12.static.yhbimg.com/article/2019/02/26/16/02456ade977d8dfdbc4ca548b196c1d62b.png?imageView/2/w/{width}/h/{height}', | ||
60 | + userName: 'MOMO草' | ||
61 | + }; | ||
62 | + }, | ||
63 | +}; | ||
64 | +</script> | ||
65 | + | ||
66 | +<style lang="scss" scoped> | ||
67 | +.detail-container { | ||
68 | + background: #fff; | ||
69 | +} | ||
70 | + | ||
71 | +.author-container { | ||
72 | + width: 100%; | ||
73 | + height: 100px; | ||
74 | +} | ||
75 | + | ||
76 | +.source-container { | ||
77 | + width: 100%; | ||
78 | + height: 750px; | ||
79 | +} | ||
80 | + | ||
81 | +.slide-container { | ||
82 | + padding: 40px 0 36px 24px; | ||
83 | +} | ||
84 | + | ||
85 | +.note-container { | ||
86 | + padding: 0 24px 100px; | ||
87 | + background: #fff; | ||
88 | +} | ||
89 | + | ||
90 | +.note-header { | ||
91 | + font-size: 36px; | ||
92 | + color: #222; | ||
93 | + letter-spacing: 0.34px; | ||
94 | + line-height: 56px; | ||
95 | + font-weight: bold; | ||
96 | +} | ||
97 | + | ||
98 | +.note-content { | ||
99 | + font-size: 30px; | ||
100 | + color: #000; | ||
101 | + letter-spacing: 0.28px; | ||
102 | + line-height: 50px; | ||
103 | +} | ||
104 | + | ||
105 | +.note-date { | ||
106 | + margin-top: 20px; | ||
107 | + font-size: 30px; | ||
108 | + color: #999; | ||
109 | + letter-spacing: 0.28px; | ||
110 | +} | ||
111 | + | ||
112 | +.praise-wrapper { | ||
113 | + margin-top: 60px; | ||
114 | + margin-left: calc((100%-160px)/2); | ||
115 | + height: 160px; | ||
116 | + width: 160px; | ||
117 | + background: url("~statics/image/coupon/used@3x.png"); | ||
118 | + background-size: contain; | ||
119 | + background-repeat: no-repeat; | ||
120 | +} | ||
121 | + | ||
122 | +.recommend-container { | ||
123 | + background: #F2F2F2; | ||
124 | + padding: 36px 24px 0; | ||
125 | +} | ||
126 | + | ||
127 | +.recommend-text { | ||
128 | + font-size: 32px; | ||
129 | + color: #222222; | ||
130 | + font-weight: bold; | ||
131 | + text-align: left; | ||
132 | +} | ||
133 | + | ||
134 | +.recommend-list { | ||
135 | + margin-top: 30px; | ||
136 | +} | ||
137 | + | ||
138 | +</style> |
1 | +<template> | ||
2 | + <div class="container"> | ||
3 | + <WidgetAvatar :lazy="true" class="widget-avatar" :src="userHeadIco" :width="70" :height="70"></WidgetAvatar> | ||
4 | + <span>{{userName}}</span> | ||
5 | + </div> | ||
6 | +</template> | ||
7 | + | ||
8 | +<script> | ||
9 | +import WidgetAvatar from '../../../components/widget-avatar'; | ||
10 | + | ||
11 | +export default { | ||
12 | + name: 'articleAuthor', | ||
13 | + components: { | ||
14 | + WidgetAvatar | ||
15 | + }, | ||
16 | + props: { | ||
17 | + userHeadIco: String, | ||
18 | + userName: String | ||
19 | + } | ||
20 | +}; | ||
21 | +</script> | ||
22 | + | ||
23 | +<style lang="scss" scoped> | ||
24 | +.container { | ||
25 | + height: 100px; | ||
26 | + padding-left: 24px; | ||
27 | + display: flex; | ||
28 | + flex-direction: row; | ||
29 | + align-items: center; | ||
30 | + | ||
31 | + .widget-avatar { | ||
32 | + width: 70px; | ||
33 | + height: 70px; | ||
34 | + } | ||
35 | + | ||
36 | + span { | ||
37 | + margin-left: 20px; | ||
38 | + font-size: 24px; | ||
39 | + color: #222; | ||
40 | + letter-spacing: 0.05px; | ||
41 | + } | ||
42 | +} | ||
43 | +</style> |
1 | +<template> | ||
2 | + <div class="cover-slide"> | ||
3 | + <cube-slide ref="slide" :loop="false" :auto-play="false" :data="imageList"> | ||
4 | + <cube-slide-item v-for="(item, index) in imageList" :key="index" @click.native="clickHandler(item, index)"> | ||
5 | + <a click="javascript:void 0" class="square-img-container"> | ||
6 | + <SquareImg :src="item.image_url" :width="600" :height="600"/> | ||
7 | + </a> | ||
8 | + </cube-slide-item> | ||
9 | + <template slot="dots" slot-scope="props"> | ||
10 | + <div class="dot-wrap"> | ||
11 | + {{props.current + 1}}/{{imageList.length}} | ||
12 | + </div> | ||
13 | + </template> | ||
14 | + </cube-slide> | ||
15 | + </div> | ||
16 | +</template> | ||
17 | + | ||
18 | +<script> | ||
19 | +import { Slide } from 'cube-ui'; | ||
20 | +import SquareImg from '../../product/components/square-img'; | ||
21 | + | ||
22 | +export default { | ||
23 | + name: 'articleImage', | ||
24 | + components: { | ||
25 | + 'cube-slide': Slide, | ||
26 | + 'cube-slide-item': Slide.Item, | ||
27 | + SquareImg | ||
28 | + }, | ||
29 | + props: { | ||
30 | + imageList: Array | ||
31 | + }, | ||
32 | + data() { | ||
33 | + return { | ||
34 | + }; | ||
35 | + }, | ||
36 | + methods: { | ||
37 | + clickHandler(item, index) { | ||
38 | + console.log(item, index); | ||
39 | + } | ||
40 | + } | ||
41 | +}; | ||
42 | +</script> | ||
43 | + | ||
44 | +<style lang="scss" scoped> | ||
45 | +.cover-slide { | ||
46 | + flex: 1; | ||
47 | + | ||
48 | + .square-img-container { | ||
49 | + display: block; | ||
50 | + width: 100%; | ||
51 | + height: 750px; | ||
52 | + margin: 0 auto; | ||
53 | + } | ||
54 | + | ||
55 | + .dot-wrap { | ||
56 | + margin-left: 24px; | ||
57 | + margin-bottom: 24px; | ||
58 | + background: #000; | ||
59 | + opacity: 0.5; | ||
60 | + width: 80px; | ||
61 | + height: 48px; | ||
62 | + border-radius: 30px; | ||
63 | + color: white; | ||
64 | + font-size: 24px; | ||
65 | + letter-spacing: 1.96px; | ||
66 | + line-height: 48px; | ||
67 | + text-align: center; | ||
68 | + } | ||
69 | +} | ||
70 | + | ||
71 | +.cube-slide-item { | ||
72 | + img { | ||
73 | + margin: 0 auto; | ||
74 | + } | ||
75 | +} | ||
76 | + | ||
77 | +</style> |
1 | +<template> | ||
2 | + <div class="video-container"> | ||
3 | + <VideoPlayer | ||
4 | + ref="videoPlayer" | ||
5 | + class="videoWrapper" | ||
6 | + :source="videoUrl" | ||
7 | + :cover="coverUrl" | ||
8 | + ></VideoPlayer> | ||
9 | + </div> | ||
10 | +</template> | ||
11 | + | ||
12 | +<script> | ||
13 | +import VideoPlayer from '@/components/video-player'; | ||
14 | + | ||
15 | +export default { | ||
16 | + name: 'article-video', | ||
17 | + props: { | ||
18 | + videoUrl: String, | ||
19 | + coverUrl: String | ||
20 | + }, | ||
21 | + data() { | ||
22 | + return { | ||
23 | + }; | ||
24 | + }, | ||
25 | + components: { | ||
26 | + VideoPlayer | ||
27 | + } | ||
28 | +}; | ||
29 | +</script> | ||
30 | + | ||
31 | +<style scoped> | ||
32 | +.video-container { | ||
33 | + flex: 1; | ||
34 | +} | ||
35 | + | ||
36 | +.videoWrapper { | ||
37 | + display: block; | ||
38 | + width: 100%; | ||
39 | + height: 750px; | ||
40 | +} | ||
41 | + | ||
42 | +</style> |
@@ -27,7 +27,6 @@ export default { | @@ -27,7 +27,6 @@ export default { | ||
27 | data() { | 27 | data() { |
28 | return {}; | 28 | return {}; |
29 | }, | 29 | }, |
30 | - | ||
31 | methods: { | 30 | methods: { |
32 | imageformatError() { | 31 | imageformatError() { |
33 | console.log(6666); | 32 | console.log(6666); |
@@ -35,8 +34,9 @@ export default { | @@ -35,8 +34,9 @@ export default { | ||
35 | }, | 34 | }, |
36 | computed: {}, | 35 | computed: {}, |
37 | components: {} | 36 | components: {} |
38 | -} | 37 | +}; |
39 | </script> | 38 | </script> |
39 | + | ||
40 | <style lang="scss" scoped> | 40 | <style lang="scss" scoped> |
41 | .horizontalSlide { | 41 | .horizontalSlide { |
42 | overflow: hidden; | 42 | overflow: hidden; |
@@ -45,17 +45,20 @@ export default { | @@ -45,17 +45,20 @@ export default { | ||
45 | -webkit-overscroll-behavior-x: contain; | 45 | -webkit-overscroll-behavior-x: contain; |
46 | scroll-behavior: smooth; | 46 | scroll-behavior: smooth; |
47 | } | 47 | } |
48 | + | ||
48 | .list-warp { | 49 | .list-warp { |
49 | overflow-x: scroll; | 50 | overflow-x: scroll; |
50 | width: max-content; | 51 | width: max-content; |
51 | font-size: 0; | 52 | font-size: 0; |
52 | } | 53 | } |
54 | + | ||
53 | .list-item { | 55 | .list-item { |
54 | display: inline-flex; | 56 | display: inline-flex; |
55 | width: 600px; | 57 | width: 600px; |
56 | height: 180px; | 58 | height: 180px; |
57 | margin-right: 24px; | 59 | margin-right: 24px; |
58 | border-radius: 8px; | 60 | border-radius: 8px; |
61 | + | ||
59 | .image { | 62 | .image { |
60 | min-width: 136px; | 63 | min-width: 136px; |
61 | min-height: 180px; | 64 | min-height: 180px; |
@@ -64,6 +67,7 @@ export default { | @@ -64,6 +67,7 @@ export default { | ||
64 | border-radius: 8px 0 0 8px; | 67 | border-radius: 8px 0 0 8px; |
65 | filter: contrast(0.9); | 68 | filter: contrast(0.9); |
66 | } | 69 | } |
70 | + | ||
67 | .title { | 71 | .title { |
68 | font-size: 24px; | 72 | font-size: 24px; |
69 | color: #999; | 73 | color: #999; |
@@ -75,11 +79,13 @@ export default { | @@ -75,11 +79,13 @@ export default { | ||
75 | -webkit-line-clamp: 2; | 79 | -webkit-line-clamp: 2; |
76 | -webkit-box-orient: vertical; | 80 | -webkit-box-orient: vertical; |
77 | } | 81 | } |
82 | + | ||
78 | .bottom { | 83 | .bottom { |
79 | display: flex; | 84 | display: flex; |
80 | align-items: center; | 85 | align-items: center; |
81 | justify-content: space-between; | 86 | justify-content: space-between; |
82 | } | 87 | } |
88 | + | ||
83 | .info { | 89 | .info { |
84 | padding: 20px; | 90 | padding: 20px; |
85 | display: flex; | 91 | display: flex; |
@@ -88,6 +94,7 @@ export default { | @@ -88,6 +94,7 @@ export default { | ||
88 | border: 1px solid #F0F0F0; | 94 | border: 1px solid #F0F0F0; |
89 | border-radius: 0 8px 8px 0; | 95 | border-radius: 0 8px 8px 0; |
90 | } | 96 | } |
97 | + | ||
91 | .price { | 98 | .price { |
92 | margin-left: 16px; | 99 | margin-left: 16px; |
93 | font-size: 28px; | 100 | font-size: 28px; |
@@ -95,6 +102,7 @@ export default { | @@ -95,6 +102,7 @@ export default { | ||
95 | vertical-align: middle; | 102 | vertical-align: middle; |
96 | flex: 1 1 auto; | 103 | flex: 1 1 auto; |
97 | } | 104 | } |
105 | + | ||
98 | .icon-goumai { | 106 | .icon-goumai { |
99 | float: right; | 107 | float: right; |
100 | } | 108 | } |
@@ -7,11 +7,6 @@ export default [ | @@ -7,11 +7,6 @@ export default [ | ||
7 | { | 7 | { |
8 | name: 'ArticleDetail', | 8 | name: 'ArticleDetail', |
9 | path: '/xianyu/article/detail', | 9 | path: '/xianyu/article/detail', |
10 | - // component: () => import() | ||
11 | - }, | ||
12 | - { | ||
13 | - name: 'waterfall', | ||
14 | - path: '/xianyu/waterfallTest', | ||
15 | - component: () => import('./waterfall') | ||
16 | - }, | 10 | + component: () => import(/* webpackChunkName: "articleDetail" */ './articleDetail') |
11 | + } | ||
17 | ]; | 12 | ]; |
apps/pages/article/waterfall.vue
deleted
100644 → 0
1 | -<!-- | ||
2 | - * @description: | ||
3 | - * @fileName: waterfall.vue | ||
4 | - * @author: huzhiming | ||
5 | - * @date: 2019-12-18 15:23:55 | ||
6 | - * @后台人员: | ||
7 | - * @version: v1.0.0 | ||
8 | - * @path: 页面访问路径及参数说明 | ||
9 | -!--> | ||
10 | -<template> | ||
11 | - <div class="article-waterfall-wrap"> | ||
12 | - <horizontalSlide v-model="items" :style="{'margin': '20px 0 0 12px'}"></horizontalSlide> | ||
13 | - <!-- <div class="water"> | ||
14 | - <div class="piping" ref="piping0"></div> | ||
15 | - <div class="piping" ref="piping1"></div> | ||
16 | - <div class="piping" ref="piping2"></div> | ||
17 | - <div class="piping" ref="piping3"></div> | ||
18 | - </div> --> | ||
19 | - </div> | ||
20 | -</template> | ||
21 | - | ||
22 | -<script> | ||
23 | -import axios from 'axios'; | ||
24 | - | ||
25 | -import horizontalSlide from './components/horizontalSlide' | ||
26 | - | ||
27 | -export default { | ||
28 | - name: 'Article', | ||
29 | - mixins: [], | ||
30 | - props: {}, | ||
31 | - // 服务端渲染函数 | ||
32 | - async asyncData ({ isDev, route, store, env, params, query, req, res, redirect, error }) { | ||
33 | - return {} | ||
34 | - }, | ||
35 | - data() { | ||
36 | - return { | ||
37 | - items: [...Array(20).keys()].map(item => item), | ||
38 | - | ||
39 | - moments: [], | ||
40 | - available: 1, | ||
41 | - height1: 0, | ||
42 | - height2: 0, | ||
43 | - height3: 0, | ||
44 | - page: 1 | ||
45 | - } | ||
46 | - }, | ||
47 | - created() { | ||
48 | - // 获取第一页数据 | ||
49 | - // this.fetchMoments(); | ||
50 | - }, | ||
51 | - mounted() { | ||
52 | - // 用来监听滚轮 | ||
53 | - window.addEventListener("scroll", this.handleScroll); | ||
54 | - }, | ||
55 | - activated() {}, | ||
56 | - deactivated() {}, | ||
57 | - // beforeRouteEnter (to, from, next) {}, | ||
58 | - // beforeRouteUpdate(to, from, next) {}, | ||
59 | - // beforeRouteLeave(to, from, next) {}, | ||
60 | - destroyed() {}, | ||
61 | - methods: { | ||
62 | - fetchMoments() { | ||
63 | - // 请求接口方法 | ||
64 | - // const result = await this.$api.post('https://m.yohobuy.com/grass/api/grass/topicRelatedArticles', { | ||
65 | - // page, | ||
66 | - // limit: limit || 10, | ||
67 | - // type: 6, | ||
68 | - // topicId: 2713 | ||
69 | - // }); | ||
70 | - | ||
71 | - axios.get('https://m.yohobuy.com/grass/api/grass/topicRelatedArticles') | ||
72 | - .then(function (response) { | ||
73 | - console.log(response); | ||
74 | - }) | ||
75 | - .catch(function (error) { | ||
76 | - console.log(error); | ||
77 | - }); | ||
78 | - | ||
79 | - | ||
80 | - // https://m.yohobuy.com/grass/api/grass/topicRelatedArticles | ||
81 | - }, | ||
82 | - // sort()函数是递归的,因为要确保每个卡片的图片加载完成后再获取管道的高度,但是图片加载完成的函数是个异步函数, | ||
83 | - // 如果放在for循环中会打乱顺序,因此要使异步函数同步执行,for循环改为递归。 | ||
84 | - sort(j) { | ||
85 | - if (j < this.moments.length) { | ||
86 | - let that = this; | ||
87 | - // 创建Image类 | ||
88 | - var newImg = new Image(); | ||
89 | - // 获取要加载的图片地址 | ||
90 | - newImg.src = | ||
91 | - "http://lanyue.ink:8123/images/" + | ||
92 | - (Math.floor(Math.random() * 15) + 1) + | ||
93 | - ".png"; | ||
94 | - // 图片加载完成后(异步) | ||
95 | - newImg.onload = () => { | ||
96 | - // 四个管道的高度 | ||
97 | - var arr = [ | ||
98 | - that.$refs.piping0.offsetHeight, | ||
99 | - that.$refs.piping1.offsetHeight, | ||
100 | - that.$refs.piping2.offsetHeight, | ||
101 | - that.$refs.piping3.offsetHeight | ||
102 | - ]; | ||
103 | - //获取管道最小高度 | ||
104 | - var min = arr.indexOf(Math.min.apply(Math, arr)); | ||
105 | - // 添加卡片的模板 | ||
106 | - var html = | ||
107 | - `<div class="card"> | ||
108 | - <img src=` + newImg.src + `> | ||
109 | - <div> | ||
110 | - <img src="http://lanyue.ink:8123/images/avatar.jpg" alt=""> | ||
111 | - <div>` + this.moments[j].id + " " + this.moments[j].content + `</div> | ||
112 | - </div> | ||
113 | - </div>`; | ||
114 | - //给最小的管道添加卡片 | ||
115 | - if (min == 0) { | ||
116 | - that.$refs.piping0.innerHTML += html; | ||
117 | - } else if (min == 1) { | ||
118 | - that.$refs.piping1.innerHTML += html; | ||
119 | - } else if (min == 2) { | ||
120 | - that.$refs.piping2.innerHTML += html; | ||
121 | - } else if (min == 3) { | ||
122 | - that.$refs.piping3.innerHTML += html; | ||
123 | - } | ||
124 | - that.sort(j + 1); | ||
125 | - }; | ||
126 | - } | ||
127 | - }, | ||
128 | - handleScroll() { | ||
129 | - // 获取滚轮位置 | ||
130 | - var scrollTop = | ||
131 | - window.pageYOffset || | ||
132 | - document.documentElement.scrollTop || | ||
133 | - document.body.scrollTop; | ||
134 | - this.height1 = scrollTop; | ||
135 | - // 文档高度 | ||
136 | - this.height2 = document.body.scrollHeight; | ||
137 | - // 可视区域 | ||
138 | - this.height3 = | ||
139 | - document.compatMode == "CSS1Compat" | ||
140 | - ? document.documentElement.clientHeight | ||
141 | - : document.body.clientHeight; | ||
142 | - // 如果滚动到最低(这里设置离最底还有100距离才触发函数) | ||
143 | - // available条件是为了防止触底时一直不断地请求。因此,请求一次后available设为0,直到滚动到离底部超过100距离(即数据加载玩后)才设为1 | ||
144 | - if (this.height3 + this.height1 >= this.height2 - 100 && this.available) { | ||
145 | - //请求下一页 | ||
146 | - this.page++; | ||
147 | - this.available = 0; | ||
148 | - let that = this; | ||
149 | - fetch("api/moments?page=" + this.page) | ||
150 | - .then(res => res.json()) | ||
151 | - .then(res => { | ||
152 | - that.moments = res.data; | ||
153 | - if (that.moments[0]) { | ||
154 | - that.sort(0); | ||
155 | - } else { | ||
156 | - that.page--; | ||
157 | - } | ||
158 | - }); | ||
159 | - } else if (this.height3 + this.height1 < this.height2 - 100) { | ||
160 | - this.available = 1; | ||
161 | - } | ||
162 | - } | ||
163 | - }, | ||
164 | - computed: {}, | ||
165 | - watch: {}, | ||
166 | - components: { | ||
167 | - horizontalSlide | ||
168 | - } | ||
169 | -}; | ||
170 | -</script> | ||
171 | - | ||
172 | -/* 定义局部样式,添加外围容器,scss嵌套尽量不要超过三层,会影响查找器性能 */ | ||
173 | -<style rel='stylesheet/scss' lang='scss' scoped> | ||
174 | -.waterfall-wrap {} | ||
175 | -//@import "./style.scss"; | ||
176 | -</style> | ||
177 | - | ||
178 | -/* 定义全局样式,添加外围容器,避免覆盖全局样式, 若不需要,请删除 */ | ||
179 | -<style rel='stylesheet/scss' lang='scss'> | ||
180 | -.waterfall-wrap {} | ||
181 | -</style> |
-
Please register or login to post a comment