宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動(dòng)態(tài)
精選推薦

UniApp 使用 RenderJS 在 App 端實(shí)現(xiàn)復(fù)雜交互

管理 管理 編輯 刪除

前言

使用 UniApp 開發(fā) Android / iOS App 時(shí),經(jīng)常會(huì)有地圖、可視化圖表、攝像頭、視頻播放、人臉采集、富文本編輯器等需求。而 UniApp 提供的相關(guān)組件或多或少存在各種影響使用的問題:如地圖層級(jí)過高難以覆蓋,UniApp 插件市場中的可視化圖表功能缺失、攝像頭相關(guān) API 接口過于簡陋等,使得開發(fā)工作難以進(jìn)行。

RenderJS

在這種情況下,RenderJS 的出現(xiàn)極大程度上緩解了這些難題。 RenderJS 是內(nèi)置在 UniApp 框架中的一個(gè)組件,它運(yùn)行在視圖層,可以在 App 端中對 DOM 直接進(jìn)行操作,并運(yùn)行 for web 的 JavaScript 庫,這意味著在 Web 支持的一切功能都可以在 App 端實(shí)現(xiàn)。

與此同時(shí), RenderJS 也存在著一定的限制:如不支持 Vue3 的 Setup 寫法,不能直接和邏輯層進(jìn)行通信,需要借助一定的技巧才能實(shí)現(xiàn)雙向通信等。

示例代碼

下面是 RenderJS 實(shí)際使用的一點(diǎn)例子,這些代碼想說明的問題只有一個(gè):視圖層和邏輯層如何互相調(diào)用方法和傳遞數(shù)據(jù)。示例比較長,可以翻到下面跟著說明來閱讀代碼。

<template>
  <view id="container" style="padding-top: 20vh;" :viewLayerCallJson="viewLayerCallJson"
    :change:viewLayerCallJson="viewLayer.handleLogicLayerCall" :viewLayerData="viewLayerData" :change:viewLayerData="viewLayer.handleLogicLayerData">
    <button @click="handleTest">調(diào)用邏輯層方法</button>
    <button @click="viewLayer.handleViewLayerTest">調(diào)用視圖層方法</button>
    <button @click="handleTest2">從邏輯層調(diào)用視圖層方法</button>
    <button @click="viewLayer.handleViewLayerTest2">從視圖層調(diào)用邏輯層方法</button>

    <button @click="handleSendDataToViewLayer">視圖層傳遞數(shù)據(jù)給視圖層</button>
    <button @click="handleTest4">動(dòng)態(tài)創(chuàng)建 VIDEO 元素</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      viewLayerCallJson: null,
      viewLayerData: null
    };
  },
  methods: {
    handleViewLayerCall({ method, params }) {
      this[method]?.(params);
    },
    handleCallViewLayerFunc(method, params) {
      const randomNethodPrefix = Math.random().toString(36).substring(2, 15);
      this.viewLayerCallJson = JSON.stringify({
        method: `${randomNethodPrefix}-${method}`,
        params
      });
    },
    handleTest2() {
      this.handleCallViewLayerFunc("createEl", {
        tag: "input",
        value: "hahahaha"
      });
    },
    handleTest3({ content }) {
      uni.showModal({
        title: "提示",
        content,
        success: (res) => {
          console.log(res);
        }
      });
    },
    handleTest4() {
      this.handleCallViewLayerFunc("createEl", {
        tag: "video"
      });
    },
    handleTest() {
      uni.showModal({
        title: "提示",
        content: "邏輯層方法被調(diào)用啦",
        success: (res) => {
          console.log(res);
        }
      });
    },
    handleSendDataToViewLayer() {
      this.viewLayerData = Date.now();
    }
  }
}
</script>

<script lang="renderjs" module="viewLayer">
export default {
  data() {
      return {
          _data: {}
      };
  },
  methods: {
      handleViewLayerTest() {
          alert("視圖層方法被調(diào)用啦")
      },
      handleViewLayerTest2() {
          this.callLogicLayerFunc("handleTest3", { 
              content: "從視圖層調(diào)用邏輯層方法"
          });
      },
      handleLogicLayerCall(json) {
          if (!json) return;
          const { method: randomMethod, params } = JSON.parse(json);
          const method = randomMethod.split("-")[1];
          this[method]?.(params);
      },
      createEl({ value, tag }) {
          const el = document.createElement(tag);
          if (value) {
            el.value = value;
          }
          document.querySelector("#container").append(el);
      },
      callLogicLayerFunc(method, params) {
          this.$ownerInstance.callMethod("handleViewLayerCall", {
              method,
              params
          });
      },
      handleLogicLayerData(newval, oldval, owner, instance) {
        console.log(newval, oldval, owner, instance);
      }
  }
}
</script>

<style>
button + button {
  margin-top: 20px;
}
</style>


編寫 RenderJS 代碼

寫在正常 script 標(biāo)簽中的代碼運(yùn)行在邏輯層,而 RenderJS 運(yùn)行在視圖層。 RenderJS 的代碼在編寫時(shí)需要單獨(dú)寫在一個(gè) script 標(biāo)簽中,同時(shí)給 script 標(biāo)簽添加 lang="renderjs" 和 module="xxx" 的屬性,前者是固定值不能修改,后者可以自行定義,用來在模板中引用 RenderJS 中定義的屬性和方法。

df086202502201508222378.png

邏輯層向視圖層傳遞數(shù)據(jù)

傳遞數(shù)據(jù)需要關(guān)注以下幾點(diǎn):

  1. 在邏輯層中定義數(shù)據(jù),這個(gè)無需多言,正常定義要傳遞的數(shù)據(jù)即可。

e1682202502201513267900.png

2. 在模板內(nèi)任意標(biāo)簽中綁定要傳遞的數(shù)據(jù),通過 :change:[屬性名] 來監(jiān)聽綁定數(shù)據(jù)的變化,并綁定在視圖層中定義的回調(diào)函數(shù),綁定視圖層中定義的回調(diào)函數(shù)時(shí)需要以視圖層 module 屬性為前綴來調(diào)用。

02892202502201517406156.png

3. 在視圖層內(nèi)定義屬性變化的回調(diào)函數(shù)

df5bb202502201519323447.png

回調(diào)函數(shù)會(huì)傳遞四個(gè)參數(shù),分別是綁定屬性新值,上一次的值,視圖層實(shí)例以及邏輯層實(shí)例,需要注意回調(diào)函數(shù)在組件創(chuàng)建之后無論數(shù)據(jù)是否變化都會(huì)被調(diào)用一次。


視圖層向邏輯層傳遞數(shù)據(jù)

視圖層并不能直接向邏輯層傳遞數(shù)據(jù),只能借助調(diào)用邏輯層方法的形式來傳遞數(shù)據(jù),具體可以參見下一小節(jié)。


視圖層調(diào)用邏輯層方法

視圖層可以通過 $ownerInstance.callMethod 方法來調(diào)用邏輯層內(nèi)定義的方法,該方法接受兩個(gè)參數(shù),邏輯層方法名和邏輯層方法接受的參數(shù)。

e3cc1202502201523519483.png

邏輯層調(diào)用視圖層的方法

邏輯層并不能直接調(diào)用視圖層的方法,但通過一些技巧可以巧妙的實(shí)現(xiàn)調(diào)用。通過將要調(diào)用的方法和參數(shù)名序列化為 JSON 字符串,并作為數(shù)據(jù)傳遞給視圖層,視圖層在回調(diào)方法內(nèi)反序列化 JSON 數(shù)據(jù),然后執(zhí)行相關(guān)方法。

如果連續(xù)調(diào)用同一個(gè)方法并傳遞相同的參數(shù),由于 JSON 字符串沒有發(fā)生變化,因?yàn)橐晥D層的回調(diào)函數(shù)并不會(huì)被執(zhí)行,因此需要在 JSON 字符串內(nèi)加入一些隨機(jī)因子,使得每次調(diào)用方法生成的 JSON 字符串總是不相同的。

96c0e202502201532249511.png

5baf2202502201533192306.png

561b9202502201533429526.png

需要注意傳遞的數(shù)據(jù)內(nèi)容必須是兼容 JSON 的基本數(shù)據(jù)類型,如果傳遞 Set、Map、ArrayBuffer 等類型將會(huì)出現(xiàn)不可預(yù)知的錯(cuò)誤,同時(shí)傳遞的數(shù)據(jù)也不宜過大過于頻繁,否則可能會(huì)造成性能問題。

使用場景

基于以上的例子,以往很多不能實(shí)現(xiàn)的操作都可以實(shí)現(xiàn)。如引入 ECharts 使用全功能圖表,通過動(dòng)態(tài)創(chuàng)建 Video 元素來避免使用 App 內(nèi)置的 Video 元素,使用 Web 端的各種地圖組件,不再為 App 端 Map 組件層級(jí)過高無法覆蓋而頭痛,使用 navigator.getUserMedia 操作攝像頭來實(shí)現(xiàn)自定義視頻錄制界面等等,一切在 Web 端可以實(shí)現(xiàn)的功能都可以在 App 中實(shí)現(xiàn),不再受限于 UniApp App 的 API 限制。


注意事項(xiàng)

RenderJS 僅兼容 App 和 Web 兩端,雖然在微信小程序中存在著類 RenderJS 的組件 WXS,但其只是 RenderJS 的剪裁版,因此并不兼容。

RenderJS 是一個(gè)用來在 App 中實(shí)現(xiàn) Web 相關(guān)能力的產(chǎn)物,因此在 Web 中并不需要 RenderJS。 RenderJS 在 Web 端運(yùn)行時(shí),其會(huì)以 mixin 形式混入邏輯層,因此在編寫視圖層代碼時(shí),應(yīng)注意在屬性名和方法名上和邏輯層加以區(qū)分,以免出現(xiàn)在 Web 端運(yùn)行時(shí)被覆蓋的問題。

請登錄后查看

plz 最后編輯于2025-02-20 16:16:52

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
2826
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動(dòng)態(tài) 精選推薦 首頁頭條 首頁動(dòng)態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動(dòng)獲取的帖子內(nèi)容,不準(zhǔn)確時(shí)需要手動(dòng)修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊

切換手機(jī)號(hào)登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服