Как включить кнопку "Назад" при использовании WebView в Nativescript-Vue

Я начинающий разработчик nativescript-vue. В настоящее время я реализую код на стороне Android, и мне удалось вставить WebView. Однако, если я коснулся физической кнопки "Назад" на моем телефоне, приложение было немедленно прекращено. Когда я использую WebView в Nativescript-Vue, когда я касаюсь кнопки "Назад", я хочу знать, как вернуться без конца.

Я попробовал следующую ссылку. Однако возникает ошибка. Веб-браузер Nativescript и кнопка возврата Android

Отличается ли он от кода NativeScript и кода NativeScript Vue? Я даже не замечаю разницы между двумя выше. Пожалуйста, помогите мне.

/app/components/App.vue

<template>
    <Page actionBarHidden="true">
        <FlexboxLayout>
            <WebView src="http://example.com" />
        </FlexboxLayout>
    </Page>
</template>

<script >

</script>

<style scoped>
</style>

/app/main.js

import Vue from 'nativescript-vue'
import App from './components/App'
import VueDevtools from 'nativescript-vue-devtools'
import { AndroidApplication, AndroidActivityBackPressedEventData } from "application";
import * as application from "application";
import {WebView} from "tns-core-modules/ui/web-view";
var webView = new WebView();
application.android.on(AndroidApplication.activityBackPressedEvent, (AndroidActivityBackPressedEventData) => {
  AndroidActivityBackPressedEventData.cancel = true; // prevents default back button behavior
  webView.canGoBack = true;
  console.log('back')

  // console.log("webview can go back "+this.webView.canGoBack);
  // if (webView.canGoBack) //if webview can go back
  //   webView.goBack();
  // else
  //   this.router.backToPreviousPage();
});

if(TNS_ENV !== 'production') {
  Vue.use(VueDevtools)
}

// Prints Vue logs when --env.production is *NOT* set while building
Vue.config.silent = (TNS_ENV === 'production')

new Vue({
  render: h => h('frame', [h(App)])
}).$start()

Сообщение об ошибке

An uncaught Exception occurred on "main" thread.
com.tns.NativeScriptException: 
Calling js method onBackPressed failed

TypeError: Cannot set property canGoBack of [object Object] which has only a getter
File: "file:///data/data/io.bagstation.bagstation/files/app/bundle.js, line: 375, column: 20

StackTrace: 
    Frame: function:'module.exports../main.js.application__WEBPACK_IMPORTED_MODULE_3__.android.on.AndroidActivityBackPressedEventData', file:'file:///data/data/io.bagstation.bagstation/files/app/bundle.js', line: 375, column: 21
    Frame: function:'Observable.notify', file:'file:///data/data/io.bagstation.bagstation/files/app/vendor.js', line: 41320, column: 15
    Frame: function:'ActivityCallbacksImplementation.onBackPressed', file:'file:///data/data/io.bagstation.bagstation/files/app/vendor.js', line: 63019, column: 25
    Frame: function:'NativeScriptActivity.onBackPressed', file:'file:///data/data/io.bagstation.bagstation/files/app/vendor.js', line: 60331, column: 21


    at com.tns.Runtime.callJSMethodNative(Native Method)
    at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1116)
    at com.tns.Runtime.callJSMethodImpl(Runtime.java:996)
    at com.tns.Runtime.callJSMethod(Runtime.java:983)
    at com.tns.Runtime.callJSMethod(Runtime.java:967)
    at com.tns.Runtime.callJSMethod(Runtime.java:959)
    at com.tns.NativeScriptActivity.onBackPressed(NativeScriptActivity.java:50)
    at android.app.Activity.onKeyUp(Activity.java:3049)
    at android.view.KeyEvent.dispatch(KeyEvent.java:2723)
    at android.support.v4.view.KeyEventDispatcher.activitySuperDispatchKeyEventPre28(KeyEventDispatcher.java:137)
    at android.support.v4.view.KeyEventDispatcher.dispatchKeyEvent(KeyEventDispatcher.java:87)
    at android.support.v4.app.SupportActivity.dispatchKeyEvent(ComponentActivity.java:126)
    at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:535)
    at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:59)
    at android.support.v7.app.AppCompatDelegateImpl$AppCompatWindowCallback.dispatchKeyEvent(AppCompatDelegateImpl.java:2533)
    at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:357)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4798)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4670)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4205)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4258)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4224)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4351)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4232)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4408)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4205)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4258)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4224)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4232)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4205)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4258)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4224)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4384)
    at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4552)
    at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2454)
    at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2017)
    at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2008)
    at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2431)
    at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:325)
    at android.os.Looper.loop(Looper.java:142)
    at android.app.ActivityThread.main(ActivityThread.java:6650)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:818)

Я не знаю, куда поместить мой файл, если вы просто напишите код. Буду признателен, если вы напишите имя файла вместе!

Большое спасибо.

1 ответ

Я столкнулся с абсолютно идентичной проблемой и долго не мог ее решить. + абсолютно нигде не написано (по крайней мере я не нашел) как получить доступ к нативным компонентам, минуя vue компоненты. В частности через исх.

Возможно, моя версия имеет костыль в себе. Но он работает.

webpack.config.js В нем я добавил псевдоним к ядру нативного скрипта. Не спрашивайте, я не понимаю, почему это работает. И почему если я не сделаю этот алиас - он не будет работать. Это похоже на какое-то волшебство.

      const webpack = require("@nativescript/webpack");

module.exports = (env) => {
webpack.init(env);

webpack.chainWebpack(config => {
    config.resolve.alias.set('tns-core-modules', '@nativescript/core')
})

return webpack.resolveConfig();
};

в AndroidManifest.xml в разделе приложения я добавил android:usesCleartextTraffic="true" — это нужно для того, чтобы webview мог обращаться к ресурсам, не являющимся https

ну осталось только добавить одну маленькую деталь в компонент vue

      <template>
  <Page actionBarHidden="true">
    <GridLayout>
      <WebView ref="test" src="paste link here or in vars "/>
    </GridLayout>
  </Page>
</template>

<script>
const application = require("tns-core-modules/application");


export default {
  computed: {
    message() {
      return "Blank {N}-Vue app";
    },

  },

  mounted() {
    let self = this
    application.android.on(application.AndroidApplication.activityBackPressedEvent, function (args) {
      console.log("Event: " + args.eventName + ", Activity: " + args.activity);
      args.cancel = true; // to cancel back navigation and do something custom.
      if (self.$refs.test.nativeView.canGoBack) //if webview can go back
        self.$refs.test.nativeView.goBack();

    });
  }

ну, это почти все, что я сделал.

Другие вопросы по тегам