網站首頁 編程語言 正文
目錄
首先放一下效果圖:
I.場景的引入及難點分析
這個效果的場景有很多的實際意義,比如說制作一個實時的點贊、收藏或關注某個人、商品等等功能的時候,需要一個實時的前端反饋效果。
這個效果看似非常簡單,但是有兩個難點:
?第一個點在于實現:事先沒有定義的、需要從后端實時獲取的內容選中。這是什么意思呢?比如說上面gif圖中的這些人物的信息,每一行都是從后端發起請求獲取后渲染到前端的,而不是我們實現就定義好的內容,因此實現選中它們中的某一行,是需要一些特殊方法的。
?第二個點在于實現將已經被用戶標記的內容在下一次獲取后刷新它的狀態為已標記。這是什么意思呢?比如說上面gif圖中的這些人物對象,有一些已被該用戶添加為關心,那么當用戶下一次進入該頁面時,這些已經被添加關心的對象需要以“紅心”狀態顯現出來。這個點的難度還不算大,只需要在每一次獲取后端的內容后對標記對象進行狀態更新即可。
II.動態標記效果實現思路和步驟
首先,整體的思路是利用動態類名對不同的元素進行選擇。下面對具體的步驟進行介紹:
1??搭建該效果的基礎前端組件:
<view class="content" v-for="(item,index) in upperList" :key="index">
<view :class = "currentUpperClass">
<view :class="currentIconClass"><image :class = "currentImgClass" :src= "item.face" mode="widthFix"></image>
</view>
<view :class="currentNickClass">
<text>{{item.name}}</text>
</view>
<span :class="currentFontIconColorClass[index]">
<span @click = "addSpecialList(item.uid,index)" :class="currentFontIconClass" ></span>
</span>
</view>
</view>
簡單介紹一下上面的部分:“content”類的view組件是每一行元素的父容器,可以看到使用了v-for循環遍歷從后端獲取的數據并渲染。上面的部分除了動態類名外,其他的地方與普通的渲染沒有任何區別。
2??動態類名數組的妙用:
第二步就是該效果的實現核心:首先,動態類名這個小技巧大家一定都聽說過,用一個變量替代普通的靜態字符串類名。這里把動態類名進行了進一步的加工:使用動態類名數組。
那為什么需要用到動態類名數組?思考一個棘手的問題:如果從后端獲取了一系列的數據,并通過v-for渲染到前端,當用戶點擊了某一行的元素,我們怎么能選中這一行呢?這項看起來很easy的功能,但分析后發現其實并不容易,究其原因是因為每一行的元素都是v-for直接進行渲染的,我們如果判定用戶的點擊事件,那么得到的結果就是無論用戶點擊了哪一行元素,返回的事件都是同一個,這將會造成一個現象:用戶點擊了心形圖標進行“標記”,之后所有的心形圖標都變成了紅色的bug。
那么這里給出一種實現的思路:動態類名數組。什么意思呢?就是在最初渲染的時候,把類名部分用一個類名數組動態賦值,這個類名數組提前定義好它的元素,并且確保每一個元素都是不同的、且有規律可循的,例如下面這樣:
currentFontIconColorClass : ["un0","un1","un2","un3","un4","un5",
"un6","un7","un8","un9","un10","un11","un12","un13","un14","un15",
"un16","un17","un18","un19","un20","un21","un22","un23","un24","un25",
"un26","un27","un28","un29","un30","un31","un32","un33","un34","un35",
"un36","un37","un38","un39","un40","un41","un42","un43","un44","un45",
"un46","un47","un48","un49"]
}
?每一個元素都不同,是為了實現唯一選中,這也是我們的基本需求。
?有規律可循,是為了后面我們通過用戶的點擊事件,能夠通過一些邏輯判斷哪一個元素被點擊。
此時回看第一步給出的代碼塊,發現原來這個span標簽被賦值了一個動態類名數組:
<span :class="currentFontIconColorClass[index]">
<span @click = "addSpecialList(item.uid,index)" :class="currentFontIconClass" ></span>
</span>
3??實現點擊元素選中:
緊接上一步最后,我們已經把span標簽進行了動態類名數組處理。接下來,介紹怎么完整實現點擊選中:
首先,給父span標簽的子標簽span添加一個點擊事件,至于為什么有一個子span標簽,是因為子span標簽是實際上是用來顯示心形圖標的標簽。這個點擊事件的對象毫無疑問就是心形圖標,其中傳參要特別注意把index作為參數傳入,這是我們在點擊事件函數中獲取唯一元素的必要參數。(第一個參數是原項目的特殊參數,這里不需要care它,重點關注index參數)
接下來,我們對點擊函數進行處理:
addSpecialList(e,f){
this.uid = e;
if(this.currentFontIconColorClass[f] == "un" + f.toString()){
uni.request({
url:'https://xxxx',
method:'GET',
data:{username : this.username, uid: this.uid},
header: {
'content-type': 'application/x-www-form-urlencoded' //表明后端接收的是(表單)字符串類型,例如'id=1231454&sex=男'
},
success: (res) => {
if(res.data.status == "200"){
uni.showToast({
title: "已添加特別關心"
})
}
}
})
this.currentFontIconColorClass[f] = "Specilized";
this.$forceUpdate();
}
else{
uni.request({
url:'https://xxxx',
method:'GET',
data:{username: this.username,uid: this.uid},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: (res) => {
uni.showToast({
title: "已取消特別關心",
})
// this.friendList = res.data
}
})
this.currentFontIconColorClass[f] = "un" + f.toString();
this.$forceUpdate();
}
}
上面的代碼處理過程是這樣的:
? 首先,用戶點擊了某個元素,觸發了點擊函數,同時該元素對應的索引index一并被傳入,這時候,我們進行一個簡單的字符串拼接,把"un"和這個索引值index拼接,并與我們最初的動態類名數組的對應位進行比較,實現了我們說的對象的點擊選中。同時,它的新類名變成了一個統一的類名:Specilized,該類名的渲染效果就是紅色的心?
從這兒不難看出前面提到的要給動態類名數組元素設置有規律可循的值的意義所在。
? 接著,當用戶取消某個元素的標記時,點擊該元素,觸發了點擊函數,通過判斷,發現它的原類名是Specilized,那就改回"un"和這個索引值index拼接的字符串。
【重點補充】:
這里一定要注意,修改動態類名之后,一定在修改后的下一行加上這行代碼,否則你的修改無法實施反饋:
this.$forceUpdate()
4??對已經標記的元素在加載時的處理:
上面三個步驟把第一個難點解決了,下面用簡單的介紹解決第二個難點:
加載時,我們可以告知后端,讓他們給我們在返回時用一個返回參數來區分一個元素是否已經被用戶標記,例如這樣的參數:
if(this.upperList[i].has_special_concerned == "TRUE"){
this.currentFontIconColorClass[i] = "Specilized";
this.$forceUpdate()
}
如果這個參數是TRUE,那么我們就知道這個元素已經被標記,這時候我們只需要對它的類名進行修改,統一改為“Specilized”即可。
接下來,重復循環上一個操作,直到對獲取的所有元素全部遍歷一遍之后,方可結束。
5??局限性:
首先聲明,實現這項顯示效果的方法肯定不止這一種,有很多比這個方法好的方法,同時,這個方法也存在著局限性:
? 代碼復雜性。很明顯,上面的步驟可以看出代碼會有些冗長,這是其一也。
? 需要提前定義好最大的上限。同樣很明顯,在上面的代碼中可以看出,動態類名數組的長度需要提前定義,因而建議根據實際的場景進行規劃,長度以只大不小為準。
原文鏈接:https://blog.csdn.net/qq_52736131/article/details/122361956
相關推薦
- 2022-03-20 Maven工程pom中如何定義jdk版本(maven配置jdk版本)
- 2023-07-09 echart 設置柱狀圖y軸最大刻度
- 2022-10-25 詳解redis在服務器linux下啟動的相關命令(安裝和配置)_Redis
- 2021-12-07 c++代碼各種注釋示例詳解_C 語言
- 2022-10-06 使用pip下載時提示"You?are?using?pip?version?8.1.1,?howeve
- 2022-10-14 Ubuntu18.04使用Xorg創建虛擬屏幕
- 2022-10-07 Qt入門學習之數據庫操作指南_C 語言
- 2024-03-07 使用JdbcTemplate和Druid技術簡化持久層的編寫
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支