-
$router:跳转
-
$route:接受数据
-
函数都需要被调用,不然就失去了作用,有些函数通过点击事件触发,有些函数需要放到created中才能被触发,也有些函数在另外的函数中触发
项目组件实现效果步骤:
1.设置路由(或 连接接口)(要与后台保持一致,不能随便写)
- 路由在router中的index.js中设置
- 接口在api中的index.js中设置
2.写好对应的函数,与要用到的数据(可以先打印一下,看是否获取到了)
3.引入需要的vant组件
4.将内容渲染到页面上
图片懒加载
1.先把数据获取到,并存放到变量cates、imgs中
2.在页面上渲染出来(遍历)
3.引入懒加载vant组件
4.在图片上,将src属性改为v-lazy
路由跳转
1.在需要点击进行跳转的页面 写@click='getPhotoInfo(img.id)',并写好该函数(先打印一下看是否得到id)
getPhotoInfo(id) {
// console.log(id)
this.$router.push('/home/phontoinfo/' + id)
}
2.在Home/photos下创建PhotoInfo文件夹,文件夹下创建index.vue文件
- PhotoInfo/index.vue
<template>
<div>photoinfo</div>
</template>
<script>
export default {
data: () => ({})
}
</script>
<style lang="less" scoped>
</style>
3.配置路由
- photolist.vue(点击图片后跳转到photoinfo)
<img
v-for="img in imgs"
:key="img.id"
v-lazy="img.img_url"
alt=""
@click="goDetail('/home/photoinfo',img.id)"
/>
goDetail(id) {
// console.log(id)
this.$router.push('/home/photoinfo/' + id)
}
- router/index.js
import Photoinfo from '../views/Home/photos/PhotoInfo'
{
path: '/home/photoinfo/:id',
component: Photoinfo
}
因为goDetail()函数会被多次使用(news:newslist跳转到newsinfo,photolist跳转到photoinfo......)所以可以把goDetail()函数放到全局中(main.js)
1.创建文件夹mixins,文件夹下有index.js文件
2./mixins/index.js
import Vue from 'vue'
Vue.mixin({
methods: {
goDetail(url, id) {
this.$router.push(url + '/' + id)
}
}
})
3.在main.js引入mixins
import './mixins'
4.在photolist.vue的图片上设置点击事件
<img
v-for="img in imgs"
:key="img.id"
v-lazy="img.img_url"
alt=""
@click="goDetail('/home/photoinfo',img.id)"
/>
图片预览
- vue-preview 图片预览第三方组件 github.com/LS1231/vue-… npmjs.com/package/vue-preview
1.在vant里找到图片预览组件
import { ImagePreview } from 'vant'
2.点击图片进行预览(设置点击事件)
<img
v-for="(item, index) in thumImages"
:key="item.id"
:src="item.src"
alt=""
@click="showThum(index)"
/>
3.把数据进行处理,为一个新数组
// 显示预览效果
showThum(startPosition) {
const images = []
// 把数据进行处理成一个新数组
this.thumImages.forEach(item => {
if (item.src) images.push(item.src)
})
ImagePreview({
images,
// 默认显示某一张
startPosition
})
}
页面跳转(路由)
1.创建文件夹goodsinfo/index.vue
2.配置路由
import Goodsinfo from '../views/Home/goods/Goodsinfo'
{
path: '/home/goodsinfo/:id',
component: Goodsinfo,
props: true
}
3.在goodslist/index.vue设置点击事件以及函数
<div
class="goods-list-item"
v-for="good in goods"
:key="good.id"
@click="goGoodsInfo(good.id)"
>
goGoodsInfo(id) {
this.$router.push('/home/goodsinfo/' + id)//这里的地址要与路由中配置的一样
}
加载更多
1.写一个按钮放在goods-list div里,并设置点击事件
<van-button type="warning" block @click="getMore">{{
moreText
}}</van-button>
2.实现函数
getMore() {
this.getGoods()
}
- 但是只是这样的话会一直加载,加重服务器的负载,所以需要优化(节流)
- 1.定义一个bool型数据
data: () => ({ pageNo: 0, pageSize: 3, goods: [], isHasMore: false//用于节流 })- 2.在获取数据函数内进行节流
async getGoods() { ++this.pageNo const res = await this.$http.getGoods({ pageNo: this.pageNo, pageSize: this.pageSize }) this.goods = this.goods.concat(res.data.message) // 节流 this.isHasMore = this.pageNo * this.pageSize > res.data.count }- 3.处理按钮上显示的内容,但还未加载完时,显示“加载更多”,当加载完后,显示“被掏空了”
computed: { moreText() { return this.isHasMore ? '被掏空了' : '加载更多' } }
使用list组件实现加载
1.在vant中找到list组件,引入到vant.js中
import { Button, NavBar, Tabbar, TabbarItem, Swipe, SwipeItem, Toast, Grid, GridItem, Card, Panel, Field, Icon, Rate, Tabs, Tab, Lazyload, List } from 'vant'
Vue.use(List)
2.在goodslist页面使用该组件
<template>
<div>
// van-list组件
<van-list
class="goods-list"
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
offset="0"
>
<div
class="goods-list-item"
v-for="good in goods"
:key="good.id"
@click="goGoodsInfo(good.id)"
>
<div class="img-box">
<img v-lazy="good.img_url" alt="" />
</div>
<h2 class="title">{{ good.title }}</h2>
<div class="info">
<div class="price">
<span class="new">现价:¥{{ good.sell_price }}</span>
<span class="old">原价:¥{{ good.market_price }}</span>
</div>
<div class="sell">
<span>热卖中</span>
<span>剩余{{ good.stock_quantity }}件</span>
</div>
</div>
</div>
<!-- <van-button type="warning" block @click="getMore">{{
moreText
}}</van-button> -->
</van-list>
</div>
</template>
3.组件的基础用法
- 基础用法 List 组件通过 loading 和 finished 两个变量控制加载状态,当组件滚动到底部时,会触发 load 事件并将 loading 设置成 true。此时可以发起异步操作并更新数据,数据更新完毕后,将 loading 设置成 false 即可。若数据已全部加载完毕,则直接将 finished 设置成 true 即可。
<script>
export default {
data: () => ({
pageNo: 0,
pageSize: 3,
goods: [],
// isHasMore: false
loading: false,
finished: false,
total: 0
}),
methods: {
async onLoad() {
// 异步更新数据
// setTimeout 仅做示例,真实场景中一般为ajax请求
setTimeout(async () => {
await this.getGoods()
// 加载状态结果
this.loading = false
console.log(this.total)
// 数据全部加载完成
if (this.goods.length >= this.total) {
this.finished = true
}
}, 500)
},
async getGoods() {
++this.pageNo
const res = await this.$http.getGoods({ pageNo: this.pageNo, pageSize: this.pageSize })
this.goods = this.goods.concat(res.data.message)
// this.isHasMore = this.pageNo * this.pageSize > res.data.count
this.total = res.data.count
},
// 加载更多
// getMore() {
// this.getGoods()
// },
// 跳转到商品详情页
goGoodsInfo(id) {
this.$router.push('/home/goodsinfo/' + id)
}
},
created() {
// this.getGoods()
}
// computed: {
// moreText() {
// return this.isHasMore ? '被掏空了' : '加载更多'
// }
// }
}
</script>
Home首页与goodsinfo公用轮播组件
1.在components文件夹下创建文件Swipe.vue
<template>
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="item in lunbolist" :key="item.id">
<img :src="item.src || item.img" alt="" />
</van-swipe-item>
</van-swipe>
</template>
<script>
export default {
props: ['lunbolist']// 从别的页面接受参数
}
</script>
<style lang="less" scoped>
.goods-info {
width: 96%;
margin: 0 auto;
border: 1px solid #ccc;
.my-swipe {
padding: 10px;
text-align: center;
img {
width: 50%;
height: 100%;
}
}
}
</style>
2.Home/index.vue 或 goodsinfo/index.vue
1.引入Swipe.vue组件
import Swipe from '../../../../components/Swipe.vue'
2.注册组件
components: {
Swipe
}
3.渲染
<template>
<div class="goods-info">
<!-- <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="item in lunbolist" :key="item.id">
<img :src="item.src" alt="" />
</van-swipe-item>
</van-swipe> -->
<Swipe class="my-panel" :lunbolist="lunbolist"></Swipe>
</div>
</template>