想利用暑假时间好好学习一下vue,会记录每一天的学习内容。 今天是学习vue的第17 天!
起起伏伏乃人生常态,继续加油~
1. 轮播图展示
(不写具体代码,直接引入使用) 在Home.vue 中代码:
import {Swiper} from '../../components/common/swiper/Swiper.vue';
import {SwiperItem} from '../../components/common/swiper/SwiperItem.vue'
components: {
NavBar,
Swiper,
SwiperItem
},
<swiper>
<swiper-item v-for="item in banners" :key="item.title">
<a :href="item.link">
<img :src="item.image" alt="">
</a>
</swiper-item>
</swiper>
目前效果:
还可以再抽一层,如果不想把轮播图的内部逻辑也放在Home.vue 抽到HomeSwiper.vue 中: 这里要注意在HomeSwiper.vue 中,我们是没有banners 的数据的,就要借助父子通信了
props: {
banners: Array
},
在Home.vue 中引入、注册、使用:
import HomeSwiper from './childComponents/HomeSwiper.vue'
components: {
NavBar,
HomeSwiper
},
<home-swiper :banners="banners"></home-swiper>
2. 推荐信息的展示
新建一个组件文件: 要拿到的数据在Home.vue 中,依然需要父子通信
props: {
recommends: Array
}
在Home.vue 中引入、注册、使用:
import HomeRecommendView from './childComponents/HomeRecommendView.vue'
components: {
NavBar,
HomeSwiper,
HomeRecommendView
},
<home-recommend-view :recommends="recommends"></home-recommend-view>
HomeRecommendView.vue 中代码: 比较简单,没啥要说的
<template>
<div id="recommend-view">
<div v-for="item in recommends" :key="item.sort">
<a :href="item.link">
<img :src="item.image" alt="">
<div>{{ item.title }}</div>
</a>
</div>
</div>
</template>
样式比较简单也就不放代码了
3. 封装一张图片
是的,就是一张图片,但是因为依然是一个模块,所以还是把它封装了 步骤都跟上面的封装一样,这里跳过
4. tab切换栏的封装
tab切换栏在别的界面也可能会用到,所以封装在components/content 中比较合适 活跃状态的tab栏有颜色和文字底部一条线 主要逻辑是给选项卡动态绑定active 类 默认是第一个选项卡有颜色,所以设置一个currentIndex = 第一个选项卡的index = 0 点击选项卡的时候能拿到index ,这时候就应该让currentIndex = index ,使得{active: ture} ,让该点击的选项卡绑定上active 类
<template>
<div class="tab-control">
<div @click="clickTab(index)" v-for="(item,index) in titles" :key="index">
<span :class="{active: currentIndex == index}">{{ item }}</span>
</div>
</div>
</template>
<script>
export default {
props: {
titles: Array,
},
data() {
return {
currentIndex: 0
}
},
methods: {
clickTab(index) {
this.currentIndex = index
}
}
};
</script>
.active {
color: #ff8198;
position: relative;
}
5. 首页商品数据的请求和保存
export function getHomeGoodsData(type,page) {
return request({
url: '/home/data',
params: {
type,
page
}
})
}
data() {
return {
goods: {
'pop': {page: 1, list: []},
'new': {page: 1, list: []},
'sell': {page: 1, list: []},
}
}
},
methods: {
getHomeGoodsData(type) {
const page = this.goods[type].page;
getHomeGoodsData(type, page).then(res => {
console.log(res);
this.goods[type].list.push(...res.data.data.list);
this.goods[type].page += 1;
})
}
},
created() {
this.getHomeGoodsData('pop');
this.getHomeGoodsData('sell');
this.getHomeGoodsData('new');
}
6. 首页商品数据的展示
Goods.vue 中代码: 先从Home.vue 中拿到一整组goods 数据,再传给子组件GoodsItem.vue
<template>
<div class="goods">
<goods-item v-for="item in goods" :key="item.title" :goods-item="item"></goods-item>
</div>
</template>
<script>
import GoodsItem from './GoodsItem.vue'
export default {
props: {
goods: Array
},
components: {
GoodsItem
}
}
</script>
GoodsItem.vue 中代码:
<template>
<div class="goods-item">
<img :src="goodsItem.show.img" alt="">
<div>
<p class="goods-item-title">{{goodsItem.title}}</p>
<span class="goods-item-price">{{goodsItem.price}}</span>
<span class="goods-item-star">🌟{{goodsItem.cfav}}</span>
</div>
</div>
</template>
<script>
export default {
props: {
goodsItem: Object
}
}
</script>
Home.vue 中代码:
<goods :goods="goods['pop'].list"></goods>
(这里我们的tab栏还不能切换对应商品,暂时传了一个固定的'pop' ) (样式不放了,不是重点)
7. 点击tab栏切换商品数据
其实就是下面这行代码,不能传一个固定的'pop' 实际上是用户点到了哪个选项卡再将对应页面的数据传给子组件Goods ->GoodsItem ,再显示对应的商品
<goods :goods="goods['pop'].list"></goods>
我们的TabControl 组件中是监听了click 事件的,这时候应该在子组件TabControl 中发射自定义事件,也就是将用户点击了哪个选项卡相关的信息发到父组件Home 中
TabControl.vue 中代码:
methods: {
clickTab(index) {
this.currentIndex = index;
this.$emit('tab-item-click',index);
}
}
Home.vue 中代码:
<tab-control class="home-tab" :titles="titles" @tab-item-click="clickTab"></tab-control>
上面的tab-item-click 事件对应了clickTab 方法,我们就要定义一个clickTab 方法来处理这个事件 我们再思考一下index 怎么与goods 对象中的三个属性'pop' 、'new' 、'sell' 对应起来:
data() {
return {
goods: {
'pop': {page: 1, list: []},
'new': {page: 1, list: []},
'sell': {page: 1, list: []},
},
goodsType: ['pop','new','sell'],
currentType: 'pop'
}
}
clickTab(index) {
this.currentType = this.goodsType[index]
},
这个时候就可以把该行固定写了'pop' 改成动态的了:
<goods :goods="goods[currentType].list"></goods>
(样式凑合看,马马虎虎随便写了一下😢)
8. 回到顶部组件封装使用
先新建一个BackTop 组件,然后在Home 组件中应用 (这里跳过,不放代码了,上面重复过很多遍)
然后要实现一个点击BackTop 组件回到顶部的功能, ??一下:组件不能直接监听点击事件
<back-top @click="backTop"></back-top>
如果想要监听组件的原生事件,要加修饰符.native
<back-top @click.native="backTop"></back-top>
backTop() {
let timer = null;
timer = setInterval(() => {
document.documentElement.scrollTop > 0
? (document.documentElement.scrollTop =
document.documentElement.scrollTop - 10)
: clearInterval(timer);
}, 5);
我们还需要实现:当界面滚动到一定位置,这个回到顶部按钮再出现,否则不出现
不出现可以在样式中设置display:none ,这里我就用了动态绑定类的方式:
<back-top :class="{hide: isHide}" @click.native="backTop"></back-top>
data() {
return {
isHide: true,
}
},
mounted() {
window.onscroll = () => {
document.documentElement.scrollTop > 800
? (this.isHide = false)
: (this.isHide = true);
}
9. 上拉加载更多
当滚动条到达界面底部时会自动加载更多商品数据:
滚动条到达底部会调用getHomeGoodsData() 方法,会发送一次新的网络请求,同时将新请求到的结果push 进goods 的list 数组,同时page +1 (这里判断滚动条是否到达底部我没写兼容)
methods:{
listenScroll() {
window.onscroll = () => {
document.documentElement.scrollTop > 800
? (this.isHide = false)
: (this.isHide = true);
if (
document.documentElement.scrollTop +
document.documentElement.clientHeight >=
document.documentElement.scrollHeight
) {
this.getHomeGoodsData(this.currentType);
}
};
},
}
mounted() {
this.listenScroll();
}
getHomeGoodsData(type) {
const page = this.goods[type].page;
getHomeGoodsData(type, page).then(res => {
console.log(res);
this.goods[type].list.push(...res.data.data.list);
this.goods[type].page += 1;
})
}
|