Vue3中如何在自定义脚本中调用组件方法?

vue3 执行自定义脚本,自定义脚本中调用组件自身的方法,.call中传值proxy,但是无法获取getBoxByUID(), 报错提示“getBoxByUID is not defined”

const getBoxByUID = (pid) => {
    for (let key in itemRefs) {
        if (itemRefs[key].propsData.boxItem.pid == pid) return itemRefs[key]
    }
}
const { proxy } = getCurrentInstance()
const alarmChangedScript = () => {
    let scriptStr =
        "var alarm = getBoxByUID(1447428693).curHighestAlarm; var measObjName = '状态正常'; if (alarm != null) {measObjName = alarm.measObjectName}; getBoxByUID(1447428693).refreshData(measObjName);"
    new Function(scriptStr).call(proxy)
}

vue2中的写法如下


  getBoxByUID(id) {
    let curComponent;
    this.$children.forEach((childComponet: any) => {
      let boxItem = childComponet.$options.propsData.boxItem;
      if (boxItem.id === id) {
        curComponent = childComponet;
      }
    });
    return curComponent;
  }

  alarmChangedScript(scriptString) {
    // let scriptStr = "var alarm = this.getBoxByUID(-1004645418).curHighestAlarm;var measObjName = '暂无';var measZoneName = '暂无';if (alarm != null) {measObjName = alarm.measObjectName;measZoneName = alarm.regionName;}this.getBoxByUID(-1943778209).refreshData(measZoneName);this.getBoxByUID(-1360208550).refreshData(measObjName);"
    new Function(scriptString).call(this);

请问vue3中,哪个字段可以替代vue2中的this

阅读 1k
avatarAI BotBETA

在 Vue 3 中,由于引入了 Composition API 和 Proxy 对象来处理组件实例,你不能像在 Vue 2 中那样直接通过 this 来访问组件实例的方法和属性。在你的场景中,你需要通过 getCurrentInstance 获取的 proxy 对象来调用组件方法,但是直接在 new Function 中使用 getBoxByUID 函数会导致作用域问题,因为 getBoxByUID 并没有在 proxy 的上下文中定义。

解决方案

  1. 确保 getBoxByUID 函数在 proxy 的作用域中可用
    你可以将 getBoxByUID 函数定义为一个组件的 method 或者在 setup 函数中通过 expose 方法暴露出来(如果你在使用 <script setup>)。但是,由于你正在尝试在动态脚本中调用它,一个更简单的方法是将这个函数作为一个变量传递给 new Function 的作用域。
  2. 修改 alarmChangedScript 函数
    你需要将 getBoxByUID 函数作为一个参数传递给动态执行的脚本,或者将这个函数定义在脚本可以访问的作用域中。

下面是一个修改后的示例,展示了如何在 Vue 3 中实现这一点:

### 修改后的代码

<script setup>
import { getCurrentInstance, ref } from 'vue';

// 假设 itemRefs 是在组件的某个地方定义的响应式引用
const itemRefs = ref([]);

// 定义 getBoxByUID 函数
const getBoxByUID = (pid) => {

for (let key in itemRefs.value) {
    if (itemRefs.value[key].props.boxItem.pid == pid) return itemRefs.value[key];
}
return null;

}

const { proxy } = getCurrentInstance();

// 封装 alarmChangedScript 函数,将 getBoxByUID 作为参数传递
const alarmChangedScript = () => {

const scriptStr = `
    var getBoxByUIDFunc = arguments[0];
    var alarm = getBoxByUIDFunc(1447428693).curHighestAlarm; 
    var measObjName = '状态正常'; 
    if (alarm != null) {
        measObjName = alarm.measObjectName;
    }
    getBoxByUIDFunc(1447428693).refreshData(measObjName);
`;
new Function('getBoxByUIDFunc', scriptStr).call(proxy, getBoxByUID);

}

// 调用 alarmChangedScript
alarmChangedScript();
</script>


在这个修改后的示例中,`getBoxByUID` 函数被作为参数 `getBoxByUIDFunc` 传递给 `new Function`,这样它就可以在动态执行的脚本中正确访问了。同时,注意 `itemRefs.value` 用于访问响应式引用的当前值。
2 个回答

将 getBoxByUID 方法添加到 proxy 对象上,这样就可以在脚本中通过 this 调用。

import { getCurrentInstance } from 'vue';

export default {
  setup() {
    const { proxy } = getCurrentInstance();

    proxy.getBoxByUID = (pid) => {
      for (let key in proxy.itemRefs) {
        if (proxy.itemRefs[key].propsData.boxItem.pid == pid) return proxy.itemRefs[key];
      }
    };

    const alarmChangedScript = () => {
      let scriptStr =
        "var alarm = this.getBoxByUID(1447428693).curHighestAlarm; var measObjName = '状态正常'; if (alarm != null) {measObjName = alarm.measObjectName}; this.getBoxByUID(1447428693).refreshData(measObjName);";
      const dynamicFunction = new Function(scriptStr).call(proxy);
    };

    return {
      alarmChangedScript,
    };
  },
};

vue官网不推荐使用getCurrentInstance

<script lang="ts">
  import { defineComponent } from 'vue';

  function useSetup() {
    function getBoxByUID(pid: number) {
      return {
        curHighestAlarm: {
          measObjectName: 'measObjectName',
          regionName: 'regionName',
        },
        refreshData: (data: string) => {
          console.log(data);
        },
      };
    }

    return {
      getBoxByUID,
    };
  }

  export default defineComponent({
    setup() {
      const proxy = useSetup();
      let scriptStr = `var alarm = this.getBoxByUID(-1004645418).curHighestAlarm;
var measObjName = '暂无';
var measZoneName = '暂无';
if (alarm != null) {
    measObjName = alarm.measObjectName;
    measZoneName = alarm.regionName;
}
this.getBoxByUID(-1943778209).refreshData(measZoneName);
this.getBoxByUID(-1360208550).refreshData(measObjName);`;
      new Function(scriptStr).call(proxy);
    },
  })
</script>
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏