【问题标题】:How to make method calls and v-shows work from outside Vue如何在 Vue 外部进行方法调用和 v-show 工作
【发布时间】:2022-01-03 11:56:44
【问题描述】:

我们正在使用 Vue.js 来实现弹出功能。 Vue App 中的“点击”按钮会正确启动弹窗,但是下面的例子 vueApp.methods.openModal() /// 从外部调用 当我从外部调用时,弹出窗口不会出现,尽管函数调用本身是可能的。为什么是这样?另外,像这样从 Vue 外部调用方法时,如何使 v-show 正常工作?

xxx.html

<div id="app">
  <button v-on:click="openModal">Click</button>
  <div id="dbg_overlay" v-show="showContent" v-on:click="closeModal">
    <div id="content"></div>
    <button v-on:click="closeModal">Close</button>
  </div>
</div>

xxx.js

const vueApp = {
  data() {
    return {
      showContent: false,
    }
  },
        
  methods: {
    openModal: function() {
      this.showContent = true
    },
    closeModal: function() {
      this.showContent = false
    }
  },  
};
      
Vue.createApp(lessonScheduleEdit).mount("#app");

vueApp.methods.openModal() /// call from outside

vue 我正在使用:

<script src="https://unpkg.com/vue@next"></script>

【问题讨论】:

    标签: javascript vue.js vuejs3


    【解决方案1】:

    您需要以下物品:

    1. 将您的 Vue 应用程序分配给一个变量,该变量在全局范围内的任何位置都可用。
    2. 一旦你使它可用,要调用在其methods 中定义为methodName 的方法,你必须直接调用它(例如:myVar.methodName()不是 myVar.methods.methodName() !!!)

    如何使变量全局可用:

    声明全局可用变量的最常用方法是使用window 对象:

    window.myVueApp = Vue.createApp(vueApp).mount("#app");
    
    // from anywhere else in the window:
    window.myVueApp.openModal();
    

    使变量全局可用的更现代的方法是使用window 的别名:globalThis

    globalThis.myVueApp = Vue.createApp(vueApp).mount('#app');
    
    // both of these will now work 
    // because, inside a browser, globalThis === window
    window.myVueApp.openModal();
    globalThis.myVueApp.openModal();
    

    注意:我可以使用globalThis吗?
    但是,即使 window 现在有了一个花哨的新别名,使用它也一样糟糕(请阅读下面的原因)。


    注意: 使用变量污染全局范围通常被认为是不好的做法,因为它存在名称冲突的风险(当两者您的代码和其他人的代码在同一页面上使用,不小心使用了相同的全局范围变量名称)。

    最终,这意味着,至少在理论上,您的代码是不可靠的(在某些情况下它可能会失败)。理想情况下,您希望编写牢不可破的代码,在任何时候都不会干扰(破坏)同一页面上运行的任何其他内容。

    为了最小化这种命名冲突的风险,您实际上可以将您的应用程序放在 Vue 命名空间中,该命名空间已经在全局范围内可用,因为我们已经知道 Vue 命名空间没有 myVueApp 属性(并且很可能其他人也会在您的页面上使用Vue.myVueApp 可以忽略不计):

    Vue.myVueApp = // ...your app here...
    

    看看它的工作原理:

    const vueApp = {
      data() {
        return {
          showContent: false,
        }
      },
            
      methods: {
        openModal: function() {
          this.showContent = true
        },
        closeModal: function() {
          this.showContent = false
        }
      },
    };
          
    Vue.myModeratelyAmazingVueApp = Vue.createApp(vueApp).mount("#app");
    <script src="https://unpkg.com/vue@next/dist/vue.global.prod.js"></script>
    <div id="app">
      <button @click="openModal">Click</button>
      <div id="dbg_overlay" v-show="showContent" @click="closeModal">
        <div id="content"></div>
        <button @click="closeModal">Close</button>
      </div>
    </div>
    
    <button onclick="Vue.myModeratelyAmazingVueApp.openModal()">external open</button>

    【讨论】:

    • 感谢您的代码,我能够实现我想要的。非常感谢你。我还要非常感谢您在编码方面的设计!
    【解决方案2】:

    最简单的方法是使用v-if 并检查您定义的值是否等于true。像这样:

    <div id="app">
      <button id="show-modal" @click="showModal = true">Show Modal</button>
      <modal v-if="showModal" @close="showModal = false"> 
        <!-- Your content in here -->
      </modal>
    </div>
    

    你也可以在你的方法中使用showModal = true,就像这样:

    methods: {
      clickModal() {   //just renamed in template it's @click="clickModal()"
        showModal = true;
      }
    }
    

    希望对您有所帮助!

    【讨论】:

    • 谢谢,我可以从 Vue 范围外调用它吗?我仍然不知道我该怎么做......
    猜你喜欢
    • 2020-05-15
    • 2018-01-07
    • 2017-07-20
    • 2022-07-12
    • 2018-05-30
    • 2010-10-25
    • 1970-01-01
    • 2016-10-06
    • 2020-12-20
    相关资源
    最近更新 更多