最近开发一个项目,原本是用的RN开发,后来打算三端统一,后来决定用VUE开发,所以涉及到一些Vue和原生交互的地方,做一下笔记~~

 

先直接上Vue代码

<template>
  <div class="page-box">
    <div class="page-content">
        <div class="page-bg">
          <div class="page-login-head">
            <img class="head-img" src="./images/head.png"/>
            <div class="head-text" @click="goLogin">
              {{userMsg}}
            </div>
          </div>
        </div>
        <!-- 我的账单 -->
        <div class="mine-item mine-item-head" @click="gotoBill">
          <div class="mine-item-content mine-item-content-bottom">
            <div class="left">
              <img class="item-img-size" src="./images/bill.png"/>
              <span class="item-text">我的账单</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
        <!-- 我的银行卡 -->
        <div class="mine-item">
          <div class="mine-item-content">
            <div class="left">
              <img src="./images/bankcard.png" style="width:5vw; height:4.1vw"/>
              <span class="item-text">我的银行卡</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
        <!-- 更改交易密码 -->
        <div class="mine-item mine-item-head">
          <div class="mine-item-content mine-item-content-bottom">
            <div class="left">
              <img class="item-img-size" src="./images/change_psw.png"/>
              <span class="item-text">更改交易密码</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
        <!-- 意见与反馈 -->
        <div class="mine-item" @click="gotoFeedback">
          <div class="mine-item-content mine-item-content-bottom">
            <div class="left">
              <img style="width:4.8vw; height:5vw" src="./images/opinion.png"/>
              <span class="item-text">意见与反馈</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
        <!-- 帮助中心 -->
        <div class="mine-item" @click="gotoHelpCenter">
          <div class="mine-item-content mine-item-content-bottom">
            <div class="left">
              <img style="width:5vw; height:5vw" src="./images/help.png"/>
              <span class="item-text">帮助中心</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
        <!-- 免责声明 -->
        <div class="mine-item" @click="ocrtest">
          <div class="mine-item-content">
            <div class="left">
              <img style="width:5vw; height:5vw" src="./images/exemption.png"/>
              <span class="item-text">免责声明</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
        <!-- 关于我们 -->
        <div class="mine-item mine-item-head" @click="gotoAboutUs">
          <div class="mine-item-content">
            <div class="left">
              <img style="width:5vw; height:5vw" src="./images/about.png"/>
              <span class="item-text">关于我们</span>
            </div>
            <span class="icon-right"></span>
          </div>
        </div>
      </div>
      <TabBar></TabBar>
  </div>
</template>

<script>
import TabBar from '@/components/tabBar/TabBar'
import { mapGetters } from 'vuex'
export default {
  components: { TabBar },
  data () {
    return {
      userMsg: '登陆/注册'
    }
  },
  mounted () {
    this.initView()
  },
  methods: {
    initView () {
      if (this.ifLogin) {
        this.userMsg = this.userInfo.cellphone
      } else {
        this.userMsg = '登陆/注册'
      }
    },
    goLogin () {
      if (!this.ifLogin) {
        this.$bridge.push({ name: 'login' })
      }
    },
    gotoAboutUs () {
      let params = {
        jumpUrl: 'http://192.168.1.38:8080/aboutus',
        title: '关于我们'
      }
      window.android.callAndroid(JSON.stringify(params))
    },
    gotoFeedback () {
      this.$bridge.push({ name: 'feedback' })
    },
    gotoHelpCenter () {
      this.$bridge.push({ name: 'helpcenter' })
    },
    gotoBill () {
      this.$bridge.push({ name: 'bill' })
    },
    ocrtest () {
      let params = {
        jumpUrl: 'http://192.168.1.38:8080/userinfo',
        title: 'ORC调试'
      }
      window.android.callAndroid(JSON.stringify(params))
    }
  },
  computed: {
    ...mapGetters(['userInfo', 'ifLogin'])
  }
}
</script>

<style lang="stylus" scoped>
  .page-box { position: relative; min-height: 100%; background: #F5F5F5}
  .page-content {
    position: relative;
    z-index: 0;
    padding-bottom :190px;
  }
  .page-bg {
    width: 100%; height: 380px;
    background: linear-gradient(32deg,rgba(46,42,50,1) 0%,rgba(78,65,80,1) 100%);
    display :flex;
    justify-content :center;
    align-items :center;
  }
  .page-box .page-bg .page-login-head {
    display :flex;
    flex-direction :column;
    align-items :center;
  }
  .page-box .page-bg .page-login-head .head-img {
    width: 124px; height: 124px;
  }
  .page-box .page-bg .page-login-head .head-text{
    margin-top :15px;
    font-size :28px;
    color :#FFFFFF;
  }
  .mine-item-head {
    margin-top :20px;
  }
  .mine-item {
    background-color :#FFFFFF;
    height :100px;
    width :100%
    padding-left :39px;
  }
  .mine-item .mine-item-content-bottom {
    border-bottom-width :1px;
    border-style :solid;
    border-bottom-color :#DDDDDD;
  }
  .mine-item .mine-item-content {
    display :flex;
    height :100px;
    width :100%
    align-items :center;
    justify-content :space-between;
  }
  .mine-item .left{
    display :flex;
  }
  .item-text {
    font-size :28px;
    color :#333333;
    margin-left :20px;
    align-self :center;
  }
  .item-img-size {
    width :31px;
    height :38px;
  }

  .icon-right {
    width: 36px; height: 36px;
    background: url('./images/arrow_grey_right.png') no-repeat center center;
    background-size: 19px 34px;
    margin-right :30px;
  }
</style>

这是一个个人中心完整VUE界面的代码,包括样式,点击事件,重点看这里就行

vue和原生交互的原理和Html里面js和原生交互一样,都是通过js代码来实现,都需要把原生方法挂载到window上面

所以这里,这里的params是需要传递给原生的数据,JSON.stringify(params)的作用是,必须把数据转为json格式,原生才能收到,否则接收不到,其中callAndroid()是原生的方法,window后面的android是原生代码里面申明的一个标志

原生代码如下


public class JsBridgeForMain {
    private static final String TAG = "JsBridgeForMain";
    private Handler deliver = new Handler(Looper.getMainLooper());
    private AgentWeb agent;
    private Context context;

    private OnNativeDataGetInterface mOnNativeDataGetInterface;

    public JsBridgeForMain(AgentWeb agent, Context context) {
        this.agent = agent;
        this.context = context;
    }

    public JsBridgeForMain(AgentWeb agent, Context context, OnNativeDataGetInterface onNativeDataGetInterface) {
        this.agent = agent;
        this.context = context;
        mOnNativeDataGetInterface = onNativeDataGetInterface;
    }

    @JavascriptInterface
    public void showMsg(final String obj) {
        Log.e(TAG, "showMsg: " + obj);
    }

    @JavascriptInterface
    public void jumpAndroid(final String obj) {
        Log.e(TAG, "jumpAndroid: " + obj);
        final Map<String, Object> params = AppUtils.getMap(obj);
        assert params != null;
        context.startActivity(new Intent(context, OcrCallbackActivity.class)
                .putExtra(PrefKeys.EXTRA_URL, params.get("href").toString()));
    }

    @JavascriptInterface
    public void callAndroid(final String obj) {
        deliver.post(new Runnable() {
            @Override
            public void run() {
                final Map<String, Object> params = AppUtils.getMap(obj);
                assert params != null;
                Log.e(TAG, "name: " + params);
                if ("OCR".equals(params.get("name"))) {
                    Gson gson = new Gson();
                    String jsonString = gson.toJson(params.get("data")).replace("\\", "");
                    jsonString = jsonString.substring(1, jsonString.length() - 1);
                    OcrEntity ocrEntity = gson.fromJson(jsonString, OcrEntity.class);
                    OcrCallbackActivity.msgId = params.get("msgId").toString();
                    if (mOnNativeDataGetInterface != null)
                        mOnNativeDataGetInterface.onDataGot(ocrEntity);
                    Log.e(TAG, "ocrEntity: " + params);
                }
                if ("phoneContact".equals(params.get("name"))) {
                    OcrCallbackActivity.msgId = params.get("msgId").toString();
                    mOnNativeDataGetInterface.onAddressCalled();
                }
                if ("GPS".equals(params.get("name"))){
                    OcrCallbackActivity.msgId = params.get("msgId").toString();
                    mOnNativeDataGetInterface.onGpsCalled();
                }
                if ("GPSStatus".equals(params.get("name"))){
                    OcrCallbackActivity.msgId = params.get("msgId").toString();
                    mOnNativeDataGetInterface.onGpsStatus();
                }
            }
        });
    }
}

其中原生调用JS方法代码如下

 Map<String, String> contactMap = new HashMap<>();
                contactMap.clear();
                contactMap.put("phone", phoneNum);
                contactMap.put("msgId", msgId);
                contactMap.put("name", contactName);
                Gson gson = new Gson();
                String contactPersonData = gson.toJson(contactMap);
                agentWeb.getJsAccessEntrace().quickCallJs("webViewBridge.callback_('" + contactPersonData + "')");

我使用的一个webview的中间件名字叫做AgentWeb,具体使用方法可以看github,

这里的

webViewBridge.callback_('" + contactPersonData + "')" 为js中的方法,contactPersonData 为原生的json数据

webViewBridge.callback_是我们自己封装的一个vue的连接桥可以忽略也可以吧这部分直接改成js里具体的方法比如前面vue代码中method里面的任意一个方法

 

 

Logo

前往低代码交流专区

更多推荐