提交 e55462cb authored 作者: 王鹏飞's avatar 王鹏飞

增加知识点模块

上级 afb9c3fb
<template>
<div class="course-tag-message">
<div class="course-tag-message-hd">
<div class="course-tag-message__title">{{data.name}}</div>
</div>
<div class="course-tag-message-bd">
<template v-if="data.children && data.children.length">
<ul class="message-tag-list">
<template v-for="item in data.children">
<li
class="course-tag-item"
:key="item.id"
@click="$emit('search', item)"
>{{item.name}}</li>
</template>
</ul>
</template>
</div>
<div class="course-tag-message-ft">
<div class="more">
更多
<van-icon name="arrow-down"></van-icon>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CourseTagMessage',
props: {
data: { type: Object }
}
}
</script>
<style lang="scss" scoped>
.course-tag-message {
padding: 10px;
background-color: #fff;
border-radius: 6px;
}
.course-tag-message-hd {
padding: 10px 0;
font-size: 15px;
color: #222;
}
.course-tag-item {
display: inline-block;
height: 24px;
margin: 0 10px 10px 0;
padding: 0 15px;
font-size: 13px;
color: #fff;
line-height: 24px;
background: #67a8ff;
border-radius: 12px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
cursor: pointer;
}
.course-tag-message-ft {
padding-top: 10px;
border-top: 1px solid #eee;
}
.more {
font-size: 13px;
color: #222;
text-align: center;
cursor: pointer;
}
</style>
<template>
<div class="message-card" :class="classes">
<div class="message-card-content">
<slot :data="data.payload">
<div class="message-card-text" v-if="data.type === 0">{{data.payload.text}}</div>
<course-tag-message :data="data.payload" v-on="$listeners" v-if="data.type === 1"></course-tag-message>
<search-tag-message :data="data.payload" v-on="$listeners" v-if="data.type === 2"></search-tag-message>
<tag-message :data="data.payload" v-on="$listeners" v-if="data.type === 3"></tag-message>
</slot>
</div>
</div>
</template>
<script>
import CourseTagMessage from './courseTagMessage.vue'
import SearchTagMessage from './searchTagMessage.vue'
import TagMessage from './tagMessage.vue'
export default {
name: 'MessageCard',
props: {
data: { type: Object }
},
components: { CourseTagMessage, SearchTagMessage, TagMessage },
computed: {
isMyPublish() {
return this.data.from === 'user'
},
classes() {
return {
'is-my': this.isMyPublish,
'is-system': !this.isMyPublish
}
}
}
}
</script>
<style lang="scss" scoped>
.message-card {
clear: both;
margin: 20px;
}
.message-card-text {
display: inline-block;
padding: 10px;
background-color: #fff;
border-radius: 6px;
}
.is-system {
.message-card-content {
text-align: left;
}
}
.is-my {
.message-card-content {
text-align: right;
}
.message-card-text {
color: #fff;
background-color: #67a8ff;
}
}
</style>
<template>
<div class="search-tag-message">
<p class="tips">交小通猜你想查:</p>
<ul class="search-tag-list">
<template v-for="(item,index) in data">
<li class="search-tag-item" :key="item.id" @click="$emit('change', item)">
<span class="num">{{index+1}}:</span>
<span class="text">{{item.title}}</span>
</li>
</template>
</ul>
</div>
</template>
<script>
export default {
name: 'SearchTagMessage',
props: {
data: { type: Array }
}
}
</script>
<style lang="scss" scoped>
.search-tag-message {
padding: 10px;
background-color: #fff;
border-radius: 6px;
}
.search-tag-item {
margin: 10px 0;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
.num {
display: inline-block;
min-width: 24px;
}
.text {
border-bottom: 1px solid #2b7ce9;
cursor: pointer;
}
}
</style>
<template>
<div class="tag-message" v-html="html"></div>
</template>
<script>
export default {
name: 'TagMessage',
props: {
data: { type: Object }
},
computed: {
html() {
return this.data.contents.replace(/\n/g, '<br/>')
}
}
}
</script>
<style lang="scss" scoped>
.tag-message {
padding: 10px;
background-color: #fff;
border-radius: 6px;
font-size: 13px;
line-height: 30px;
}
</style>
<template>
<div class="messages">
<template v-for="item in messageList">
<message-card :data="item" :key="item.id" @search="onSearchTag" @change="onChangeTag"></message-card>
</template>
</div>
</template>
<script>
import MessageCard from './messageCard.vue'
import * as api from '@/api/course.js'
export default {
props: { courseId: { type: String, required: true } },
components: { MessageCard },
data() {
return {
messageList: [] // {id:'', type: 1, payload: {}}
}
},
methods: {
// 获取知识点列表
getCourseTagList() {
api.getCourseTagList(this.courseId).then(response => {
this.messageList = response.chapters.map((item, index) => {
return {
id: this.genId(index),
type: 1,
from: 'system',
payload: item
}
})
})
},
// 点击标签
onSearchTag(data) {
this.messageList.push({
id: this.genId(),
type: 0,
from: 'user',
payload: { text: data.name }
})
this.searchTag(data.name)
},
searchTag(keywords) {
api.getSearchTagList({ keywords }).then(response => {
this.messageList.push({
id: this.genId(),
type: 2,
from: 'system',
payload: response
})
})
},
onChangeTag(data) {
this.messageList.push({
id: this.genId(),
type: 0,
from: 'user',
payload: { text: data.title }
})
this.getCourseTag(data.id)
},
// 获取知识点详情
getCourseTag(tagId) {
api.getCourseTag(tagId).then(response => {
this.messageList.push({
id: this.genId(),
type: 3,
from: 'system',
payload: response
})
})
},
// 生成消息ID
genId(index) {
index = index || this.messageList.length
return `message_${index}`
}
},
beforeMount() {
this.getCourseTagList()
}
}
</script>
<style lang="scss" scoped>
.messages {
background: #eee;
overflow: hidden;
}
</style>
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
class="main-tabs" class="main-tabs"
v-model="tabActive" v-model="tabActive"
color="#2b7ce9" color="#2b7ce9"
:sticky="true"
:line-height="2" :line-height="2"
@click="onTabClick" @click="onTabClick"
> >
...@@ -12,7 +13,7 @@ ...@@ -12,7 +13,7 @@
<course-chapter :courseId="courseId" :data="detail.chapters"></course-chapter> <course-chapter :courseId="courseId" :data="detail.chapters"></course-chapter>
</van-tab> </van-tab>
<van-tab title="知识点速学" name="1"> <van-tab title="知识点速学" name="1">
<course-tag :courseId="courseId"></course-tag> <course-tag :courseId="courseId" style="margin-left:-0.4rem;margin-right:-0.4rem;"></course-tag>
</van-tab> </van-tab>
</van-tabs> </van-tabs>
</div> </div>
......
<template> <template>
<div class="course-tag-message"> <div class="course-tag-message" :class="classes">
<div class="course-tag-message-hd"> <div class="course-tag-message-hd">
<div class="course-tag-message__title">{{data.name}}</div> <div class="course-tag-message__title">{{data.name}}</div>
</div> </div>
<div class="course-tag-message-bd"> <div class="course-tag-message-bd">
<template v-if="data.children && data.children.length"> <template v-if="data.children && data.children.length">
<ul class="message-tag-list"> <ul class="message-tag-list" ref="content">
<template v-for="item in data.children"> <template v-for="item in data.children">
<li <li class="course-tag-item" :key="item.id" @click="$emit('search', item)">{{item.name}}</li>
class="course-tag-item"
:key="item.id"
@click="$emit('search', item)"
>{{item.name}}</li>
</template> </template>
</ul> </ul>
</template> </template>
</div> </div>
<div class="course-tag-message-ft"> <div class="more" @click="toggleMore" v-if="hasMore">
<div class="more"> <template v-if="!showMore">
更多 <span>更多</span>
<van-icon name="arrow-down"></van-icon> <van-icon name="arrow-down"></van-icon>
</div> </template>
<template v-else>
<span>收起</span>
<van-icon name="arrow-up"></van-icon>
</template>
</div> </div>
</div> </div>
</template> </template>
...@@ -30,6 +30,31 @@ export default { ...@@ -30,6 +30,31 @@ export default {
name: 'CourseTagMessage', name: 'CourseTagMessage',
props: { props: {
data: { type: Object } data: { type: Object }
},
data() {
return {
showMore: false,
maxHeight: 76,
contentHeight: 0
}
},
computed: {
hasMore() {
return this.contentHeight > this.maxHeight
},
classes() {
return {
'has-more': this.hasMore && !this.showMore
}
}
},
methods: {
toggleMore() {
this.showMore = !this.showMore
}
},
mounted() {
this.contentHeight = this.$refs.content.offsetHeight
} }
} }
</script> </script>
...@@ -45,6 +70,10 @@ export default { ...@@ -45,6 +70,10 @@ export default {
font-size: 15px; font-size: 15px;
color: #222; color: #222;
} }
.has-more .course-tag-message-bd {
height: 76px;
overflow: hidden;
}
.course-tag-item { .course-tag-item {
display: inline-block; display: inline-block;
height: 24px; height: 24px;
...@@ -60,11 +89,9 @@ export default { ...@@ -60,11 +89,9 @@ export default {
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
} }
.course-tag-message-ft { .more {
padding-top: 10px; padding-top: 10px;
border-top: 1px solid #eee; border-top: 1px solid #eee;
}
.more {
font-size: 13px; font-size: 13px;
color: #222; color: #222;
text-align: center; text-align: center;
......
<template> <template>
<div class="messages"> <div class="course-tag">
<template v-for="item in messageList"> <div class="messages" ref="messages">
<message-card :data="item" :key="item.id" @search="onSearchTag" @change="onChangeTag"></message-card> <template v-for="item in messageList">
</template> <message-card :data="item" :key="item.id" @search="onSearchTag" @change="onChangeTag"></message-card>
</template>
</div>
<div class="send">
<div class="inner">
<form action="/">
<van-search
v-model="searchValue"
left-icon
show-action
background="#f7f7f7"
placeholder="全国道路运输安全生产管理培训"
@search="onSearch"
>
<template #action>
<div @click="onSearch">搜索</div>
</template>
</van-search>
</form>
</div>
</div>
</div> </div>
</template> </template>
...@@ -14,7 +34,13 @@ export default { ...@@ -14,7 +34,13 @@ export default {
components: { MessageCard }, components: { MessageCard },
data() { data() {
return { return {
messageList: [] // {id:'', type: 1, payload: {}} messageList: [], // {id:'', type: 1, payload: {}}
searchValue: ''
}
},
watch: {
messageList(list) {
this.scrollBottom()
} }
}, },
methods: { methods: {
...@@ -31,6 +57,20 @@ export default { ...@@ -31,6 +57,20 @@ export default {
}) })
}) })
}, },
// 输入搜索
onSearch() {
if (!this.searchValue.trim()) {
return
}
this.messageList.push({
id: this.genId(),
type: 0,
from: 'user',
payload: { text: this.searchValue }
})
this.searchTag(this.searchValue)
this.searchValue = ''
},
// 点击标签 // 点击标签
onSearchTag(data) { onSearchTag(data) {
this.messageList.push({ this.messageList.push({
...@@ -75,6 +115,12 @@ export default { ...@@ -75,6 +115,12 @@ export default {
genId(index) { genId(index) {
index = index || this.messageList.length index = index || this.messageList.length
return `message_${index}` return `message_${index}`
},
// 滚动到底部
scrollBottom() {
this.$nextTick(() => {
window.scrollTo(0, document.body.scrollHeight)
})
} }
}, },
beforeMount() { beforeMount() {
...@@ -88,4 +134,20 @@ export default { ...@@ -88,4 +134,20 @@ export default {
background: #eee; background: #eee;
overflow: hidden; overflow: hidden;
} }
.send {
height: 50px;
.inner {
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 50px;
background: rgba(247, 247, 247, 1);
box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.05);
z-index: 999;
}
::v-deep .van-search__content {
background-color: #fff;
}
}
</style> </style>
<template></template>
<script>
export default {
name: 'CourseTagItem'
}
</script>
<style lang="scss" scoped>
</style>
...@@ -2,13 +2,23 @@ ...@@ -2,13 +2,23 @@
<div class="search-tag-message"> <div class="search-tag-message">
<p class="tips">交小通猜你想查:</p> <p class="tips">交小通猜你想查:</p>
<ul class="search-tag-list"> <ul class="search-tag-list">
<template v-for="(item,index) in data"> <template v-for="(item,index) in dataList">
<li class="search-tag-item" :key="item.id" @click="$emit('change', item)"> <li class="search-tag-item" :key="item.id" @click="$emit('change', item)">
<span class="num">{{index+1}}:</span> <span class="num">{{index+1}}:</span>
<span class="text">{{item.title}}</span> <span class="text">{{item.title}}</span>
</li> </li>
</template> </template>
</ul> </ul>
<div class="more" @click="toggleMore" v-if="hasMore">
<template v-if="!showMore">
<span>更多</span>
<van-icon name="arrow-down"></van-icon>
</template>
<template v-else>
<span>收起</span>
<van-icon name="arrow-up"></van-icon>
</template>
</div>
</div> </div>
</template> </template>
...@@ -16,7 +26,31 @@ ...@@ -16,7 +26,31 @@
export default { export default {
name: 'SearchTagMessage', name: 'SearchTagMessage',
props: { props: {
data: { type: Array } data: {
type: Array,
default() {
return []
}
}
},
data() {
return { showMore: false, maxCount: 7 }
},
computed: {
hasMore() {
return this.data.length > 5
},
dataList() {
if (this.hasMore && !this.showMore) {
return this.data.filter((item, index) => index < this.maxCount)
}
return this.data
}
},
methods: {
toggleMore() {
this.showMore = !this.showMore
}
} }
} }
</script> </script>
...@@ -41,4 +75,12 @@ export default { ...@@ -41,4 +75,12 @@ export default {
cursor: pointer; cursor: pointer;
} }
} }
.more {
padding-top: 10px;
border-top: 1px solid #eee;
font-size: 13px;
color: #222;
text-align: center;
cursor: pointer;
}
</style> </style>
<template> <template>
<div class="tag-message" v-html="html"></div> <div class="tag-message" :class="classes">
<div class="tag-message-bd">
<div class="tag-message-content" ref="content" v-html="html"></div>
</div>
<div class="more" @click="toggleMore" v-if="hasMore">
<template v-if="!showMore">
<span>更多</span>
<van-icon name="arrow-down"></van-icon>
</template>
<template v-else>
<span>收起</span>
<van-icon name="arrow-up"></van-icon>
</template>
</div>
</div>
</template> </template>
<script> <script>
...@@ -8,10 +22,33 @@ export default { ...@@ -8,10 +22,33 @@ export default {
props: { props: {
data: { type: Object } data: { type: Object }
}, },
data() {
return {
showMore: false,
maxHeight: 90,
contentHeight: 0
}
},
computed: { computed: {
hasMore() {
return this.contentHeight > this.maxHeight
},
classes() {
return {
'has-more': this.hasMore && !this.showMore
}
},
html() { html() {
return this.data.contents.replace(/\n/g, '<br/>') return this.data.contents.replace(/\n/g, '<br/>')
} }
},
methods: {
toggleMore() {
this.showMore = !this.showMore
}
},
mounted() {
this.contentHeight = this.$refs.content.offsetHeight
} }
} }
</script> </script>
...@@ -21,7 +58,21 @@ export default { ...@@ -21,7 +58,21 @@ export default {
padding: 10px; padding: 10px;
background-color: #fff; background-color: #fff;
border-radius: 6px; border-radius: 6px;
}
.has-more .tag-message-bd {
height: 90px;
overflow: hidden;
}
.tag-message-content {
font-size: 13px; font-size: 13px;
line-height: 30px; line-height: 30px;
} }
.more {
padding-top: 10px;
border-top: 1px solid #eee;
font-size: 13px;
color: #222;
text-align: center;
cursor: pointer;
}
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论