效果图:
主要就是需要把写的vue前端页面中的每个数据抽离出来,方便后续的引用与修改
原来的vue代码:
<template> <view> <view class="index-list"> <view class="index-list1"> <view class=""> <image src="../../static/demo/userpic/12.jpg" mode="widthFix" lazy-load></image> 昵称 </view> <view> <view class="icon iconfont icon-zengjia"></view>关注 </view> </view> <view class="index-list2">我是标题</view> <view class="index-list3"> <!-- 图片 --> <image src="../../static/demo/datapic/11.jpg" mode="widthFix" lazy-load></image> <!-- 视频 --> <view class="icon iconfont icon-bofang index-list-play"></view> <view class="index-list-playInfo"> 20W播放 2:47 </view> </view> <view class="index-list4"> <!-- 左边 --> <view> <view> <view class="icon iconfont icon-icon_xiaolian-mian"></view>10 </view> <view> <view class="icon iconfont icon-kulian"></view>10 </view> </view> <!-- 右边 --> <view> <view> <view class="icon iconfont icon-pinglun1"></view>10 </view> <view> <view class="icon iconfont icon-zhuanfa"></view>10 </view> </view> </view> </view> </view> </template> <script> export default { data() { return { title: 'Hello' } }, onLoad() { }, methods: { } } </script> <!-- uniapp在编译的时候会把子组件和父组件合并成同一个文件,一个组件的CSS可能会污染另一个组件的CSS,所以这时候需要使用scoped限制样式的作用域 --> <style scoped> /* 封装常用样式 */ .index-list{ padding: 20rpx; border-bottom: 1rpx solid #EEEEEE; } .index-list1{ display: flex; justify-content: space-between; align-items: center; } .index-list1>view:first-child{ display: flex; align-items: center; color: #989898; } .index-list1>view:first-child image{ width: 90rpx; height: 90rpx; border-radius: 100%; } .index-list1>view:last-child{ display: flex; align-items: center; background-color: #F4F4F4; border-radius: 5rpx; padding: 0 10rpx; } .index-list2{ padding-top: 15rpx; font-size: 35rpx; } .index-list3{ padding-top: 15rpx; position: relative; display: flex; justify-content: center; align-items: center; } .index-list3>image{ padding-top: 15rpx; width: 100%; border-radius: 10rpx; } .index-list-play{ position: absolute; font-size: 140rpx; color: #FFFFFF; } .index-list-playInfo{ position: absolute; /* 这里的值是透明度 (可以在下载的icon的网页图标中调)*/ background-color: rgb(51 51 51 / 48%); right: 8rpx; bottom: 8rpx; border-radius: 20rpx; color: #FFFFFF; padding: 0 15rpx; font-size: 22rpx; } .index-list4{ padding: 15px 0; display: flex; justify-content: space-between; align-items: center; /* color: #989898; */ } .index-list4 view{ color: #989898; } .index-list4>view>view{ display: flex; align-items: center; } .index-list4>view>view>view{ margin-right: 15rpx; } .index-list4>view:first-child{ display: flex; align-items: center; } .index-list4>view>view:first-child{ margin-right: 15rpx; } .index-list4>view:last-child{ display: flex; align-items: center; } </style>
封装后的vue组件(子组件):
<template> <view class="index-list animated fadeInLeft fast"> <view class="index-list1"> <view> <image :src="item.userpic" mode="widthFix" lazy-load></image> {{item.username}} </view> <!-- 只有 isguanzhu为true该view才会显示,这里不能使用v-if--> <view v-show="!item.isguanzhu" @tap="guanzhu"> <view class="icon iconfont icon-zengjia" ></view>关注 </view> </view> <view class="index-list2" @tap="openDetail()">{{item.title}}</view> <view class="index-list3" @tap="openDetail()"> <!-- 图片 --> <image :src="item.titlepic" mode="widthFix" lazy-load></image> <!-- 判断是否为视频,是则显示 --> <template v-if="item.type=='video'"> <!-- 视频 --> <view class="icon iconfont icon-bofang index-list-play"></view> <view class="index-list-playInfo"> {{item.playnum}}播放 {{item.long}} </view> </template> </view> <view class="index-list4"> <!-- 左边(顶踩) --> <view> <view :class="{'active': (item.infonum.index==1)}" @tap="caozuo('ding')"> <view class="icon iconfont icon-icon_xiaolian-mian"></view> {{item.infonum.dingnum}} </view> <view :class="{'active':(item.infonum.index==2)}" @tap="caozuo('cai')"> <view class="icon iconfont icon-kulian"></view> {{item.infonum.cainum}} </view> </view> <!-- 右边(评论转发)--> <view> <view> <view class="icon iconfont icon-pinglun1"></view> {{item.commentnum}} </view> <view> <view class="icon iconfont icon-zhuanfa"></view> {{item.sharenum}} </view> </view> </view> </view> </template> <script> export default { // 父组件传来的值 props:{ item:Object, index:Number }, methods:{ // 关注点击事件 guanzhu(){ this.item.isguanzhu=true; //这里感觉有问题,这样不能取消关注 // 消息提示框 uni.showToast({ title: '关注成功', }); }, // 顶踩 caozuo(type){ switch (type){ case "ding": if(this.item.infonum.index==1){ return; }else if(this.item.infonum.index==2){ this.item.infonum.dingnum++; this.item.infonum.cainum--; }else{ this.item.infonum.dingnum++; } this.item.infonum.index=1; break; case "cai": if(this.item.infonum.index==2){ return; }else if(this.item.infonum.index==1){ this.item.infonum.dingnum--; this.item.infonum.cainum++; }else{ this.item.infonum.cainum++; } this.item.infonum.index=2 break; } }, // 进入详情页 openDetail(){ console.log("进入详情页!"); } } } </script> <style scoped> /* 封装常用样式 */ .index-list{ padding: 20rpx; border-bottom: 1rpx solid #EEEEEE; } .index-list1{ display: flex; justify-content: space-between; align-items: center; } .index-list1>view:first-child{ display: flex; align-items: center; color: #989898; } .index-list1>view:first-child image{ width: 90rpx; height: 90rpx; border-radius: 100%; } .index-list1>view:last-child{ display: flex; align-items: center; background-color: #F4F4F4; border-radius: 5rpx; padding: 0 10rpx; } .index-list2{ padding-top: 15rpx; font-size: 35rpx; } .index-list3{ padding-top: 15rpx; position: relative; display: flex; justify-content: center; align-items: center; } .index-list3>image{ padding-top: 15rpx; width: 100%; border-radius: 10rpx; } .index-list-play{ position: absolute; font-size: 140rpx; color: #FFFFFF; } .index-list-playInfo{ position: absolute; /* 这里的值是透明度 (可以在下载的icon的网页图标中调)*/ background-color: rgb(51 51 51 / 48%); right: 8rpx; bottom: 8rpx; border-radius: 20rpx; color: #FFFFFF; padding: 0 15rpx; font-size: 22rpx; } .index-list4{ padding: 15px 0; display: flex; justify-content: space-between; align-items: center; /* color: #989898; */ } .index-list4 view{ color: #989898; } .index-list4>view>view{ display: flex; align-items: center; } .index-list4>view>view>view{ margin-right: 15rpx; } .index-list4>view:first-child{ display: flex; align-items: center; } .index-list4>view>view:first-child{ margin-right: 15rpx; } .index-list4>view:last-child{ display: flex; align-items: center; } .index-list4 .active,.index-list4 .active>view{ color:red; } </style>
其中样式中的公共部分可以进行封装,以简化CSS代码
在父组件中引入封装的vue子组件:
<template> <view> <block v-for="(item,index) in list" :key="index"> <index-list :item="item" :index="index"></index-list> </block> </view> </template> <script> import indexList from "../../components/index/index-list.vue"; export default { components:{ indexList }, data() { return { list:[ { userpic:"../../static/demo/userpic/12.jpg", username:"昵称", isguanzhu:false, title:"我是标题", type:"img", // img:图文,video:视频 titlepic:"../../static/demo/datapic/11.jpg", infonum:{ index:0,//0:没有操作,1:顶,2:踩; dingnum:11, cainum:11, }, commentnum:10, sharenum:10, }, { userpic:"../../static/demo/userpic/12.jpg", username:"昵称", isguanzhu:true, title:"我是标题", type:"video", // img:图文,video:视频 titlepic:"../../static/demo/datapic/11.jpg", playnum:"20w", long:"2:47", infonum:{ index:1,//0:没有操作,1:顶,2:踩; dingnum:11, cainum:11, }, commentnum:10, sharenum:10, } ] } }, onLoad() { }, methods: { }, } </script> <style> </style>
其中的数据在实际应用中来自后端