[English](./README.md) | 简体中文

# @ray-js/webview-invoke

> WebviewInvoke 是一款跨多平台的和Webview进行通信的中间件。可以在ray 平台上，小程序平台上，ReactNative 平台上来进行和Webview的通信

## 安装

```sh
$ npm install @ray-js/webview-invoke
// 或者
$ yarn add @ray-js/webview-invoke
```

## 使用

### 在Ray 项目中使用
<!--START_SECTION:txp-usage-->

小程序视图层
</br>

```xml
<web-view src="{{src}}" id="{{ webviewId }}" bind:message="onMessage" bind:load="onLoadEnd" bind:error="onError"></web-view>
```

小程序逻辑层
```js
const componentOptions = {
   properties: {
    src: { type: String },
    webviewId: { type: String },
  },
  data: {},
  observers: {},
  lifetimes: {
    ready() {
      this.bindWebViewInvoke();
      this.defineCallbacks();
      this.bindFunctions();
    },
  },
  methods: {
    onLoadEnd() {
       // 这里模拟发送数据到WebView中
      setTimeout(() => {
        this.postBundleBinaryWEB({
          key: 'file',
          id: 'file',
          bundle: 'bundle',
          index: 1,
          total: 10,
        });
      }, 3000);
    },
    /**
     * 创建webviewContext 对象并和invoke进行绑定
     */
    bindWebViewInvoke() {
      if (ty.createWebviewContext) {
        this.webviewContext = ty.createWebviewContext(this.data.webviewId);
        /**
         * 给webviewContext 注入platform 属性
         */
        Object.defineProperty(this.webviewContext, 'platform', {
          value: 'mini',
          writable: false,
        });
        this.invoke = createInvoke(() => this.webviewContext);
      }
    },
    /**
     * 创建定义的回调函数,可以把数据从WebView中, 把数据抛出来
     */
    defineCallbacks() {
      if (this.invoke) {
        this.invoke.define('onLoggerInfo', this.onLoggerInfo);
      }
    },
    /**
     * 定义从逻辑层，把数据抛到WebView中的指定方法里
     */
    bindFunctions() {
      if (this.invoke) {
        this.postBundleBinaryWEB = this.invoke.bind('postBundleBinary');
      }
    },
    // 这里接受来自WebView的消息
    onMessage(evt) {
      if (this.invoke) {
        this.invoke.listener(evt);
      }
    },
    // WebView加载失败
    onError() {},
    /**
     * 以下方法都是绑定小程序原生组件和ray组件之间的通信
     * @param {*} data
     */
    onLoggerInfo(data) {
      this.triggerEvent('onLoggerInfo'.toLowerCase(), data);
    },
  }
};
Component(componentOptions);
```


Ray组件中使用小程序的组件进行混合开发
```tsx
import React, { useState, useEffect, useCallback, useRef } from 'react';
// 这个是你的小程序组件
import WebView from '../webview';

interface IProps {}
const MapView: React.FC<IProps> = props => {
  const webviewId: any = useRef(`webviewId_${new Date().getTime()}`).current;

  const onLoggerInfo = (data: any) => {
    console.log('收到了来自WebView中回调过来的数据',data);
  };

  const onEvent = useCallback((evt: { type: string; detail: any}) => {
    const { detail } = evt;
    switch (evt.type) {
      case 'onLoggerInfo'.toLowerCase():
        onLoggerInfo(detail);
        break;
    }
  }, []);

  return (
    <View>
      <WebView
        //这里是你的服务地址，也可以换成本地文件
        src="http://172.20.10.3:3000?mode=debugger"
        webviewId={webviewId}
        // 这里不同的ray版本的写法可能有点不同
        bindonloggerinfo={onEvent}
        />
    </View>
  )
} 

```
<!--END_SECTION:txp-usage-->