Showing
6 changed files
with
314 additions
and
309 deletions
1 | <template> | 1 | <template> |
2 | - <div v-if="data.topicImageUrl" class="topic-head" :style="headStyle"> | ||
3 | - <div class="center"> | ||
4 | - <p class="desc">{{data.topicDesc}}</p> | ||
5 | - <div v-if="showAttAmount" class="att-amount"> | ||
6 | - <label>{{data.attAmount}}人已关注</label> | ||
7 | - </div> | ||
8 | - <div v-if="+data.allowAttention" class="att-topic-btn" :class="attClass" @click="onClick"> | ||
9 | - <WidgetFollow v-if="!share" class="att-click-wrap" :topic-id="data.topicId" :follow="data.hasAttention" @on-follow="onFollow"></WidgetFollow> | ||
10 | - <template v-if="data.hasAttention"> | ||
11 | - 已关注 | ||
12 | - </template> | ||
13 | - <template v-else> | ||
14 | - <span class="iconfont icon-plus"></span> | ||
15 | - 关注话题 | ||
16 | - </template> | 2 | + <div class="topic-banner" :style="headStyle"> |
3 | + <div class="banner-main"> | ||
4 | + <div class="topic-name">{{data.topicName}}</div> | ||
5 | + <p class="topic-desc">{{data.topicDesc}}</p> | ||
6 | + <div class="topic-extra"> | ||
7 | + <label class="att-amount">{{data.articleAmount}}人参与讨论</label> | ||
8 | + <WidgetFollow v-if="+data.allowAttention" class="att-click-wrap" :topic-id="data.topicId" :follow="data.hasAttention" :share="share" @on-follow="onFollow"></WidgetFollow> | ||
17 | </div> | 9 | </div> |
18 | </div> | 10 | </div> |
19 | </div> | 11 | </div> |
20 | - <div v-else class="topic-head-empty" :style="headStyle"></div> | ||
21 | </template> | 12 | </template> |
22 | 13 | ||
23 | <script> | 14 | <script> |
@@ -44,22 +35,9 @@ export default { | @@ -44,22 +35,9 @@ export default { | ||
44 | } | 35 | } |
45 | 36 | ||
46 | return style; | 37 | return style; |
47 | - }, | ||
48 | - showAttAmount() { | ||
49 | - return this.data && +this.data.showAttAmount > 0; | ||
50 | - }, | ||
51 | - attClass() { | ||
52 | - return { | ||
53 | - active: this.data.hasAttention | ||
54 | - }; | ||
55 | } | 38 | } |
56 | }, | 39 | }, |
57 | methods: { | 40 | methods: { |
58 | - onClick() { | ||
59 | - if (this.share) { | ||
60 | - return this.$links.toDownloadApp(); | ||
61 | - } | ||
62 | - }, | ||
63 | onFollow(follow) { | 41 | onFollow(follow) { |
64 | this.$emit('on-follow', follow); | 42 | this.$emit('on-follow', follow); |
65 | }, | 43 | }, |
@@ -68,98 +46,70 @@ export default { | @@ -68,98 +46,70 @@ export default { | ||
68 | </script> | 46 | </script> |
69 | 47 | ||
70 | <style scoped> | 48 | <style scoped> |
71 | -.topic-head { | ||
72 | - min-height: 360px; | ||
73 | - background-size: 100%; | ||
74 | - box-sizing: border-box; | ||
75 | - position: relative; | 49 | +.topic-banner { |
76 | background-size: cover; | 50 | background-size: cover; |
77 | - display: flex; | ||
78 | - align-items: center; | 51 | + background-repeat: no-repeat; |
52 | + background-color: #eee; | ||
53 | + color: #fff; | ||
54 | + position: relative; | ||
79 | 55 | ||
80 | - &:before { | ||
81 | - content: ""; | ||
82 | - height: 1px; | ||
83 | - position: absolute; | ||
84 | - top: -1px; | ||
85 | - left: 0; | ||
86 | - right: 0; | ||
87 | - z-index: 1; | ||
88 | - box-shadow: 0 0 140px 40px #000; | 56 | + .banner-main { |
57 | + height: 240px; | ||
89 | } | 58 | } |
90 | 59 | ||
91 | - .center { | ||
92 | - width: 100%; | ||
93 | - position: relative; | ||
94 | - z-index: 2; | ||
95 | - text-align: center; | ||
96 | - padding: 40px 100px; | ||
97 | - box-sizing: border-box; | 60 | + .topic-name { |
61 | + height: 50px; | ||
62 | + padding: 0 30px; | ||
63 | + margin: 30px 0 18px; | ||
64 | + font-size: 36px; | ||
65 | + letter-spacing: 0.09PX; | ||
66 | + font-weight: 800; | ||
67 | + display: flex; | ||
68 | + align-items: center; | ||
98 | } | 69 | } |
99 | 70 | ||
100 | - .desc { | 71 | + .topic-desc { |
72 | + padding: 0 30px; | ||
73 | + height: 60px; | ||
101 | font-size: 24px; | 74 | font-size: 24px; |
102 | - color: #fff; | ||
103 | - line-height: 1.42; | ||
104 | - word-break: break-all; | 75 | + font-weight: 300; |
76 | + line-height: 30px; | ||
77 | + overflow: hidden; | ||
78 | + text-overflow: ellipsis; | ||
79 | + display: -webkit-box; | ||
80 | + -webkit-line-clamp: 2; | ||
81 | + -webkit-box-orient: vertical; | ||
105 | } | 82 | } |
106 | 83 | ||
107 | - $attColor: #b0b0b0; | ||
108 | - | ||
109 | - .att-amount { | ||
110 | - margin-top: 20px; | ||
111 | - color: $attColor; | ||
112 | - display: flex; | ||
113 | - justify-content: center; | ||
114 | - | ||
115 | - label { | ||
116 | - display: inline-block; | ||
117 | - position: relative; | ||
118 | - line-height: 1; | ||
119 | - | ||
120 | - &:before, | ||
121 | - &:after { | ||
122 | - content: ""; | ||
123 | - width: 60px; | ||
124 | - height: 2px; | ||
125 | - background-color: $attColor; | ||
126 | - display: block; | ||
127 | - position: absolute; | ||
128 | - top: 50%; | ||
129 | - margin-top: -1px; | ||
130 | - } | ||
131 | - | ||
132 | - &:before { | ||
133 | - right: calc(100% + 20px); | ||
134 | - } | ||
135 | - | ||
136 | - &:after { | ||
137 | - left: calc(100% + 20px); | ||
138 | - } | ||
139 | - } | ||
140 | - } | ||
141 | - | ||
142 | - .att-topic-btn { | ||
143 | - width: 200px; | ||
144 | - height: 50px; | ||
145 | - font-size: 26px; | ||
146 | - border-radius: 28px; | ||
147 | - line-height: 1; | 84 | + .topic-extra { |
85 | + width: 100%; | ||
86 | + height: 36px; | ||
87 | + margin: 34px 0 40px; | ||
148 | display: flex; | 88 | display: flex; |
149 | align-items: center; | 89 | align-items: center; |
150 | - justify-content: center; | ||
151 | - background-color: #d90025; | ||
152 | - color: #fff; | ||
153 | - margin: 36px auto 0; | ||
154 | - position: relative; | 90 | + justify-content: space-between; |
155 | 91 | ||
156 | - .iconfont { | ||
157 | - font-weight: bold; | ||
158 | - margin-right: 10px; | 92 | + .att-amount { |
93 | + font-size: 26px; | ||
94 | + font-weight: 700px; | ||
95 | + margin-left: 30px; | ||
159 | } | 96 | } |
160 | 97 | ||
161 | - &.active { | ||
162 | - background-color: #e48a8a; | 98 | + .att-click-wrap { |
99 | + width: 190px; | ||
100 | + height: 60px; | ||
101 | + padding-right: 36px; | ||
102 | + margin-right: -32px; | ||
103 | + border-radius: 31px; | ||
104 | + border-color: #ff5660; | ||
105 | + background-color: #ff5660; | ||
106 | + color: #fff; | ||
107 | + font-size: 32px; | ||
108 | + | ||
109 | + &.follow { | ||
110 | + background: none; | ||
111 | + border-color: #fff; | ||
112 | + } | ||
163 | } | 113 | } |
164 | } | 114 | } |
165 | } | 115 | } |
1 | <template> | 1 | <template> |
2 | - <div class="fixed-header" :style="`background: rgba(64,64,64,${stepPercent});`"> | 2 | + <div class="fixed-header" :class="{'full-header': step >= 100}" :style="`background: rgba(255,255,255,${stepPercent});`"> |
3 | <LayoutHeader theme="transparent"> | 3 | <LayoutHeader theme="transparent"> |
4 | <template> | 4 | <template> |
5 | - <div ref="titleBlock" class="title-block"> | ||
6 | - <span :style="titleStyle">#{{title}}</span> | ||
7 | - </div> | ||
8 | - <div v-if="!share && +data.allowAttention" class="att-topic-btn" :class="attClass"> | ||
9 | - <WidgetFollow class="att-click-wrap" :topic-id="data.topicId" :follow="data.hasAttention" :share="share" @on-follow="onFollow"></WidgetFollow> | ||
10 | - <span>{{data.hasAttention ? '已关注' : '关注'}}</span> | ||
11 | - </div> | 5 | + <div ref="titleBlock" class="title-block" :style="titleStyle">#{{title}}</div> |
12 | </template> | 6 | </template> |
13 | <template v-slot:opts> | 7 | <template v-slot:opts> |
14 | <WidgetShare v-if="!share" class="topic-share" :option="shareOption" @click.native="onShare"></WidgetShare> | 8 | <WidgetShare v-if="!share" class="topic-share" :option="shareOption" @click.native="onShare"></WidgetShare> |
15 | </template> | 9 | </template> |
16 | </LayoutHeader> | 10 | </LayoutHeader> |
11 | + <div class="suction-top-block"> | ||
12 | + <slot name="suctionTop"></slot> | ||
13 | + </div> | ||
17 | </div> | 14 | </div> |
18 | </template> | 15 | </template> |
19 | 16 | ||
@@ -39,41 +36,42 @@ export default { | @@ -39,41 +36,42 @@ export default { | ||
39 | ], | 36 | ], |
40 | computed: { | 37 | computed: { |
41 | stepPercent() { | 38 | stepPercent() { |
42 | - return parseInt(this.step, 10) / 100; | 39 | + let percent = parseInt(this.step, 10) / 100; |
40 | + | ||
41 | + this.setIconColor(Math.floor((255 - 34) * (1 - percent) + 34)); | ||
42 | + | ||
43 | + return percent; | ||
43 | }, | 44 | }, |
44 | titleStyle() { | 45 | titleStyle() { |
45 | - let style = {}; | ||
46 | - let stepPercent = this.stepPercent; | ||
47 | - | ||
48 | - if (!this.offsetLeft) { | ||
49 | - this.updateTitleOffset(); | ||
50 | - } | 46 | + const criticalPercent = 0.3; |
47 | + const style = { | ||
48 | + opacity: 0 | ||
49 | + }; | ||
51 | 50 | ||
52 | - if (get(this, '$yoho.isiOS')) { | ||
53 | - style.transform = `translate3d(${-stepPercent * this.offsetLeft}px, 0, 0)`; | ||
54 | - } else { | ||
55 | - style.transform = `translate3d(${this.stepPercent > 0.86 ? -this.offsetLeft : 0}px, 0, 0)`; | 51 | + if (this.stepPercent > criticalPercent) { |
52 | + style.opacity = ((this.stepPercent - criticalPercent) / (1 - criticalPercent)).toFixed(2); | ||
56 | } | 53 | } |
57 | 54 | ||
58 | return style; | 55 | return style; |
59 | - }, | ||
60 | - attClass() { | ||
61 | - return { | ||
62 | - active: this.data.hasAttention, | ||
63 | - show: this.stepPercent > 0.86 | ||
64 | - }; | ||
65 | } | 56 | } |
66 | }, | 57 | }, |
67 | - watch: { | ||
68 | - title() { | ||
69 | - this.offsetLeft = 0; | ||
70 | - } | 58 | + mounted() { |
59 | + this._iconColor && this.setIconColor(this._iconColor); | ||
71 | }, | 60 | }, |
72 | methods: { | 61 | methods: { |
73 | - updateTitleOffset() { | ||
74 | - if (this.$refs && this.$refs.titleBlock) { | ||
75 | - this.$nextTick(() => { | ||
76 | - this.offsetLeft = this.$refs.titleBlock.offsetLeft + 40; | 62 | + setIconColor(color) { |
63 | + if (!this.$el) { | ||
64 | + this._iconColor = color; | ||
65 | + return; | ||
66 | + } | ||
67 | + | ||
68 | + if (!this.icons) { | ||
69 | + this.icons = [...this.$el.querySelectorAll('.back .iconfont'), ...this.$el.querySelectorAll('.opts .iconfont')]; | ||
70 | + } | ||
71 | + | ||
72 | + if (this.icons && this.icons.length) { | ||
73 | + this.icons.forEach(dom => { | ||
74 | + dom.style.color = `rgb(${color},${color},${color})`; | ||
77 | }); | 75 | }); |
78 | } | 76 | } |
79 | }, | 77 | }, |
@@ -89,30 +87,34 @@ export default { | @@ -89,30 +87,34 @@ export default { | ||
89 | 87 | ||
90 | <style scoped> | 88 | <style scoped> |
91 | .fixed-header { | 89 | .fixed-header { |
92 | - position: fixed; | 90 | + position: absolute; |
93 | width: 100%; | 91 | width: 100%; |
94 | z-index: 10; | 92 | z-index: 10; |
95 | - transition: all 500ms; | 93 | + transition: background 50ms; |
94 | + | ||
95 | + &.full-header:after { | ||
96 | + content: ""; | ||
97 | + background-color: #fff; | ||
98 | + position: absolute; | ||
99 | + left: 0; | ||
100 | + right: 0; | ||
101 | + top: 0; | ||
102 | + bottom: 0; | ||
103 | + z-index: -1; | ||
104 | + } | ||
96 | 105 | ||
97 | /deep/ .title { | 106 | /deep/ .title { |
98 | overflow: visible!important; | 107 | overflow: visible!important; |
99 | } | 108 | } |
100 | 109 | ||
101 | .title-block { | 110 | .title-block { |
102 | - font-size: 0; | ||
103 | - | ||
104 | - > span { | ||
105 | - max-width: 400px; | ||
106 | - line-height: 1.2; | ||
107 | - font-size: 36px; | ||
108 | - display: inline-block; | ||
109 | - vertical-align: super; | ||
110 | - overflow: hidden; | ||
111 | - text-overflow:ellipsis; | ||
112 | - white-space: nowrap; | ||
113 | - position: relative; | ||
114 | - transition: all 116ms; | ||
115 | - } | 111 | + color: #222; |
112 | + line-height: 1.2; | ||
113 | + font-size: 36px; | ||
114 | + overflow: hidden; | ||
115 | + text-overflow:ellipsis; | ||
116 | + white-space: nowrap; | ||
117 | + transition: opacity 100ms; | ||
116 | } | 118 | } |
117 | 119 | ||
118 | .att-topic-btn { | 120 | .att-topic-btn { |
@@ -153,5 +155,11 @@ export default { | @@ -153,5 +155,11 @@ export default { | ||
153 | .topic-share { | 155 | .topic-share { |
154 | margin-right: 26px; | 156 | margin-right: 26px; |
155 | } | 157 | } |
158 | + | ||
159 | + .suction-top-block { | ||
160 | + width: 100%; | ||
161 | + position: absolute; | ||
162 | + top: 100%; | ||
163 | + } | ||
156 | } | 164 | } |
157 | </style> | 165 | </style> |
1 | +<template> | ||
2 | + <div class="tab-block"> | ||
3 | + <div v-for="(tab, index) in tabList" :key="index" :ref="'tab-item' + index" class="tab-item" :class="{active: index == activeIndex}" @click="changeType(index)"> | ||
4 | + <div class="name">{{tab.name}}</div> | ||
5 | + <div v-if="index == statusBlockIndex" ref="statusBlock" class="tab-status-block" :style="statusBlockStyle"></div> | ||
6 | + </div> | ||
7 | + </div> | ||
8 | +</template> | ||
9 | + | ||
10 | +<script> | ||
11 | +import {findIndex} from 'lodash'; | ||
12 | + | ||
13 | +export default { | ||
14 | + props: { | ||
15 | + activeType: { | ||
16 | + type: Number, | ||
17 | + default: 0 | ||
18 | + } | ||
19 | + }, | ||
20 | + data() { | ||
21 | + let tabList = [ | ||
22 | + {name: '最新', type: 2}, | ||
23 | + {name: '热门', type: 1}, | ||
24 | + ]; | ||
25 | + let index = Math.max(findIndex(tabList, {type: this.activeType}), 0); | ||
26 | + | ||
27 | + return { | ||
28 | + tabList, | ||
29 | + statusBlockIndex: index, | ||
30 | + activeIndex: index, | ||
31 | + statusBlockStyle: {} | ||
32 | + }; | ||
33 | + }, | ||
34 | + watch: { | ||
35 | + activeType(val) { | ||
36 | + let index = findIndex(this.tabList, {type: val}); | ||
37 | + | ||
38 | + if (index > -1) { | ||
39 | + this.activeIndex = index; | ||
40 | + } | ||
41 | + }, | ||
42 | + activeIndex() { | ||
43 | + this.changeStatusBlockStyle(); | ||
44 | + } | ||
45 | + }, | ||
46 | + methods: { | ||
47 | + changeType(index) { | ||
48 | + this.activeIndex = index; | ||
49 | + this.$emit('on-change-tab', {...this.tabList[index]}); | ||
50 | + }, | ||
51 | + changeStatusBlockStyle() { | ||
52 | + const baseDom = this.$refs['tab-item' + this.statusBlockIndex]; | ||
53 | + | ||
54 | + if (baseDom) { | ||
55 | + const baseLeft = baseDom[0].offsetLeft; | ||
56 | + const {offsetLeft, offsetWidth} = this.$refs['tab-item' + this.activeIndex][0] || {}; | ||
57 | + | ||
58 | + this.statusBlockStyle = { | ||
59 | + transform: `translate3d(${offsetLeft - baseLeft}px, 0, 0)`, | ||
60 | + width: offsetWidth + 'px' | ||
61 | + }; | ||
62 | + } | ||
63 | + } | ||
64 | + } | ||
65 | +}; | ||
66 | +</script> | ||
67 | + | ||
68 | +<style scoped> | ||
69 | +.tab-block { | ||
70 | + height: 100px; | ||
71 | + background-color: #fff; | ||
72 | + display: flex; | ||
73 | + justify-content: center; | ||
74 | + font-size: 32px; | ||
75 | + | ||
76 | + .tab-item { | ||
77 | + margin: 0 38px; | ||
78 | + padding-top: 20px; | ||
79 | + color: #b0b0b0; | ||
80 | + position: relative; | ||
81 | + | ||
82 | + &.active { | ||
83 | + color: #222; | ||
84 | + font-weight: 500; | ||
85 | + } | ||
86 | + | ||
87 | + .name { | ||
88 | + margin-bottom: 4px; | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | + .tab-status-block { | ||
93 | + width: 100%; | ||
94 | + height: 10px; | ||
95 | + background: #d0021b; | ||
96 | + box-shadow: 0 4px 8px 0 rgba(210,0,13,0.34); | ||
97 | + position: absolute; | ||
98 | + transition: all 500ms; | ||
99 | + } | ||
100 | +} | ||
101 | + | ||
102 | +</style> |
1 | <template> | 1 | <template> |
2 | <div> | 2 | <div> |
3 | <Layout class="article"> | 3 | <Layout class="article"> |
4 | - <TopicHeader ref="header" :title="topicTitle" :step="headerAnimateStep" :data="topicSimpleInfo" :share="share" @on-follow="onFollowTopic"></TopicHeader> | 4 | + <TopicHeader ref="header" :title="topicTitle" :step="headerAnimateStep" :data="topicSimpleInfo" :share="share" @on-follow="onFollowTopic"> |
5 | + <template v-if="tabBlockSuctionTop" v-slot:suctionTop> | ||
6 | + <TopicTabBlock :active-type="activeTopicListType" @on-change-tab="onChangeTab"></TopicTabBlock> | ||
7 | + </template> | ||
8 | + </TopicHeader> | ||
5 | 9 | ||
6 | <RecycleScrollReveal :size="5" :thumbs="thumbs" ref="scroll" @scroll="onScroll" :offset="800" :on-fetch="onFetch" :manual-init="true" | 10 | <RecycleScrollReveal :size="5" :thumbs="thumbs" ref="scroll" @scroll="onScroll" :offset="800" :on-fetch="onFetch" :manual-init="true" |
7 | @on-inited="onInited"> | 11 | @on-inited="onInited"> |
8 | <template v-slot:eternalTop> | 12 | <template v-slot:eternalTop> |
9 | - <TopicBanner ref="topicHead" :data="topicSimpleInfo" :share="share" @on-follow="onFollowTopic"></TopicBanner> | 13 | + <TopicBanner ref="topicBanner" :data="topicSimpleInfo" :share="share" @on-follow="onFollowTopic"></TopicBanner> |
14 | + <TopicTabBlock :active-type="activeTopicListType" @on-change-tab="onChangeTab"></TopicTabBlock> | ||
10 | </template> | 15 | </template> |
11 | <template class="article-item" #item="{ data }"> | 16 | <template class="article-item" #item="{ data }"> |
12 | <ArticleItem2 | 17 | <ArticleItem2 |
@@ -31,17 +36,6 @@ | @@ -31,17 +36,6 @@ | ||
31 | 立即参与 | 36 | 立即参与 |
32 | </a> | 37 | </a> |
33 | </Layout> | 38 | </Layout> |
34 | - <ArticleActionSheet v-if="showArticleDetailAction" ref="actionSheet"></ArticleActionSheet> | ||
35 | - <YohoActionSheet transfer v-if="showCommentAction" ref="commentAction" :full="true"> | ||
36 | - <Comment ref="comment" | ||
37 | - :destId="articleId" | ||
38 | - :popup="true" | ||
39 | - :article-id="articleId" | ||
40 | - :pos-id="posId" | ||
41 | - @on-close="onClose" | ||
42 | - @on-comment="onActionComment"></Comment> | ||
43 | - </YohoActionSheet> | ||
44 | - <MoreActionSheet transfer ref="moreAction" @on-follow="onFollow" @on-delete="onDelete"></MoreActionSheet> | ||
45 | </div> | 39 | </div> |
46 | </template> | 40 | </template> |
47 | 41 | ||
@@ -55,6 +49,7 @@ import ArticleActionSheet from './components/detail/article-action-sheet'; | @@ -55,6 +49,7 @@ import ArticleActionSheet from './components/detail/article-action-sheet'; | ||
55 | import MoreActionSheet from './components/detail/more-action-sheet'; | 49 | import MoreActionSheet from './components/detail/more-action-sheet'; |
56 | import TopicHeader from './components/topic/header'; | 50 | import TopicHeader from './components/topic/header'; |
57 | import TopicBanner from './components/topic/banner'; | 51 | import TopicBanner from './components/topic/banner'; |
52 | +import TopicTabBlock from './components/topic/tab-block'; | ||
58 | import {mapState as mapYohoState, mapActions as mapYohoActions, mapMutations as mapYohoMutations, createNamespacedHelpers} from 'vuex'; | 53 | import {mapState as mapYohoState, mapActions as mapYohoActions, mapMutations as mapYohoMutations, createNamespacedHelpers} from 'vuex'; |
59 | const {mapState, mapMutations, mapActions} = createNamespacedHelpers('article'); | 54 | const {mapState, mapMutations, mapActions} = createNamespacedHelpers('article'); |
60 | 55 | ||
@@ -70,14 +65,8 @@ export default { | @@ -70,14 +65,8 @@ export default { | ||
70 | topicId: 0, | 65 | topicId: 0, |
71 | topicName: '', | 66 | topicName: '', |
72 | headerAnimateStep: 0, | 67 | headerAnimateStep: 0, |
73 | - articleId: 0, | ||
74 | - articleIndex: -1, | ||
75 | - showCommentAction: false, | ||
76 | - showCommentActioning: false, | ||
77 | - showArticleDetailAction: false, | ||
78 | - showMoreAction: true, | ||
79 | scrollTop: 0, | 68 | scrollTop: 0, |
80 | - currentId: 0, | 69 | + activeTopicListType: 2, |
81 | colWidthForTwo: 0, | 70 | colWidthForTwo: 0, |
82 | scrolling: false | 71 | scrolling: false |
83 | }; | 72 | }; |
@@ -140,11 +129,25 @@ export default { | @@ -140,11 +129,25 @@ export default { | ||
140 | return this.topicInfo[this.topicId] || {}; | 129 | return this.topicInfo[this.topicId] || {}; |
141 | }, | 130 | }, |
142 | publishUrl() { | 131 | publishUrl() { |
143 | - return this.topicId ? `?openby:yohobuy={"action":"go.grasspublish","params":{"topicId":"${this.topicId}","topicName":"${this.topicName}"}}` : ''; | 132 | + let params = {}; |
133 | + | ||
134 | + if (this.topicId) { | ||
135 | + params.topicId = this.topicId; | ||
136 | + params.topicName = this.topicName; | ||
137 | + | ||
138 | + if (+this.topicSimpleInfo.isReward === 1) { | ||
139 | + params.rewardNotice = this.topicSimpleInfo.rewardNotice; | ||
140 | + } | ||
141 | + } | ||
142 | + | ||
143 | + return `?openby:yohobuy={"action":"go.grasspublish","params":${JSON.stringify(params)}}`; | ||
144 | }, | 144 | }, |
145 | topicTitle() { | 145 | topicTitle() { |
146 | return this.topicName || this.topicSimpleInfo.topicName || ''; | 146 | return this.topicName || this.topicSimpleInfo.topicName || ''; |
147 | }, | 147 | }, |
148 | + tabBlockSuctionTop() { | ||
149 | + return this.scrollTop >= (this._topicHeaderHeight - this._headerHeight); | ||
150 | + }, | ||
148 | headerBgOpacity() { | 151 | headerBgOpacity() { |
149 | return this.headerAnimateStep / 100; | 152 | return this.headerAnimateStep / 100; |
150 | } | 153 | } |
@@ -152,78 +155,38 @@ export default { | @@ -152,78 +155,38 @@ export default { | ||
152 | methods: { | 155 | methods: { |
153 | ...mapYohoActions(['fetchUserProfile']), | 156 | ...mapYohoActions(['fetchUserProfile']), |
154 | ...mapYohoMutations(['SET_STATUS_BAR_COLOR']), | 157 | ...mapYohoMutations(['SET_STATUS_BAR_COLOR']), |
155 | - ...mapActions(['fetchTopicSimpleInfo', 'fetchTopicRelatedArticles', 'fetchArticleProductFavs']), | ||
156 | - ...mapMutations(['ASYNC_ARTICLE_COMMENT', 'CHANGE_AUTHOR_FOLLOW', 'CHANGE_TOPIC_FOLLOW']), | ||
157 | - onShowComment({articleId, index}) { | ||
158 | - this.articleId = articleId; | ||
159 | - this.articleIndex = index; | ||
160 | - this.showCommentAction = true; | ||
161 | - this.$nextTick(() => { | ||
162 | - if (this.showCommentActioning) { | ||
163 | - return; | ||
164 | - } | ||
165 | - this.showCommentActioning = true; | ||
166 | - this.$refs.comment.init(); | ||
167 | - this.$refs.commentAction.show(); | ||
168 | - setTimeout(() => { | ||
169 | - this.showCommentActioning = false; | ||
170 | - }, 300); | ||
171 | - }); | ||
172 | - }, | ||
173 | - onShowMore({article, index}) { | ||
174 | - this.$refs.moreAction.show(article, this.userUid, index); | ||
175 | - }, | ||
176 | - onDelete(index) { | ||
177 | - this.$refs.scroll.delete(index); | ||
178 | - }, | ||
179 | - onPageReady({success}) { | ||
180 | - if (success && this.showCommentAction) { | ||
181 | - this.$refs.commentAction.show(); | ||
182 | - setTimeout(() => { | ||
183 | - this.showCommentActioning = false; | ||
184 | - }, 300); | ||
185 | - } else { | ||
186 | - this.showCommentActioning = false; | ||
187 | - } | ||
188 | - }, | ||
189 | - onUnlockHeight(params) { | ||
190 | - this.$refs.scroll.unlockHight(params); | ||
191 | - }, | ||
192 | - onClose() { | ||
193 | - this.$refs.commentAction.hide(); | ||
194 | - }, | ||
195 | - onActionComment() { | ||
196 | - this.ASYNC_ARTICLE_COMMENT({articleId: this.articleId, type: this.type}); | ||
197 | - this.onResize(this.articleIndex); | 158 | + ...mapActions(['fetchTopicSimpleInfo', 'fetchTopicRelatedArticles']), |
159 | + ...mapMutations(['CHANGE_AUTHOR_FOLLOW', 'CHANGE_TOPIC_FOLLOW']), | ||
160 | + onChangeTab({type}) { | ||
161 | + this.page = 1; | ||
162 | + this.activeTopicListType = type; | ||
163 | + this.$refs.scroll && this.$refs.scroll.init(); | ||
198 | }, | 164 | }, |
199 | - onScroll(params) { | 165 | + onScroll({item, scrollTop, startIndex, items}) { |
200 | this.scrolling = true; | 166 | this.scrolling = true; |
201 | this._scTimer && clearTimeout(this._scTimer); | 167 | this._scTimer && clearTimeout(this._scTimer); |
202 | this._scTimer = setTimeout(() => { | 168 | this._scTimer = setTimeout(() => { |
203 | this.scrolling = false; | 169 | this.scrolling = false; |
204 | }, 400); | 170 | }, 400); |
205 | 171 | ||
206 | - this.scrollEvent(params); | ||
207 | - this._ttTimer && clearTimeout(this._ttTimer); | ||
208 | - this._ttTimer = setTimeout(() => { | ||
209 | - this.scrollEvent(params); | ||
210 | - }, throttleTime); | 172 | + this.updateHeadAnimateStep(scrollTop); |
173 | + this.scrollTop = scrollTop || 0; | ||
174 | + this.scrollEvent({item, scrollTop, startIndex, items}); | ||
211 | }, | 175 | }, |
212 | - onDounceScroll({item, scrollTop, startIndex, items}) { | 176 | + updateHeadAnimateStep(scrollTop) { |
213 | if (this.scrollTop === scrollTop) { | 177 | if (this.scrollTop === scrollTop) { |
214 | return; | 178 | return; |
215 | } | 179 | } |
216 | 180 | ||
217 | - this.scrollTop = scrollTop || 0; | ||
218 | this._headerHeight = this._headerHeight || this.$refs.header.$el.offsetHeight; | 181 | this._headerHeight = this._headerHeight || this.$refs.header.$el.offsetHeight; |
219 | - this._topicHeaderHeight = this._topicHeaderHeight || this.$refs.topicHead.$el.offsetHeight; | ||
220 | - | ||
221 | - let step = Math.round((scrollTop - 10) / (this._topicHeaderHeight - this._headerHeight) * 100); | 182 | + this._topicHeaderHeight = this._topicHeaderHeight || this.$refs.topicBanner.$el.offsetHeight; |
222 | 183 | ||
223 | - if (step && this.topicSimpleInfo.topicImageUrl) { | 184 | + let step = Math.round((scrollTop - 4) / (this._topicHeaderHeight - this._headerHeight - 10) * 100); |
185 | + if (step) { | ||
224 | this.headerAnimateStep = Math.max(Math.min(step, 100), 0); | 186 | this.headerAnimateStep = Math.max(Math.min(step, 100), 0); |
225 | } | 187 | } |
226 | - | 188 | + }, |
189 | + onDounceScroll({items}) { | ||
227 | this.reportArticleShow(items); | 190 | this.reportArticleShow(items); |
228 | }, | 191 | }, |
229 | init() { | 192 | init() { |
@@ -254,9 +217,13 @@ export default { | @@ -254,9 +217,13 @@ export default { | ||
254 | this.headerAnimateStep = 100; | 217 | this.headerAnimateStep = 100; |
255 | } | 218 | } |
256 | }), | 219 | }), |
257 | - this.fetchTopicRelatedArticles({topicId: this.topicId, page: 1}).then(res => { | 220 | + this.fetchTopicRelatedArticles({ |
221 | + topicId: this.topicId, | ||
222 | + type: this.activeTopicListType, | ||
223 | + page: 1 | ||
224 | + }).then(res => { | ||
258 | if (res.code === 200) { | 225 | if (res.code === 200) { |
259 | - this.listPreCache[`${this.topicId}-1`] = res; | 226 | + this.listPreCache[`${this.topicId}-${this.activeTopicListType}-1`] = res; |
260 | } | 227 | } |
261 | }) | 228 | }) |
262 | ]); | 229 | ]); |
@@ -271,12 +238,15 @@ export default { | @@ -271,12 +238,15 @@ export default { | ||
271 | this.fetching = true; | 238 | this.fetching = true; |
272 | this.page = this.page || 1; | 239 | this.page = this.page || 1; |
273 | 240 | ||
274 | - let result = get(this.listPreCache, `${this.topicId}-${this.page}`); | 241 | + let result = get(this.listPreCache, `${this.topicId}-${this.activeTopicListType}-${this.page}`); |
275 | 242 | ||
276 | - if (!result) { | 243 | + if (result) { |
244 | + this.listPreCache = {}; | ||
245 | + } else { | ||
277 | result = await this.fetchTopicRelatedArticles({ | 246 | result = await this.fetchTopicRelatedArticles({ |
278 | topicId, | 247 | topicId, |
279 | - page: this.page | 248 | + page: this.page, |
249 | + type: this.activeTopicListType | ||
280 | }); | 250 | }); |
281 | } | 251 | } |
282 | 252 | ||
@@ -304,24 +274,10 @@ export default { | @@ -304,24 +274,10 @@ export default { | ||
304 | onInited(items) { | 274 | onInited(items) { |
305 | this.reportArticleShow(items); | 275 | this.reportArticleShow(items); |
306 | }, | 276 | }, |
307 | - onFollow(data, follow) { | ||
308 | - this.CHANGE_AUTHOR_FOLLOW({authorUid: data.authorUid, authorType: data.authorType, follow, type: this.type}); | ||
309 | - }, | ||
310 | onFollowTopic(follow) { | 277 | onFollowTopic(follow) { |
311 | this.CHANGE_TOPIC_FOLLOW({topicId: this.topicId, follow}); | 278 | this.CHANGE_TOPIC_FOLLOW({topicId: this.topicId, follow}); |
312 | follow && this.reportTopicFollow(); | 279 | follow && this.reportTopicFollow(); |
313 | }, | 280 | }, |
314 | - onResize(index) { | ||
315 | - this.$nextTick(() => { | ||
316 | - this.$refs.scroll.resize(index); | ||
317 | - }); | ||
318 | - }, | ||
319 | - onShowGuang(params) { | ||
320 | - this.showArticleDetailAction = true; | ||
321 | - this.$nextTick(() => { | ||
322 | - this.$refs.actionSheet.show(params); | ||
323 | - }); | ||
324 | - }, | ||
325 | setPageShareInfo({topicName, topicImageUrl, topicDesc}) { | 281 | setPageShareInfo({topicName, topicImageUrl, topicDesc}) { |
326 | if (this.share) { | 282 | if (this.share) { |
327 | document && (document.title = topicName || '话题'); | 283 | document && (document.title = topicName || '话题'); |
@@ -392,75 +348,62 @@ export default { | @@ -392,75 +348,62 @@ export default { | ||
392 | } | 348 | } |
393 | }, | 349 | }, |
394 | components: { | 350 | components: { |
395 | - ArticleItem, | ||
396 | ArticleItem2, | 351 | ArticleItem2, |
397 | - ArticleActionSheet, | ||
398 | - MoreActionSheet, | ||
399 | TopicHeader, | 352 | TopicHeader, |
400 | - TopicBanner | 353 | + TopicBanner, |
354 | + TopicTabBlock | ||
401 | } | 355 | } |
402 | }; | 356 | }; |
403 | </script> | 357 | </script> |
404 | 358 | ||
405 | <style scoped> | 359 | <style scoped> |
406 | - /deep/ .recycle-scroll-reveal-main { | ||
407 | - background-color: #f7f7f7; | 360 | +/deep/ .recycle-scroll-reveal-main { |
361 | + background-color: #f7f7f7; | ||
408 | 362 | ||
409 | - .scroll-reveal-list { | ||
410 | - padding: 5px; | ||
411 | - } | 363 | + .scroll-reveal-list { |
364 | + padding: 5px; | ||
412 | } | 365 | } |
366 | +} | ||
413 | 367 | ||
414 | - /deep/ .att-click-wrap { | ||
415 | - opacity: 0; | ||
416 | - position: absolute; | ||
417 | - left: 0; | ||
418 | - top: 0; | ||
419 | - width: 100%; | ||
420 | - height: 100%; | ||
421 | - z-index: 1; | ||
422 | - } | 368 | +/deep/ .cube-recycle-list-items { |
369 | + padding-top: 54PX; | ||
423 | 370 | ||
424 | - /deep/ .cube-recycle-list-items { | ||
425 | - padding-top: 54PX; | ||
426 | - | ||
427 | - .cube-recycle-list-item:first-child { | ||
428 | - margin-top: -54PX; | ||
429 | - } | 371 | + .cube-recycle-list-item:first-child { |
372 | + margin-top: -54PX; | ||
373 | + } | ||
374 | +} | ||
375 | + | ||
376 | +.publish-btn { | ||
377 | + width: 260px; | ||
378 | + height: 80px; | ||
379 | + border-radius: 42px; | ||
380 | + font-size: 30px; | ||
381 | + color: #fff; | ||
382 | + background: #D0021B; | ||
383 | + position: absolute; | ||
384 | + bottom: 100px; | ||
385 | + left: calc(50% - 130px); | ||
386 | + z-index: 1; | ||
387 | + display: flex; | ||
388 | + align-items: center; | ||
389 | + transition: all 600ms ease-in-out; | ||
390 | + | ||
391 | + &.scroll-opacity { | ||
392 | + opacity: 0.3; | ||
430 | } | 393 | } |
431 | 394 | ||
432 | - .publish-btn { | ||
433 | - width: 260px; | ||
434 | - height: 80px; | ||
435 | - border-radius: 42px; | ||
436 | - font-size: 30px; | ||
437 | - color: #fff; | ||
438 | - background: #D0021B; | ||
439 | - position: absolute; | ||
440 | - bottom: 100px; | ||
441 | - left: calc(50% - 130px); | ||
442 | - z-index: 1; | ||
443 | - display: flex; | ||
444 | - align-items: center; | ||
445 | - transition: all 600ms ease-in-out; | ||
446 | - | ||
447 | - &.scroll-opacity { | ||
448 | - opacity: 0.3; | ||
449 | - } | ||
450 | - | ||
451 | - .avatar-block { | ||
452 | - width: 52px; | ||
453 | - height: 52px; | ||
454 | - margin: 14px 30px 14px 14px; | ||
455 | - border-radius: 50%; | ||
456 | - overflow: hidden; | ||
457 | - } | ||
458 | - | ||
459 | - .avatar { | ||
460 | - display: block; | ||
461 | - width: 100%; | ||
462 | - height: 100%; | ||
463 | - } | 395 | + .avatar-block { |
396 | + width: 52px; | ||
397 | + height: 52px; | ||
398 | + margin: 14px 30px 14px 14px; | ||
399 | + border-radius: 50%; | ||
400 | + overflow: hidden; | ||
464 | } | 401 | } |
465 | 402 | ||
403 | + .avatar { | ||
404 | + display: block; | ||
405 | + width: 100%; | ||
406 | + height: 100%; | ||
407 | + } | ||
408 | +} | ||
466 | </style> | 409 | </style> |
@@ -302,11 +302,12 @@ export default { | @@ -302,11 +302,12 @@ export default { | ||
302 | 302 | ||
303 | return result; | 303 | return result; |
304 | }, | 304 | }, |
305 | - async fetchTopicRelatedArticles({ commit, state }, {topicId, page, lastedTime}) { | 305 | + async fetchTopicRelatedArticles({ commit, state }, {topicId, page, type}) { |
306 | commit(Types.FETCH_ARTICLE_TOPIC_REQUEST, { page }); | 306 | commit(Types.FETCH_ARTICLE_TOPIC_REQUEST, { page }); |
307 | const result = await this.$api.post('/api/grass/topicRelatedArticles', { | 307 | const result = await this.$api.post('/api/grass/topicRelatedArticles', { |
308 | topicId, | 308 | topicId, |
309 | page, | 309 | page, |
310 | + type, | ||
310 | limit: 6, | 311 | limit: 6, |
311 | lastedTime: state.articleLastedTimeByTopic || void 0 | 312 | lastedTime: state.articleLastedTimeByTopic || void 0 |
312 | }); | 313 | }); |
@@ -13,6 +13,7 @@ module.exports = { | @@ -13,6 +13,7 @@ module.exports = { | ||
13 | topicId: {type: Number, require: true}, | 13 | topicId: {type: Number, require: true}, |
14 | limit: {type: Number}, | 14 | limit: {type: Number}, |
15 | page: {type: Number}, | 15 | page: {type: Number}, |
16 | + type: {type: Number}, | ||
16 | lastedTime: {type: Number} | 17 | lastedTime: {type: Number} |
17 | } | 18 | } |
18 | }, | 19 | }, |
-
Please register or login to post a comment