使用click绑定事件,当每日推荐和主题日报被点击时,绑定类名on,在此文件中是出现蓝色标记当前开大的菜单.
:class="{on:type==='recommend}"当前dom的type为recommend时,绑定类名on,主题日报同理。
handleToRecommend () {
this.type = 'recommend';
this.recommendList = [];
this.dailyTime = $.getTodayTime();
this.getRecommendList();
},
handleToTheme (id) {
this.type = 'daily';
this.themeId = id;
this.list = [];
$.ajax.get('theme/' + id).then(res => {
this.list = res.stories
.filter(item => item.type !== 1);
})
}通过点击事件,触发函数修改type值,从而给子菜单添加on类名;
在data中,type默认为recommend,故应用开启时,每日推荐出现标记.。
对应CSS{
.daily-menu ul li a:hover, .daily-menu ul li a.on{
color: #3399ff;
}
};
<div class="daily-menu-item"
:class="{ on: type === 'daily' }"
@click="showThemes = !showThemes">主题日报</div>
<ul v-show="showThemes">
<li v-for="item in themes" :key="item.id">
<a
:class="{ on: item.id === themeId && type === 'daily' }"
@click="handleToTheme(item.id)">{{ item.name }}</a>
</li>
</ul>
主题日报菜单通过click修改showThemes布尔值,达到隐藏、显示themes列表;v-show="showThemes"当showThemes为真显示,showThemes为假时隐藏;
v-for="item in themes" :key="item.id";key 的特殊属性主要用在 Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。
key 的作用渲染时候的参照关键字,或者渲染的顺序; //个人意见保留
通过formatDay格式化日期,之后通过日期分块,再根据对应日期渲染。
注意:
1,给vue组件绑定事件时候,必须加上native ,不然不会生效(监听根元素的原生事件,使用 .native
修饰符)
2,等同于在自组件中:
子组件内部处理click事件然后向外发送click事件:$emit("click".fn)
即在template 或在组件中引用组件,组件会拦截click,需要加上native原生触发。
<template v-if="type === 'daily'">
<Item
v-for="item in list"
:data="item"
:key="item.id"
@click.native="handleClick(item.id)"></Item>
</template>
<script>
handleClick (id) {
this.articleId = id;
}
</script>
此处组件对应主题日报;
踩坑。
提一下v-if和v-show的区别: v-if 当值为 true时,显示div ,当值为false时,改元素消失,代码也会消失,相当于将代码删除了,当在为true时,页面会重新渲染div;
而v-show 控制的隐藏出现,只是将css属性设为了display:none 或block;
v-if修改会重新渲染,v-show不会。
app.vue:
<template>
<div class="daily">
<div class="daily-menu">
<div class="daily-menu-item"
@click="handleToRecommend"
:class="{ on: type === 'recommend' }">每日推荐</div>
<div class="daily-menu-item"
:class="{ on: type === 'daily' }"
@click="showThemes = !showThemes">主题日报</div>
<ul v-show="showThemes">
<li v-for="item in themes" :key="item.id">
<a
:class="{ on: item.id === themeId && type === 'daily' }"
@click="handleToTheme(item.id)">{{ item.name }}</a>
</li>
</ul>
</div>
<div class="daily-list" ref="list">
<template v-if="type === 'recommend'">
<div v-for="list in recommendList" :key="formatDay(list.date)">
<div class="daily-date">{{ formatDay(list.date) }}</div>
<Item
v-for="item in list.stories"
:data="item"
:key="item.id"
@click.native="handleClick(item.id)"></Item>
</div>
</template>
<template v-if="type === 'daily'">
<Item
v-for="item in list"
:data="item"
:key="item.id"
@click.native="handleClick(item.id)"></Item>
</template>
</div>
<daily-article :id="articleId"></daily-article>
</div>
</template>
<script>
import Item from './components/item.vue';
import dailyArticle from './components/daily-article.vue';
import $ from './libs/util';
export default {
components: { Item, dailyArticle },
data () {
return {
themes: [],
showThemes: false,
type: 'recommend',
recommendList: [],
dailyTime: $.getTodayTime(),
list: [],
themeId: 0,
articleId: 0,
isLoading: false
}
},
methods: {
handleToRecommend () {
this.type = 'recommend';
this.recommendList = [];
this.dailyTime = $.getTodayTime();
this.getRecommendList();
},
handleToTheme (id) {
this.type = 'daily';
this.themeId = id;
this.list = [];
$.ajax.get('theme/' + id).then(res => {
this.list = res.stories
.filter(item => item.type !== 1);
})
},
getThemes () {
$.ajax.get('themes').then(res => {
this.themes = res.others;
})
},
getRecommendList () {
this.isLoading = true;
const prevDay = $.prevDay(this.dailyTime + 86400000);
$.ajax.get('news/before/' + prevDay).then(res => {
this.recommendList.push(res);
this.isLoading = false;
})
},
formatDay (date) {
let month = date.substr(4, 2);
let day = date.substr(6, 2);
if (month.substr(0, 1) === '0') month = month.substr(1, 1);
if (day.substr(0, 1) === '0') day = day.substr(1, 1);
return `${month} 月 ${day} 日`;
},
handleClick (id) {
this.articleId = id;
}
},
mounted () {
this.getRecommendList();
this.getThemes();
const $list = this.$refs.list;
$list.addEventListener('scroll', () => {
if (this.type === 'daily' || this.isLoading) return;
if
(
$list.scrollTop
+ document.body.clientHeight
>= $list.scrollHeight
)
{
this.dailyTime -= 86400000;
this.getRecommendList();
}
});
}
}
</script>