效果圖:
主要就是需要把寫的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>
其中的數據在實際應用中來自后端