成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

renderjs有什么用?聊聊uniapp中用renderjs的一些細節

本篇文章帶大家了解一下renderjs,通過在uniapp中使用better-scroll,聊聊renderjs的一些細節,希望對大家有所幫助!

renderjs有什么用?聊聊uniapp中用renderjs的一些細節

包含內容:

  • 使用renderjs在app端獲取dom

  • renderjs和service層之間的通信

  • renderjs中如何接收到service層中的自定義id(重點,官方文檔沒有的)

一、renderjs

1.1 renderjs的概念

  • 官方文檔

  • 運行在視圖層的js,只支持app-vue和h5(簡單來說就是開了另外一條線程)

1.2 renderjs的作用

  • 大幅降低邏輯層和視圖層的通訊損耗,提供高性能視圖交互能力(減少通訊損耗提升性能,例如一些手勢或canvas動畫的場景)

  • 在視圖層操作dom,運行for web的js庫(可以操作dom,意味著擁有window、document等這些全局變量,在app-vue的service層沒有這些)

1.3 renderjs的使用

  • 官方文檔給出的示例 (內容較為詳細,也可以看我接下來的簡要概括)
  • 在原先的script標簽的同級新增一個script,設置lang=renderjs,module=(值任意,相當于命名空間,之后會根據這個名字調用其中的方法)
  • 新script標簽內的結構和之前的幾乎一致,有幾點不同的需要注意:
    1. 生命周期不和uniapp相同,而是和vue相同,onLoad應該寫成原生vue的created
    2. 官方文檔好像說了renderjs中無法使用uni這個全局變量,具體哪個地方忘了。實測結果是:部分可以。例如uni.upx2px是可以用的,uni.request不可以,所以使用uni全局變量之前先輸出看一下有沒有
  • 在template中使用一開始給renderjs的命名加.的方式調用其中的方法
<template>   <view>     <button @tap="test.handleClick">點擊</button>   </view> </template>  <script>   export default {     // 原先的script,這里被稱為service層   } </script>  <script module="test">   export default {     data() {       return {}     },     methods: {       handleClick(event, ownerInstance) {         // event是事件對象         // ownerInstance和this.$ownerInstance是一樣的,用來調用service層的方法         console.log('點擊了按鈕')       }     },     created() {       console.log('renderjs初始化完畢')     }   } </script>

二、renderjs和service層的通信

具體分為三部分:

  • 在template中通過用戶手動操作觸發事件

  • 在service層中調用方法

  • 在renderjs中調用方法

從renderjs到service層:通過this.$ownerInstance.callMethod()方法可以調用service中的方法,第一個參數是方法名,第二個參數是傳過去的參數

<template>   <view>     <button @tap="test.onClick">點擊</button>   </view> </template>  <script>   export default {     methods: {       acceptDataFromRenderjs(data) {         console.log('從renderjs中接收到的數據', data)       }     }   } </script>  <script module="test">   export default {     data() {       return {}     },     methods: {       onClick(event, ownerInstance) {         ownerInstance.callMethod('acceptDataFromRenderjs', { content: '測試文字' })         // 或this.$ownerInstance.callMethod('acceptDataFromRenderjs', { content: '測試文字' })         // 需要注意的是:只有通過在template中用戶手動操作觸發renderjs的方法參數是這兩個:event, ownerInstance;         // 通過其他方法觸發的函數參數不一樣,后面會說       }     }   } </script>

從service層到renderjs:

這里就需要template了,首先在template中綁定一個service中定義的值,然后在同樣的位置增加:change:(屬性名)=(觸發的方法)來實現通信。

簡單來說就是service負責數據的更改,通過template監聽數據的變化來通知renderjs

<template>   <view>     // prop是個名字,可以隨意改,注意:change:[name]這兩個名字需要相同就行了     <text :prop="options" :change:prop="test.onChange">無內容</text>     <button @tap="changeOptionFn">點擊修改options</button>   </view> </template>  <script>   export default {     data() {       return {         options: {           // 這里存放準備傳遞給renderjs的數據           token: null,           num: 1         }       }     },     methods: {       changeOptionFn() {         this.options = {           // 這個地方我用時間戳來修改token,用于觸發change,實際需要傳遞的數據是num           token: Date.now(),           num: Math.random()         }       }     }   } </script>  <script module="test">   export default {     methods: {       onChange(newValue, oldValue, ownerInstance, instance) {         console.log('service層中的options發生變化')         console.log('新值', newValue)         console.log('舊值', oldValue)         // ownerInstance和this.$ownerInstance一樣,可用來向service層通信         // instance和ownerInstance的區別是:         // instance.$el指向的是觸發事件的那個節點;ownerInstance.$el指向當前vue文件中的根節點;         // instance的作用目前尚不明確,官方沒有給出用法       }     }   } </script>

在上面的例子中,prop初次綁定到節點時,事件不會觸發。

用戶首先通過點擊按鈕觸發changeOptionFn事件,函數中修改了this.options的值。

而在text節點監聽到綁定值發生了改變就會觸發test.onChange,從而實現service到renderjs的通信

上面的例子中有一點需要注意:在this.options中我定義了一個token屬性,每次修改時都將最新的時間戳賦值給他,這樣就保證了我每一次的點擊都會使options發生改變。

如果沒有這個token的話就會出現明明修改了options但是并未觸發onChange的情況。

了解js基礎的都知道,修改options是我是直接重新賦值的,改變了索引,所以即使我num值和原先的相同,他也應該做出改變(例如vue中的watch),但是事實并不是

所以可以推測出這個監聽數據改變監聽的是內部的屬性值,只有屬性的增刪改才能觸發回調。(如果一開始綁定的就是基礎數據類型的話,直接修改就好了)

故,當綁定值使用對象的時候,在對象中增加一個每次都一定會變的值,即可保證事件的觸發(如上例中的token

補充一點:進行過prop綁定的值,觸發過一次監聽事件之后,在renderjs中可以直接使用this.屬性名的方式獲取到

例如上面的代碼中,options改變導致test.onChange觸發一次之后,在renderjs中可以直接通過this.options獲取到值

三、renderjs中如何接收到service層中的自定義id

3.1 在renderjs中使用better-scroll

做過app-vue開發的話應該知道在service層中沒有document對象,無法獲取dom節點。

所以引用一些外部js的時候,如果初始化的時候需要傳入一個選擇器的,那基本就斷定用到了document對象獲取節點。

這時候就需要用到renderjs了,首先看一個better-scroll的示例。根據官方給出的示例做一些修改,我們可以得到以下代碼

<template>   <view id="my-scroll">     <view><slot /></view>   </view> </template>  <script>   export default {} </script>  <script module="BScroll">   export default {     mounted() {       // 如果這個插件支持ESModule的話就不用這么寫,直接import導入就好了       if (typeof window.BScroll == 'function') return this.initBScroll()       const script = document.createElement('script')       script.src = 'static/better-scroll.core.min.js'       script.onload = this.initBScroll       document.head.appendChild(script)     },     methods: {       initBScroll() {         this.bs = new BScroll(document.querySelector('#my-scroll'))       }     }   } </script>

3.2 better-scroll自定義id

重點來了,上面的例子中雖然實現了效果,但是也出現了一個問題:id是固定的。

如果我在同一頁面中多次使用該組件,就會導致出現多個重復id,導致無法預料的錯誤。

在官方給出的示例中,包括我研究過的插件市場中的很多項目,都是使用固定的id。

解決的方法就是由外部傳入自定義id或是由內部生成隨機id。那么應該如何在renderjs中如何接收到service層中的自定義id呢

下面我給出的方法算是我自己測試過最有效的方法了,直接看代碼

<template>   <view :id="bsId" :prop="bsId" :change:prop="BScroll.initBScroll">     <view><slot /></view>   </view> </template>  <script>   export default {     props: {       bsId: {         type: String,         default: 'bs-container'       }     }   } </script>  <script module="BScroll">   export default {     mounted() {       if (typeof window.BScroll == 'function') return this.initBScroll()       const script = document.createElement('script')       script.src = 'static/better-scroll.core.min.js'       script.onload = this.initBScroll       document.head.appendChild(script)     },     methods: {       initBScroll() {         this.bs?.destroy()         this.bs = new BScroll(document.querySelector(`#${this.$ownerInstance.$vm.bsId}`))       }     }   } </script>

在父級中傳入自定義的bsId,組件接收到之后將其作為元素id。

執行順序和之前一樣:在renderjs的mounted中加載外部js,加載完成后進行初始化操作,通過this.$ownerInstance.$vm.bsId獲取到service層中的bsId完成操作

同時,bsId也綁定了prop,監聽到改變時會重新進行初始化操作,所以在初始化的方法第一行加入了this.bs?.destroy(),如果實例已存在就先銷毀。

還記得一開始就說過的renderjs只支持app-vue和h5嗎,這里主要說的是app端,因為如果是h5端的話,是可以在service中直接使用document的,壓根不用這么麻煩。

這里還有一點需要注意的::prop="bsId" :change:prop="BScroll.initBScroll"

實測,如果不寫這行代碼,也就是不進行綁定prop的操作的話,是無法獲取到this.$ownerInstance.$vm.bsId。(app端是這樣,h5端不寫這個也可以,但是h5端壓根也用不著這種方法)

推薦:《uniapp教程》

贊(3)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
日本熟妇WWW色视频在线播放| 日韩精品无码一区二区视频| 人妻AⅤ中文字幕| 日欧一片内射VA在线影院| 丝瓜秋葵草莓香蕉榴莲绿| 无码人妻少妇色欲AV一区二区| 性色AV一区二区三区无码| 亚洲精品无码成人AV电影网| 伊人久久大香线蕉无码不卡| 91人人妻人人澡人人爽精品| 波多野结衣放荡的护士| 国产成人精品午夜视频 | 精品久久久久久中文字幕无码VR| 久久天天躁狠狠躁夜夜2019| 欧美巨大巨粗黑人性AAAAAA| 色悠久久久久综合欧美99| 性色AV无码中文AV有码VR| 亚洲人成人无码WWW影院| 综合人妻久久一区二区精品| 成人H动漫无码网站久久| 国产麻豆一精品一AV一免费软件| 久久97人妻无码一区二区三区| 妺妺窝人体色7777777| 日韩亚洲AV人人夜夜澡人人爽| 无码日韩做暖暖大全免费不卡| 亚洲精品国产AV成拍色拍婷婷| √BT天堂网WWW中文在线| 俄罗斯人又更又租| 护士HD老师FREE性ⅩⅩⅩ| 能在线观看的一区二区三区| 上司的丰满人妻中文字幕 | 国产又粗又猛又爽又黄的视频免费黑人了 | 免费看美女被靠到爽的视频| 日韩内射美女片在线观看网站 | 精品人妻无码一区二区色欲产成人 | 日产一二三区别免费必看| 亚洲AV日韩AV无码污污网站| 2021精品久久久久精品免费网| 国产XXXX色视频在线观看| 久久久久精品波多野吉衣无码AV | 亚洲A∨精品一区二区三区下载| 伊人色综合久久天天五月婷| 大胸美女污污污WWW网站| 久99久无码精品视频免费播放| 人妻丰满熟妇AV无码区动漫| 亚洲AV福利天堂在线观看| 91人妻人人爽人人澡人人精品| 国产精品久久久久成人| 麻花豆传媒剧国产入口| 无码AV中文字幕免费放| 中文精品一卡2卡3卡4卡| 国产成人亚洲精品无码青| 么公的好大好硬好深好爽视频| 天堂А√在线地址中文在线 | 麻豆人妻无码性色AV专区| 特级西西人体444WWW高清大| 伊人久久大香线蕉AV不卡| 国产成人精品三级在线影院| 蜜芽AⅤ色欲AV浪潮夜夜嗨 | 少妇乱人伦无码视频| 中国 韩国 日本 免费看| 国产精品亚洲综合色区韩国| 女生输了给对方玩一个月| 亚洲AV无码专区色爱天堂| 拔萝卜电视剧高清免费| 久久精品国产免费观看三人同眠| 少妇高潮喷水久久久影院| 在线无码VA中文字幕无码| 国产深夜男男口爆Gay| 人妻一区二区在线| 亚洲综合色区在线观看| 国产精品内射后入合集| 欧美最厉害的喷水VIDEOS| 亚洲欧美妆和亚洲妆的区别| 国产50岁老熟女网站| 男男gv在线观看| 亚洲精品无码寂寞少妇AV| 国产波霸爆乳一区二区| 欧美黑人又大又粗高潮喷水| 亚洲日韩欧洲乱码AV夜夜摸| 国产精品美女久久久免费| 人妻护士在线波多野结衣| 一二三四视频社区| 国产艳妇AV在线出轨| 色婷婷五月综合丁香中文字幕| 综合色天天鬼久久鬼色| 狠狠色噜噜狠狠狠狠色综合久AV| 上课忘穿内裤被老师摸到高潮| ASSPICS亚洲美女裸体CH| 久久精品人妻一区二区三区| 亚洲 中文 欧美 日韩 在线| 跟40岁的少妇做一次就不硬了| 欧美无人区码卡二三卡四卡| 曰韩少妇内射免费播放| 精品国产福利一区二区| 西西人体大胆WWW.4444| 从厨房一路顶撞到卧室门好吗| 欧美VIDEOSDESXO孕交| 一本色道久久综合狠狠躁| 黑料不打烊吃瓜爆料| 无码人妻精品一二三区免费 | 精品国产一区二区三区无码| 无遮挡裸体免费视频尤物| 高潮久久久久久久久不卡| 日本JAPANESE猛男GAY| 97国产精华液哪个品牌比较好贵| 久久久久亚洲AV无码专区首页网| 亚洲成AV人在线视| 国产精品原创AV片国产日韩| 婷婷蜜桃国产精品| 东京热无码人妻系列综合网站| 欧洲一卡2卡3卡4卡乱码视频| 2021无码专区人妻系列日韩| 麻豆国产成人AV在线播放欲色| 亚洲一成人精品无码一区二区三区 | 97人妻无码一区二区精品免费| 浪荡艳妇爆乳JUFD汗だく肉感| 亚洲熟妇无码一区二区三区导航 | 撒尿BBWBBW毛| 成年女人毛片免费视频喷潮| 秋霞成人无码电影在线观看| MATUREHDHQ成熟| 欧美最猛性XXX| JIZZJIZZJIZZ日本| 欧洲乱码一卡2卡三卡4卡高清| GAYFUCKⅩⅩⅩⅩHD激情| 欧美伊人色综合久久天天| YY8090理论三级在线观看| 人妻无奈被迫屈辱1-9| 波多野结衣无码中文字幕18禁| 欧美色欧美亚洲高清在线观看| 99这里只有精品| 欧美猛少妇色XXXXX猛叫| FREE性VIDEOXXⅩ欧美| 让人爽到湿的小黄书软件下载| JAPANESEXXXⅩHD乱| 人人做人人澡人人爽欧美| 成人无码精品一区二区三区亚洲区| 日韩人妻无码精品专区| 国产操熟女性爱导航| 无码中文字幕VA精品影院| 国产目拍亚洲精品一区| 亚洲成a人片在线观看无码专区 | 亚洲少妇一区二区视频| 久久天天躁狠狠躁夜夜不卡| 重囗味sm在线观看无码| 欧洲亚洲日韩性无码专区 | 精品精品国产欧美在线| 亚洲综合无码一区二区三区不卡| 老奶奶BGMBGM人与自然| 92成人午夜福利一区二区| 全部极品AV娱乐盛宴| 丰满岳跪趴高撅肥臀| 无人高清影视在线观看| 精品久久人人做人人爽综合| 尤物国精品午夜福利视频| 欧美丰满少妇XXXXX| 成人免费无遮挡无码黄漫视频| 丝袜美女人体艺术| 国精产品一二三四区产品| 亚洲熟女成年三级中文字幕| 妺妺窝人体色WWW精品| 锕锕锕锕锕锕锕锕好疼动免费| 上司人妻互换HD无码| 国产做国产爱免费视频| 一本色道无码不卡在线观看| 欧美人交A欧美精品AV一区| 懂色av 春色 色欲| 亚洲AV无码国产丝袜在线观看| 久久无码中文字幕免费影院蜜桃| FREE紧VIDEOXX粗又长| 特大巨黑吊性XXXX| 精品国产一区二区三区香蕉| 中文在线天堂А√在线| 日日摸夜夜爽无码毛片精选 | 亚洲METART人体欣赏| 美女MM131爽爽爽| 尺码最大的国产SUV| 亚洲AV丁香五月六月婷婷| 老男人吃奶疯狂啃肿奶头| 成人国产精品一区二区视频| 亚洲AV无码不卡| 奶头又大又白喷奶水AV| 公咬着小娇乳H边走边欢视频 | 成人一区二区不卡久久久| 亚洲AV无码专区国产乱码APP| 蜜臂无码AV在线| 粉嫩av观看成人网站| 亚洲人成网站18禁止大| 秋霞鲁丝片成人无码| 国产亚洲无线码一区二区| 2021自拍偷在线精品自拍偷| 天堂AV无码一区二区三区 | 日韩精品久久久久久久电影蜜臀 | 九色丨PORNY丨自拍 ICU| MM1313又粗又大受不了| 亚洲AV成人无码精品网站色欲 | 国产黄在线观看免费观看不卡| 一区二区三区无码在线观看| 少女たちよ在线观看动漫4|