如何创建一个可以在渲染的 VueJS v3 应用程序中更新模型数据的窗口函数?

问题描述 投票:0回答:1

我有一个用例,要求我使用窗口级普通 JavaScript 函数才能刷新/更新已渲染的 Vue 应用程序内的数据。我无法真正使用 Vue 本身内部的任何异步进程或触发器,因为本质上这个应用程序将在类似于 iframe 的内部运行。

我遵循了 Vue 的入门指南,虽然我能够使用默认数据渲染我的简单表格,但从 Vue 外部调用时我无法让函数正常工作。我使用 tailwind 和 vite-single-file 将其编译成单页代码文件(所有这些都有效)。

我期望做的是运行一个函数在窗口中传递一些 JSON,***refreshData(json) ***,然后让 App.vue 中的 PerformRefresh 函数根据提供的数据更新模型数据。

我尝试过的代码看起来很简单:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test App</title>
    <script>
      function refreshData(newData) {
        app.performRefresh(newData);
      }
    </script>
  </head>
  <body class="m-0 p-0">
    <div id="app" class="w-full"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

main.ts

import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
window.app = app;
app.mount('#app')

应用程序.vue

<script setup lang="ts">
  import { ref } from 'vue'
  import data from './assets/defaultData.json'
  const tableData = ref(data)

  const performRefresh = (newData) => {
    console.log("Test Reactivity Function");
    tableData.test = newData;
  }

  window.performRefresh = performRefresh;
</script>

<template>
  <div class="px-4">
    <table class="w-full">
      <tr v-for="row in tableData.test">
# Standard model rendering with mustaches here
      </tr>
    </table>
  </div>
  <h1>TEST VALUE: {{ tableData.test }}</h1>
</template>

我尝试了多种不同的方法,但都以不同的失败结果告终。主要来自阅读 StackOverflow、Vue3 文档和在线其他类似主题的建议。

  1. 在vue中的hidden中设置一个watch()来观察字段值的变化,然后在refreshData()函数中使用js将newData粘贴到隐藏字段中。这不起作用(但如果我手动将 JSON 数据复制并粘贴到字段中,则可以起作用)。
  2. 尝试使用 Pinia 设置商店(vue 内部一切正常,但无法从窗口级别访问或定位)。
  3. 使用 Mitt 尝试不同的商店方法,解决与 Pinia 相同的问题。可以让 Mitt 在窗口级别和 vue 级别运行,但不同的商店不会相互通信。 https://www.npmjs.com/package/mitt
  4. 尝试使用 Vue Events 来监视窗口 DOM,但该事件永远不会触发。

我觉得我在这里遗漏了一些基本和明显的东西,但无法完全连接这些部分。感谢您花时间向 Vue 新手用户提出建议。

javascript vue.js dom-events vuejs3 vue-composition-api
1个回答
0
投票

您可以公开该方法(在Composition API中使用

defineExpose()
):

<script setup lang="ts">
  import { defineExpose } from 'vue'
  const performRefresh = (newData) => {...}
  defineExpose({performRefresh})
</script>

然后你可以通过

app
变量访问它:

app._instance.exposed.performRefresh(newData)

这是一个片段:

const { createApp, ref } = Vue;

const App = {
  template: `<div :style="{background: color, padding: '12px'}">colored div in Vue</div>`,
  expose: ['setColor'],
  setup(){
    const color = ref('yellow')
    const setColor = (colorString) => color.value = colorString
    return {color, setColor}
  },
}
window.app = createApp(App)
app.mount('#app')

window.updateColor = function(){
  const randomColor = '#' + Math.floor(Math.random()*16777215).toString(16);
  app._instance.exposed.setColor(randomColor)
}
<div id="app"></div>
<button onclick="updateColor()">tell Vue to update color</button>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.