Vue/nuxt - 如何从子组件访问父级引用

2024-03-09

我有一个全局确认模式组件,已在我的默认布局文件中注册, 然后,我会尝试从 page/index.vue 访问它,但调用 this.$refs 只会返回一个空对象。将模式组件放在我的pages/index.vue 中会起作用,但它会破坏我的全局确认模式的目的。

布局/default.vue

<template lang="pug">
v-app(v-if="show")
  v-main
    transition
      nuxt
  confirm(ref='confirm')
</template>
<script>
import confirm from '~/components/confirm.vue'
export default {
  components: { confirm },
  data: () => ({
    show: false
  }),
  async created() {
    const isAuth = await this.$store.dispatch("checkAuth")
    if (!isAuth) return this.$router.push("/login")
    this.show = true
  }
}
</script>

组件/confirm.vue

<template>
  <v-dialog v-model="dialog" :max-width="options.width" @keydown.esc="cancel">
    <v-card>
      <v-toolbar dark :color="options.color" dense flat>
        <v-toolbar-title class="white--text">{{ title }}</v-toolbar-title>
      </v-toolbar>
      <v-card-text v-show="!!message">{{ message }}</v-card-text>
      <v-card-actions class="pt-0">
        <v-spacer></v-spacer>
        <v-btn color="primary darken-1" @click.native="agree">Yes</v-btn>
        <v-btn color="grey" @click.native="cancel">Cancel</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
<script>
  export default {
    data: () => ({
      dialog: false,
      resolve: null,
      reject: null,
      message: null,
      title: null,
      options: {
        color: 'primary',
        width: 290
      }
    }),
    methods: {
      open(title, message, options) {
        this.dialog = true
        this.title = title
        this.message = message
        this.options = Object.assign(this.options, options)
        return new Promise((resolve, reject) => {
          this.resolve = resolve
          this.reject = reject
        })
      },
      agree() {
        this.resolve(true)
        this.dialog = false
      },
      cancel() {
        this.resolve(false)
        this.dialog = false
      }
    }
  }
</script>

然后我想从我的pages/index.vue 中调用它(如果引用在这里,它会起作用,但我想要一个全局确认模式)

methods: {
    async openConfirm() {
      console.log("openConfirm")
       if (await this.$refs.confirm.open('Delete', 'Are you sure?', { color: 'red' })) {
         console.log('--yes')
       }else{
         console.log('--no')
       }
    },


简短的回答是:不要那样滥用 $ref 。最终,它只会导致反模式包裹着反模式。

与您要完成的确切任务相关的更详细的答案: 我现在已经在几个 Vue 项目中解决了同样的问题(全局的、基于承诺的确认对话框),到目前为止,这是非常有效的:

  1. 将确认对话框设置为其自己的独立“模块”,以便您可以使用两行将其添加到 main.js 中:
import ConfirmModule from './modules/confirm';
Vue.use(ConfirmModule);

(旁白:还有其他一些“全局模块化组件”,例如警报等......)

  1. 使用 JS 文件来编排设置过程、promise 管理和组件实例化。例如:
import vuetify from '@/plugins/vuetify';
import confirmDialog from './confirm-dialog.vue';

export default {
  install(Vue) {
    const $confirm = (title, text, options) => {
      const promise = new Promise((resolve, reject) => {
        try {
          let dlg = true;
          const props = {
            title, text, options, dlg,
          };
          const on = { };
          const comp = new Vue({
            vuetify,
            render: (h) => h(confirmDialog, { props, on }),
          });
          on.confirmed = (val) => {
            dlg = false;
            resolve(val);
            window.setTimeout(() => comp.$destroy(), 100);
          };

          comp.$mount();
          document.getElementById('app').appendChild(comp.$el);
        } catch (err) {
          reject(err);
        }
      });
      return promise;
    };

    Vue.prototype.$confirm = $confirm;
  },
};
  1. 将其安装到 Vue.prototype,这样您只需调用以下命令即可从应用程序中的任何组件使用它:this.$confirm(...)

  2. 当您构建 Vue 组件(confirm-dialog.vue)时,您只需要单向绑定标题、文本和选项的 props,将 dlg prop 单向绑定到对话框,或者通过使用 getter 和 setter 计算属性...无论哪种方式...

  3. 发出一个“已确认”事件true如果用户确认。因此,从confirm-dialog.vue组件中:this.$emit('confirmed', true);

  4. 如果他们关闭对话框,或者单击“否”,则发出 false,这样承诺就不会一直存在:this.$emit('confirmed', false);

  5. 现在,您可以从任何组件中使用它,如下所示:

methods: {
  confirmTheThing() {
    this.$confirm('Do the thing', 'Are you really sure?', { color: 'red' })
      .then(confirmed => {
        if (confirmed) {
          console.log('Well OK then!');
        } else {
          console.log('Eh, maybe next time...');
        }
      });
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue/nuxt - 如何从子组件访问父级引用 的相关文章

随机推荐

  • 安装的glimpse尝试访问glimpse.axd并收到404错误?

    这很简单 我在这个页面安装了glimpse http getglimpse com About QuickStart http getglimpse com About QuickStart 然后我尝试导航到http myApp glimp
  • 在 Hibernate 中映射多级继承

    目前我有这样的结构 A B C 它使用连接表与每个子类映射一个表 由于历史原因我也使用了判别器 所以目前的情况如下所述Hibernate 手册第 9 1 3 节 http www hibernate org hib docs v3 refe
  • Mvc ActionLink 与 JavaScript

    我正在使用 MVC 我有一个带有 ActionLink 的视图 它调用我的控制器的 Action 我的问题是当我想在该操作链接的 onClick 事件上调用 javascript 函数时 因为该操作链接转换为执行时间上的 html 标准标记
  • Chrome -> 检查元素 -> 网络 (XHR) -> 预览选项卡 (HTML) 问题

    我在网络部分的预览选项卡上遇到问题 返回 HTML 时 我在预览和响应中看到原始 HTML 有时 但极少数情况下 HTML 会在 预览 选项卡中正确呈现 是我做错了什么还是只是 Chrome 的一些错误 Thanks 我也在测试这个 对我来
  • 如何找到AVPlayer当前比特率

    我正在尝试获取 AVPlayer 播放视频流的比特率 我尝试过observed bit rate的财产AVPlayerItemAccessLogEvent 但它具有非常高的价值 经过进一步探索Observed bit rate财产 我了解该
  • 如何将 OpenCV Mat 划分为矩形子区域?

    我想划分一个简单的Mat 200x200 位于不同区域 10x10 我做了两个循环 然后创建了一个Rect我在其中指出每次迭代中我想要的变量 x y width height 最后 我将图像的该区域保存在vector of Mats 但我的
  • 如何每天自动备份Firestore数据库

    我想每天备份 Firestore 数据库 我的数据结构是这样的 usersCollection uid defaultCurrency USD name something dreamsCollection name image 我看过fi
  • 压倒一切!重要的风格

    标题几乎概括了这一点 外部样式表有以下代码 td EvenRow a display none important 我尝试过使用 element style display inline and element style display
  • NetworkStream 正在读取不应该存在的数据

    我在 NetworkStream 从套接字缓冲区读取不应该存在的数据时遇到问题 顺便说一句 我正在发送非常大的缓冲区 现在我刚刚在本地主机上进行测试 这是我读取数据的方式 前 4 个字节包含消息的长度 然后我只读取 4096 个块 直到达到
  • 如何配置 husky pre-push hook 来运行测试

    我正在尝试配置 husky 预推送挂钩以在推送之前运行测试 一切看起来都很好 跑完后git push origin钩子被触发并且测试正在运行 问题是 当测试完成后 即使操作成功 推送也会被冻结 并且没有其他事情发生 包 json scrip
  • SQL Server - 列顺序重要吗?

    在性能和优化方面 在 SQL Server 中构建表时 列的排列顺序重要吗 我的主键是第一列有什么关系吗 构建多字段索引时 列是否相邻有关系吗 Using ALTER TABLE syntax is it possible to speci
  • 正则表达式匹配 img 标签中的任何 url

    我需要一个可以匹配 img src 标签中任何 url 的正则表达式 URL 可以是 images temp jpg 或 temp1 jpg 甚至 http www example com temp jpg i 123 或其他任何内容 我写
  • 使用带参数的资源文件

    我的问题是关于 c 中的资源文件 resx 字符串 部分 我用它来存储我的消息 我想知道如何使用带参数的资源条目的 值 例子 名称 显示单元格值 值 单元格上的值 和行 是 我想填写 具有不同值的参数 谢谢你 您可以对资源文件中存储的字符串
  • 确保 Spring Quartz 作业执行不重叠

    我有一个 Java 程序 每 20 秒从 Spring Qquartz 执行一次 有时只需要几秒钟即可执行 但随着数据变大 我确信它会运行 20 秒或更长时间 当一个实例仍在执行时 如何防止 Quartz 触发 触发作业 解雇两个在数据库上
  • 在两个视图控制器之间进行 Segue

    在我的故事板 如上所示 上 我有一个 ViewController 它包含一个带注释的 MKMapView 这些注释包含一个公开图标 点击该图标时 应该将用户导航到另一个 ViewController 为此 我在视图控制器之间创建了一个推送
  • 有没有办法评估带有液体标签的字符串

    我需要提供页面内容参考列表 它应该包含页面上各部分的参考 我能看到的唯一方法是使用page content并解析它 但我偶然发现了数据评估的问题 例如我可以从page content site data sdk language SDK但没
  • Java 中比较版本字符串的有效方法[重复]

    这个问题在这里已经有答案了 可能的重复 如何比较 Java 中的两个版本字符串 https stackoverflow com questions 198431 how do you compare two version strings
  • Delphi解析xml文件

    首先 我对编码和 Delphi 很陌生 已经断断续续使用了几个月了 下面是一个示例 xml 文件 我想要实现的是解析 xml 文件的每个 名称 部分中的所有数据 我以前从未这样做过 一些指导将不胜感激 我在这里看过与此类似的其他问题 但我无
  • 在 Google Apps 脚本中异步运行函数

    我正在制作一个调用 GAS 函数的 Slack 机器人 一切正常 只是 Slack 显示错误消息 因为它在调用 API 时只等待 3 秒响应 任何人都可以帮助我弄清楚如何异步运行 everyDay2 以便我可以在完成之前返回响应 我尝试过
  • Vue/nuxt - 如何从子组件访问父级引用

    我有一个全局确认模式组件 已在我的默认布局文件中注册 然后 我会尝试从 page index vue 访问它 但调用 this refs 只会返回一个空对象 将模式组件放在我的pages index vue 中会起作用 但它会破坏我的全局确