最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

uni-app中App與webview雙向?qū)崟r通信詳細(xì)代碼示例

 更新時間:2024年07月17日 09:39:09   作者:智能??????  
在移動應(yīng)用開發(fā)中,uni-app是一個非常流行的框架,它允許開發(fā)者使用一套代碼庫構(gòu)建多端應(yīng)用,包括H5、小程序、App等,這篇文章主要給大家介紹了關(guān)于uni-app中App與webview雙向?qū)崟r通信的相關(guān)資料,需要的朋友可以參考下

在 Uniapp 中,App 與 里面嵌入的 webview 進行雙向的實時通信

vue2 , 模擬器

主要分為兩部分

  • webview 向 app 發(fā)送信息

  • app 向 webview 發(fā)送信息

以下是實現(xiàn)方式,用一個例子來說明

(文章最后我會放這個例子的github地址)

webview 向 app 發(fā)送信息

示例: webview 里面向 app 發(fā)送 圖片的 base64 , app 保存圖片到系統(tǒng)相冊;

此處分為, app 和 webview 部分:

  • app 注冊事件

  • webview 觸發(fā) app 的事件

app部分

  • 保存到系統(tǒng)相冊功能(功能具體細(xì)節(jié)不重要)

    // utils/appMessageHandler.js
    // 這里代碼都在app下執(zhí)行
    function appSaveImgFile(params) {
      const { base64, downloadName } = params
      const bitmap = new plus.nativeObj.Bitmap("test");
      bitmap.loadBase64Data(
        base64,
        function () {
          const url = "_doc/" + downloadName + ".png"; // url為時間戳命名方式
          bitmap.save(
            url,
            {
              overwrite: true, // 是否覆蓋
              // quality: 'quality'  // 圖片清晰度
            },
            (i) => {
              plus.gallery.save(
                i.target,
                function () {
                  uni.showToast({
                    title: "APP圖片保存至相冊",
                    icon: "none",
                  });
                  bitmap.clear();
                },
                function (e) {
                  uni.showToast({
                    title: "APP圖片保存至相冊失敗:" + JSON.stringify(e),
                    icon: "none",
                  });
                  bitmap.clear();
                }
              );
            },
            (e) => {
              uni.showToast({
                title: "圖片保存失敗1:" + JSON.stringify(e),
                icon: "none",
              });
              bitmap.clear();
            }
          );
        },
        (e) => {
          uni.showToast({
            title: "圖片保存失敗2:" + JSON.stringify(e),
            icon: "none",
          });
          bitmap.clear();
        }
      );
    }
    
    export {
      appSaveImgFile,
    }
    
  • 在App.vue中注冊事件;將 appMessageHandle.js 里面所有導(dǎo)出的事件進行注冊;注意需要條件編譯

    // App.vue
    <script>
    import * as appPlusMessageHandler from "./utils/appMessageHandler";
    
    export default {
      data() {
        return {
          appRegisterMap: undefined,
        };
      },
      onLaunch: function () {
        console.log("App Launch");
        // #ifdef APP-PLUS
        // 注冊事件
        plus.globalEvent.addEventListener("plusMessage", this.plusMessageHandler);
        // #endif
      },
      methods: {
        /**
         * 將所有導(dǎo)出的 app 事件
         * 用 map 建立 函數(shù)名 - 函數(shù) 的聯(lián)系
         * 返回 map
         */
        registerAppPlusMap() {
          if (this.appRegisterMap) {
            return this.appRegisterMap;
          }
          let map = new Map();
          Object.keys(appPlusMessageHandler).forEach((item) => {
            map.set(item, appPlusMessageHandler[item]);
          });
          this.appRegisterMap = map;
          return map;
        },
        /**
         * 用 action 獲取的函數(shù)名
         * 通過 map 獲取到函數(shù),調(diào)用執(zhí)行
         */
        plusMessageHandler(msg) {
          let map = this.registerAppPlusMap();
          if (msg.data.args.data.arg?.action) {
            let handler = map.get(msg.data.args.data.arg?.action);
            let params = msg.data.args.data.arg?.params;
            handler && handler(params);
          }
        },
      },
    };
    </script>
    

webview 部分

通過使用 uni.webview.js (文末附錄放源碼,我做了些許修改,邏輯沒改,是一些變量調(diào)整了下) 的功能 postMessage , 向 app 發(fā)送圖片生成的 base64;

  • main.js 中掛載 uWeb (uni.webview.js)

    // main.js
    // 全局添加uWeb
    // #ifdef H5
    import uWeb from "@/utils/uni.webview.js";
    // #endif
    
    // #ifdef H5
    Vue.prototype.$uWeb = uWeb;
    // #endif
    
  • 生成的圖片base64,通過以下方式發(fā)送給 app

    此處 action 與 上面 plusMessageHandler方法的 action 是對應(yīng)的

    appSaveImgFile 與 appMessageHandler.js 里的函數(shù)名是對應(yīng)的

    // 某個頁面或者js
    this.$uWeb.postMessage({
            data: {
              action: "appSaveImgFile",
              params: {
                base64: imgBase64,
                downloadName,
              },
            },
          });
    

至此,webview 能隨時向 app 發(fā)送消息了

App 向 webview 發(fā)送消息

使用 evalJS

分兩步:

  • webview 在 window 注冊事件

  • app 使用 evalJs 觸發(fā) webview 的事件

注意: 確保webview 先注冊好事件之后,app發(fā)送的事件才能被 webview 接收到

具體實現(xiàn),utils下新建appToWebview.js; appSendMessage 是給 App 用的;webviewGetMessage 是給 webview 注冊用的

// appToWebview.js
// 發(fā)送信息之前,先要有 webviewGetMessage
function appSendMessage(_this, action, params) {
  const self = _this;
  self.currentWebview = self.$scope?.$getAppWebview()?.children()[0];
  //傳遞大量數(shù)據(jù)
  self.currentWebview?.evalJS(`${action}(${JSON.stringify(params)})`);
}

function webviewGetMessage(action, callback) {
  // #ifdef H5
  window[action] = (data) => {
    let params = JSON.parse(JSON.stringify(data));
    callback(params);
  };
  // #endif
}

export { appSendMessage, webviewGetMessage };

webview 部分

用 webviewGetMessage 注冊一個 msgFromApp 名字的事件,給 App 調(diào)用;

  // 某個 webview 頁面,
  created() {
    webviewGetMessage("msgFromApp", (params) => {
      console.log("getAppParams", params);
      this.appMsg = params;
    });
  },

App

用 appSendMessage 發(fā)送一個信息給 webview

  // 某個有 webview 的 app 頁面,
  mounted() {
    setTimeout(() => {
      appSendMessage(this, "msgFromApp", { msgFromApp: 233 });
    }, 5000);
  },

至此,完成了 app 向 webview 發(fā)送信息

GitHub 地址

GitHub - adcGG/uniapp-app-webview: Communication between app and webview

這里 uniapp 項目,app 和 用到的 h5 地址是同一個項目下的

app/index 用到的 webview 的 url 為 webviewUrl: “http://192.168.1.16:8080/#/pages/h5/index”,

附錄

uni.webview.js

!(function (e, n) {
  "object" == typeof exports && "undefined" != typeof module
    ? (module.exports = n())
    : "function" == typeof define && define.amd
    ? define(n)
    : ((e = e || self).webUni = n());
})(this, function () {
  "use strict";
  try {
    var e = {};
    Object.defineProperty(e, "passive", {
      get: function () {
        !0;
      },
    }),
      window.addEventListener("test-passive", null, e);
  } catch (e) {}
  var n = Object.prototype.hasOwnProperty;

  function t(e, t) {
    return n.call(e, t);
  }
  var i = [],
    a = function (e, n) {
      var t = {
        options: {
          timestamp: +new Date(),
        },
        name: e,
        arg: n,
      };
      if (window.__dcloud_weex_postMessage || window.__dcloud_weex_) {
        if ("postMessage" === e) {
          var a = {
            data: [n],
          };
          return window.__dcloud_weex_postMessage
            ? window.__dcloud_weex_postMessage(a)
            : window.__dcloud_weex_.postMessage(JSON.stringify(a));
        }
        var o = {
          type: "WEB_INVOKE_APPSERVICE",
          args: {
            data: t,
            webviewIds: i,
          },
        };
        window.__dcloud_weex_postMessage
          ? window.__dcloud_weex_postMessageToService(o)
          : window.__dcloud_weex_.postMessageToService(JSON.stringify(o));
      }
      if (!window.plus)
        return window.parent.postMessage(
          {
            type: "WEB_INVOKE_APPSERVICE",
            data: t,
            pageId: "",
          },
          "*"
        );
      if (0 === i.length) {
        var r = plus.webview.currentWebview();
        if (!r) throw new Error("plus.webview.currentWebview() is undefined");
        var d = r.parent(),
          s = "";
        (s = d ? d.id : r.id), i.push(s);
      }
      if (plus.webview.getWebviewById("__uniapp__service"))
        plus.webview.postMessageToUniNView(
          {
            type: "WEB_INVOKE_APPSERVICE",
            args: {
              data: t,
              webviewIds: i,
            },
          },
          "__uniapp__service"
        );
      else {
        var w = JSON.stringify(t);
        plus.webview
          .getLaunchWebview()
          .evalJS(
            'UniPlusBridge.subscribeHandler("'
              .concat("WEB_INVOKE_APPSERVICE", '",')
              .concat(w, ",")
              .concat(JSON.stringify(i), ");")
          );
      }
    },
    o = {
      navigateTo: function () {
        var e =
            arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
          n = e.url;
        a("navigateTo", {
          url: encodeURI(n),
        });
      },
      navigateBack: function () {
        var e =
            arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
          n = e.delta;
        a("navigateBack", {
          delta: parseInt(n) || 1,
        });
      },
      switchTab: function () {
        var e =
            arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
          n = e.url;
        a("switchTab", {
          url: encodeURI(n),
        });
      },
      reLaunch: function () {
        var e =
            arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
          n = e.url;
        a("reLaunch", {
          url: encodeURI(n),
        });
      },
      redirectTo: function () {
        var e =
            arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
          n = e.url;
        a("redirectTo", {
          url: encodeURI(n),
        });
      },
      getEnv: function (e) {
        window.plus
          ? e({
              plus: !0,
            })
          : e({
              h5: !0,
            });
      },
      postMessage: function () {
        var e =
          arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
        a("postMessage", e.data || {});
      },
    },
    r = /uni-app/i.test(navigator.userAgent),
    d = /Html5Plus/i.test(navigator.userAgent),
    s = /complete|loaded|interactive/;
  var w = window.my && navigator.userAgent.indexOf("AlipayClient") > -1;
  var u =
    window.swan && window.swan.webView && /swan/i.test(navigator.userAgent);
  var c =
    window.qq &&
    window.qq.miniProgram &&
    /QQ/i.test(navigator.userAgent) &&
    /miniProgram/i.test(navigator.userAgent);
  var g =
    window.tt &&
    window.tt.miniProgram &&
    /toutiaomicroapp/i.test(navigator.userAgent);
  var v =
    window.wx &&
    window.wx.miniProgram &&
    /micromessenger/i.test(navigator.userAgent) &&
    /miniProgram/i.test(navigator.userAgent);
  var p = window.qa && /quickapp/i.test(navigator.userAgent);
  for (
    var l,
      _ = function () {
        (window.UniAppJSBridge = !0),
          document.dispatchEvent(
            new CustomEvent("UniAppJSBridgeReady", {
              bubbles: !0,
              cancelable: !0,
            })
          );
      },
      f = [
        function (e) {
          if (r || d)
            return (
              window.__dcloud_weex_postMessage || window.__dcloud_weex_
                ? document.addEventListener("DOMContentLoaded", e)
                : window.plus && s.test(document.readyState)
                ? setTimeout(e, 0)
                : document.addEventListener("plusready", e),
              o
            );
        },
        function (e) {
          if (v)
            return (
              window.WeixinJSBridge && window.WeixinJSBridge.invoke
                ? setTimeout(e, 0)
                : document.addEventListener("WeixinJSBridgeReady", e),
              window.wx.miniProgram
            );
        },
        function (e) {
          if (c)
            return (
              window.QQJSBridge && window.QQJSBridge.invoke
                ? setTimeout(e, 0)
                : document.addEventListener("QQJSBridgeReady", e),
              window.qq.miniProgram
            );
        },
        function (e) {
          if (w) {
            document.addEventListener("DOMContentLoaded", e);
            var n = window.my;
            return {
              navigateTo: n.navigateTo,
              navigateBack: n.navigateBack,
              switchTab: n.switchTab,
              reLaunch: n.reLaunch,
              redirectTo: n.redirectTo,
              postMessage: n.postMessage,
              getEnv: n.getEnv,
            };
          }
        },
        function (e) {
          if (u)
            return (
              document.addEventListener("DOMContentLoaded", e),
              window.swan.webView
            );
        },
        function (e) {
          if (g)
            return (
              document.addEventListener("DOMContentLoaded", e),
              window.tt.miniProgram
            );
        },
        function (e) {
          if (p) {
            window.QaJSBridge && window.QaJSBridge.invoke
              ? setTimeout(e, 0)
              : document.addEventListener("QaJSBridgeReady", e);
            var n = window.qa;
            return {
              navigateTo: n.navigateTo,
              navigateBack: n.navigateBack,
              switchTab: n.switchTab,
              reLaunch: n.reLaunch,
              redirectTo: n.redirectTo,
              postMessage: n.postMessage,
              getEnv: n.getEnv,
            };
          }
        },
        function (e) {
          return document.addEventListener("DOMContentLoaded", e), o;
        },
      ],
      m = 0;
    m < f.length && !(l = f[m](_));
    m++
  );
  l || (l = {});
  var E = "undefined" != typeof webUni ? webUni : {};
  if (!E.navigateTo) for (var b in l) t(l, b) && (E[b] = l[b]);
  return (E.webView = l), E;
});

總結(jié) 

到此這篇關(guān)于uni-app中App與webview雙向?qū)崟r通信的文章就介紹到這了,更多相關(guān)uni-app App與webview雙向?qū)崟r通信內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue全局指令文件?directives詳解

    vue全局指令文件?directives詳解

    全局指令是Vue.js中的一種自定義指令,可以在整個應(yīng)用中重復(fù)使用,通過Vue.directive方法定義,可以在組件內(nèi)部直接使用,指令有多個生命周期鉤子,可以接收參數(shù)和修飾符,提高代碼復(fù)用性和可維護性,本文介紹vue全局指令文件directives,感興趣的朋友一起看看吧
    2025-02-02
  • vue使用watch監(jiān)聽props的技巧分享

    vue使用watch監(jiān)聽props的技巧分享

    這篇文章主要為大家詳細(xì)介紹了vue使用watch監(jiān)聽props的一些小建議,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 如何利用VUE創(chuàng)建視頻流應(yīng)用

    如何利用VUE創(chuàng)建視頻流應(yīng)用

    這篇文章主要給大家介紹了關(guān)于如何利用VUE創(chuàng)建視頻流應(yīng)用的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-03-03
  • elementUI中MENU菜單踩坑

    elementUI中MENU菜單踩坑

    本文主要介紹了elementUI中MENU菜單踩坑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 前端Vue3最常用的?20?道面試題總結(jié)(含詳細(xì)解釋和代碼示例)

    前端Vue3最常用的?20?道面試題總結(jié)(含詳細(xì)解釋和代碼示例)

    Vue3作為當(dāng)前前端主流框架,其核心特性、底層原理及生態(tài)工具是面試中的高頻考點,這篇文章主要介紹了前端Vue3最常用的20道面試題(含詳細(xì)解釋和代碼示例)的相關(guān)資料,需要的朋友可以參考下
    2026-05-05
  • vue項目配置代理如何解決跨域問題

    vue項目配置代理如何解決跨域問題

    這篇文章主要介紹了vue項目配置代理如何解決跨域問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • vue+elementUI如何實現(xiàn)頂部路由標(biāo)簽跳轉(zhuǎn)

    vue+elementUI如何實現(xiàn)頂部路由標(biāo)簽跳轉(zhuǎn)

    這篇文章主要介紹了vue+elementUI如何實現(xiàn)頂部路由標(biāo)簽跳轉(zhuǎn)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Vue核心概念Getter的使用方法

    Vue核心概念Getter的使用方法

    今天小編就為大家分享一篇關(guān)于Vue核心概念Getter的使用方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 解決Antd 里面的select 選擇框聯(lián)動觸發(fā)的問題

    解決Antd 里面的select 選擇框聯(lián)動觸發(fā)的問題

    這篇文章主要介紹了解決Antd 里面的select 選擇框聯(lián)動觸發(fā)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 詳解Vue+ElementUI從零開始搭建自己的網(wǎng)站(一、環(huán)境搭建)

    詳解Vue+ElementUI從零開始搭建自己的網(wǎng)站(一、環(huán)境搭建)

    這篇文章主要介紹了Vue+ElementUI從零開始搭建自己的網(wǎng)站(一、環(huán)境搭建),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評論

蓬莱市| 余干县| 怀来县| 永和县| 西乌| 钟祥市| 襄汾县| 天全县| 鄂尔多斯市| 海城市| 韶山市| 镇远县| 成都市| 哈尔滨市| 郯城县| 苍溪县| 贞丰县| 墨竹工卡县| 永新县| 大渡口区| 黄骅市| 陵川县| 北川| 库车县| 临桂县| 隆安县| 通河县| 福海县| 荥经县| 即墨市| 历史| 佛冈县| 沛县| 秀山| 洪江市| 镇赉县| 广汉市| 武平县| 阿尔山市| 安康市| 白山市|