久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網(wǎng)
最全最豐富的資訊網(wǎng)站

renderjs有什么用?聊聊uniapp中用renderjs的一些細(xì)節(jié)

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

renderjs有什么用?聊聊uniapp中用renderjs的一些細(xì)節(jié)

包含內(nèi)容:

  • 使用renderjs在app端獲取dom

  • renderjs和service層之間的通信

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

一、renderjs

1.1 renderjs的概念

  • 官方文檔

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

1.2 renderjs的作用

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

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

1.3 renderjs的使用

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

二、renderjs和service層的通信

具體分為三部分:

  • 在template中通過用戶手動(dòng)操作觸發(fā)事件

  • 在service層中調(diào)用方法

  • 在renderjs中調(diào)用方法

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

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

從service層到renderjs:

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

簡單來說就是service負(fù)責(zé)數(shù)據(jù)的更改,通過template監(jiān)聽數(shù)據(jù)的變化來通知renderjs

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

在上面的例子中,prop初次綁定到節(jié)點(diǎn)時(shí),事件不會(huì)觸發(fā)。

用戶首先通過點(diǎn)擊按鈕觸發(fā)changeOptionFn事件,函數(shù)中修改了this.options的值。

而在text節(jié)點(diǎn)監(jiān)聽到綁定值發(fā)生了改變就會(huì)觸發(fā)test.onChange,從而實(shí)現(xiàn)service到renderjs的通信

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

如果沒有這個(gè)token的話就會(huì)出現(xiàn)明明修改了options但是并未觸發(fā)onChange的情況。

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

所以可以推測出這個(gè)監(jiān)聽數(shù)據(jù)改變監(jiān)聽的是內(nèi)部的屬性值,只有屬性的增刪改才能觸發(fā)回調(diào)。(如果一開始綁定的就是基礎(chǔ)數(shù)據(jù)類型的話,直接修改就好了)

故,當(dāng)綁定值使用對象的時(shí)候,在對象中增加一個(gè)每次都一定會(huì)變的值,即可保證事件的觸發(fā)(如上例中的token

補(bǔ)充一點(diǎn):進(jìn)行過prop綁定的值,觸發(fā)過一次監(jiān)聽事件之后,在renderjs中可以直接使用this.屬性名的方式獲取到

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

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

3.1 在renderjs中使用better-scroll

做過app-vue開發(fā)的話應(yīng)該知道在service層中沒有document對象,無法獲取dom節(jié)點(diǎn)。

所以引用一些外部js的時(shí)候,如果初始化的時(shí)候需要傳入一個(gè)選擇器的,那基本就斷定用到了document對象獲取節(jié)點(diǎn)。

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

<template>   <view id="my-scroll">     <view><slot /></view>   </view> </template>  <script>   export default {} </script>  <script module="BScroll">   export default {     mounted() {       // 如果這個(gè)插件支持ESModule的話就不用這么寫,直接import導(dǎo)入就好了       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

重點(diǎn)來了,上面的例子中雖然實(shí)現(xiàn)了效果,但是也出現(xiàn)了一個(gè)問題:id是固定的。

如果我在同一頁面中多次使用該組件,就會(huì)導(dǎo)致出現(xiàn)多個(gè)重復(fù)id,導(dǎo)致無法預(yù)料的錯(cuò)誤。

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

解決的方法就是由外部傳入自定義id或是由內(nèi)部生成隨機(jī)id。那么應(yīng)該如何在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>

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

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

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

還記得一開始就說過的renderjs只支持app-vue和h5嗎,這里主要說的是app端,因?yàn)槿绻莌5端的話,是可以在service中直接使用document的,壓根不用這么麻煩。

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

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

推薦:《uniapp教程》

贊(3)
分享到: 更多 (0)
?
網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
最新国产精品久久久| 国产成人77亚洲精品www| 亚洲四虎影院| 亚洲1234区| 欧美片第1页| 日韩在线欧美| 欧洲亚洲一区二区三区| 高清av不卡| 日韩欧美三级| 久久天堂精品| 九九在线精品| 妖精视频成人观看www| 欧美特黄一级| 久久久久亚洲| 日韩视频二区| 国产亚洲一级| 亚洲精品婷婷| 国产精品色婷婷在线观看| 久久99青青| 国产a亚洲精品| 欧美freesex黑人又粗又大| 久久蜜桃资源一区二区老牛| 精品一区免费| 亚洲五月综合| 国产乱码精品一区二区三区亚洲人| 久久精品xxxxx| 国产在线观看91一区二区三区 | 国产精品毛片在线| 国产精品视区| 欧美日本久久| 国内自拍视频一区二区三区| 92国产精品| 日韩亚洲在线| 91综合久久爱com| 日韩av在线播放网址| 欧美日韩国产高清电影| 亚洲影院天堂中文av色| 国产日韩欧美中文在线| 超级白嫩亚洲国产第一| 精品91久久久久| 中文字幕av一区二区三区四区| 国产剧情在线观看一区| 中文字幕色婷婷在线视频| 日韩亚洲在线| 国产精品久一| 欧美日韩激情| 日韩va亚洲va欧美va久久| 国产福利片在线观看| 久久国产高清| 久久99偷拍| 激情欧美国产欧美| 亚洲欧洲日韩| 激情国产在线| 男女激情视频一区| 久久av导航| 国户精品久久久久久久久久久不卡| 最新国产精品视频| 岛国av免费在线观看| 亚洲欧洲日韩| 亚洲播播91| 欧美在线精品一区| 成人羞羞视频播放网站| 四虎精品一区二区免费| 麻豆mv在线观看| 亚洲精一区二区三区| 精品理论电影在线| 男人天堂欧美日韩| 国产91在线播放精品| 最新亚洲国产| 久久国产免费| 欧美亚洲综合视频| 欧美肉体xxxx裸体137大胆| 日韩av中文字幕一区二区三区| 在线成人动漫av| 国产精品66| 亚洲一区av| 久久精品国产大片免费观看| 国产精品v一区二区三区| 中文在线一区| 日韩亚洲一区在线| 久久国产欧美日韩精品| 精品91久久久久| 蜜臀国产一区| 欧美日韩一区二区三区不卡视频 | 亚洲综合五月| 久久九九精品| 麻豆国产精品| 蜜桃视频第一区免费观看| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 好吊日精品视频| 国产欧美大片| 国产亚洲欧洲| 欧美日韩尤物久久| 久久wwww| 亚洲精品人人| 红桃视频国产精品| 精品久久电影| 日韩福利在线观看| 亚洲激情中文| 日韩精品麻豆| 成人午夜网址| 久久99久久人婷婷精品综合| 亚洲欧美久久精品| 五月天久久777| 久久久久久色 | 亚洲欧美日韩国产一区二区| 蜜桃精品在线| 国产高清一区| 日本蜜桃在线观看视频| 麻豆久久久久久| 欧美天堂在线| 亚洲资源网站| 欧美日韩国产欧| 欧美日韩免费看片| 电影91久久久| 欧美激情一区| 国产精品99久久久久久董美香| 亚洲精品美女91| 亚洲综合五月| 亚洲久草在线| 亚洲久久在线| 亚洲深深色噜噜狠狠爱网站| 香蕉视频成人在线观看| 日韩中文在线电影| 97精品国产一区二区三区| 精品视频一区二区三区在线观看| 国产麻豆一区二区三区精品视频| 日韩一二三区在线观看| 香蕉久久夜色精品国产| 美女精品一区| 性一交一乱一区二区洋洋av| 婷婷亚洲五月色综合| re久久精品视频| 最新日韩欧美| aⅴ色国产欧美| 国产亚洲福利| 日韩影院在线观看| 免费视频一区二区| 丝袜诱惑制服诱惑色一区在线观看 | 久久在线电影| 激情综合在线| 欧美日韩国产亚洲一区| 亚洲欧美网站| 日本不卡一区二区三区| 7m精品国产导航在线| 国产欧美欧美| 久久女人天堂| 成人欧美一区二区三区的电影| a日韩av网址| 久久精品国语| 国产视频亚洲| 国产精品人人爽人人做我的可爱| 蜜桃久久av| 日韩高清成人在线| 欧美精品99| 国产va在线视频| 91九色精品| 日韩欧美三区| 欧美精品97| 日韩专区精品| 亚洲欧美日韩一区在线观看| 日韩欧美中文字幕一区二区三区 | 欧美日韩精品一区二区视频| 欧美日韩精品一本二本三本| 日韩在线一区二区| 伊人久久大香伊蕉在人线观看热v| 无码日韩精品一区二区免费| 国产精品xxx在线观看| 另类专区亚洲| 午夜免费一区| 日韩精品高清不卡| 精品72久久久久中文字幕| 国产99精品| 日韩和欧美一区二区| 麻豆国产91在线播放| 中文字幕高清在线播放| 午夜欧美在线| 国产亚洲欧美日韩精品一区二区三区| 成人午夜毛片| 午夜在线视频观看日韩17c| 日韩三区四区| 国产不卡人人| 免费视频久久| 美女性感视频久久| 欧美日韩国产欧| 18国产精品| 日韩精品专区| 亚洲日本欧美| 激情综合五月| 午夜一区在线| 免费一级欧美在线观看视频| 极品日韩av| 国产精品一页| 激情综合亚洲| 国产伦精品一区二区三区千人斩| 麻豆理论在线观看| 亚洲一区二区三区久久久| 久久精品国产亚洲aⅴ| 红桃视频国产一区| 国内精品亚洲|