невозможно ли вызвать функцию vue js из Android webview?

#javascript #android #vue.js

#javascript #Android #vue.js

Вопрос:

Я знаю, что этот вопрос существует на многих сайтах, поэтому я следил за этими ответами, но теперь работал. Итак, я задаю этот вопрос, я использую vuejs, используя typescript, и webview в Android. Что я хочу сделать, так это то, что сначала, когда я нажимаю кнопку в приложении Android, затем вызываю функцию vuejs. И второй — это вызов из js на Android. Но оба не работают. Я проверил все возможные решения, но у меня не работает. пожалуйста, дайте мне знать, как это решить. Я добавил коды. URL-адрес указан правильно, и я вижу страницу в webview, на которую перенаправляется Home «http://url /»

Home js

 <template>
  <div class="home">
        <h1>This is an Home page</h1>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
    name: 'Home',
    methods:{
      getAlert(){
        alert(11111);        
      },
      getWebViewAlert(toast:String){
        android.showToast(toast);
      }

    }
})
interface WebAppInterface{  // eslint-disable-line no-unused-vars
  showToast(toast: String) : void;
}

declare var android: WebAppInterface;// eslint-disable-line no-unused-vars

</script>

 

MainActivity.kt

     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val webviewSetting = binding.webview.settings
        webviewSetting.javaScriptEnabled = true
        webviewSetting.setSupportMultipleWindows(false)
        webviewSetting.javaScriptCanOpenWindowsAutomatically = false
        webviewSetting.loadWithOverviewMode = true
        webviewSetting.useWideViewPort = true
        webviewSetting.setSupportZoom(false)
        webviewSetting.builtInZoomControls = false
        webviewSetting.layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL
        webviewSetting.cacheMode = WebSettings.LOAD_NO_CACHE
        webviewSetting.domStorageEnabled =true
        binding.webview.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView, url: String) {
                binding.webview.loadUrl("javascript:getAlert()")
            }
        }
        binding.webview.webChromeClient = WebChromeClient()
        //binding.webview.addJavascriptInterface(WebAppInterface(this),"android")
        binding.webview.loadUrl(url)

        binding.button.setOnClickListener {
            binding.webview.loadUrl("javascript:getAlert()")
        }
    }

class WebAppInterface internal constructor(c: Context) {
    var mContext: Context
    @JavascriptInterface
    fun showToast(toast: String) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show()
    }
    init {
        mContext = c
    }
}
 

Ошибка в android studio

 I/chromium: [INFO:CONSOLE(1)] "Uncaught ReferenceError: getAlert is not defined", source: url (1)
 

обновленный код

 import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'

Vue.config.productionTip = false
let HomeVue; // eslint-disable-line no-unused-vars
new Vue({
  router,
  store,
  vuetify,
  mounted(){
    HomeVue = this
  },
  methods:{
    getAlert(){
      return this;
    }

  },
  render: h => h(App)
}).$mount('#app')
 

Комментарии:

1. Это не невозможно, но методы экземпляра Vue недоступны в глобальной области, так же как глобальная область недоступна в экземпляре <template> . Вы можете назначить экземпляр константе в глобальной области видимости, а затем вы можете взаимодействовать с любым из его свойств или методов.

2. есть ли какой-нибудь пример? для меня это было бы более эффективно?

3. Я добавил, чтобы сделать окно изменяемым, но в нем есть ошибка. это правильный путь?

4. Я предполагаю, что вам нужно будет включить свой var mContext , но я недостаточно знаю о webview и Android.

Ответ №1:

Возможно, вы слишком поздно присоединились к обсуждению. Вы можете смонтировать приложение и попытаться получить к нему доступ из своего кода Android webview

     const resumeApp = Vue.createApp({
  data() {
    return {
      resume: {
        ...resumeEN,
        address: [resumeEN.country, resumeEN.city, resumeEN.postalCode]
          .filter(Boolean)
          .join(", "),
        lang: lang,
      },
    };
  },
  methods: {
    changeLang: function (lang) {
      this.resume = resumeEN;
    },

    renderResumeDocument: function (jsonData) {
      this.resume = jsonData;
    },
  },
});

var mobileAppProxyObj = resumeApp.mount("#app");
 

Из вашего веб-просмотра Android

   resumeViewerBinding.webViewResumeViewer.webViewClient = object : WebViewClient() {
            override fun onPageFinished(view: WebView?, weburl: String?) {
                resumeViewerBinding.webViewResumeViewer.loadUrl("javascript:mobileAppProxyObj.renderResumeDocument('Javascript function in webview')")
            }
        }
 

Ответ №2:

Вероятно, проблема в TypeScript. Просто придерживайтесь ES5 и попробуйте еще раз.

Кроме того, вы загрузили среду выполнения Vue JS в НАЧАЛО вашего HTML?

Редактировать: вы должны включить Vue JS в свой index.html … Обратитесь к этому: (обратите внимание на тег script внутри раздела head>

https://github.com/vuejs/vuejs.org/blob/master/src/v2/examples/vue-20-hello-world/index.html

 <!DOCTYPE html>
<html>
<head>
  <title>My first Vue app</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    {{ message }}
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue!'
      }
    })
  </script>
</body>
</html>
 

Комментарии:

1. Я не понимаю вашего ответа, потому что я новичок в javascript. как проверить ваш ответ? и как придерживаться es5?

2. Существует стандартная версия Javascript (ES5), которая поддерживается большинством браузеров. Существует более новая версия Javascript (ES6), которая имеет меньшую поддержку. И есть альтернативная версия Javascript под названием TypeScript, которая представляет собой совсем другое дело. Кажется, вы пытаетесь использовать typescript (ts), потому что я вижу «<script lang=»ts»>»

3. @Charles Я должен сказать, что ваш код выглядит так, как будто вы используете файл «.vue», который является одностраничным компонентом Vue. Вы скомпилировали код и использовали распространяемый app.js файл в формате HTML?

4. Одностраничные компоненты «.vue» не являются обязательными в Vue. Вы можете просто включить скрипт Vue в HTML и продолжить. Также смотрите: medium.com/javascript-in-plain-english /…