yewanji 2024-07-16 22:52 采纳率: 36.3%
浏览 7
已结题

vue3 在自定义hooks 里面获取不到provide属性

我的项目采用的是electron+vue3 开发的客户端
首先,我在main.js 里面添加sqlite 数据库配置,并通过provide 将数据暴露给各大组件使用

import sqlite from 'sqlite3'
let databasePath = 'C:\\Users\\ywj\\Desktop\\note\\note.db'
let database = new sqlite.Database(databasePath)
app.provide('$db', database)

然后,在我的组件里面,我定义了一个hooks,目的是将一些功能进行抽离成公共方法

import {ref, inject} from 'vue'

export default function () {
  async function getConfig (configId) {
    const database = inject('$db')
    let config = await database.selectOneSync("select * from t_system_config where deleted='0' and configId=?", configId)
    return config?.configValue
  }
  
  function setConfig (configId, configValue) {
    const database = inject('$db')
    console.log('1223',database.insertSync)
    database.insertSync("insert into t_system_config(configId,configValue) values(?,?)", configId, configValue)
  }
  
  return {getConfig, setConfig}
}

然后我开始在我的组件里面使用这个hooks,发现watch 执行的时候报错了,

<script setup>
  import {ref, watch, inject, onMounted} from 'vue'
   watch(storePath,(newVal)=>{
    setConfig('STORE_PATH', newVal) //这里调用不行,当执行到 inject('$db') 是空的
  })
  onMounted(async () => {
    setConfig('STORE_PATH','1112') //这里调用可以,能正常获取到inject 
  })
</<script>
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-16 22:52
    关注

    引自免费微信小程序:皆我百晓生

    在你的情况中,你在自定义的hooks里面获取不到provide属性的问题可能是由于异步操作引起的。在Vue 3中,provideinject机制主要用于父子组件之间的依赖注入,但如果你在异步操作中尝试使用它们,可能会遇到问题。这是因为Vue的生命周期和异步操作的执行顺序可能并不总是按照你预期的方式进行。具体来说,当你调用自定义的hooks函数时,数据库连接可能还未完成初始化或者已经关闭,因此导致inject('$db')返回的是undefined或者无效的连接。此外,不同的地方执行环境和生命周期也可能有所不同,可能导致你遇到的问题。以下是一些可能的解决方案:

    首先,你可以尝试在初始化数据库和提供数据库对象时添加一些错误处理和检查机制,确保数据库连接在尝试使用之前已经成功建立。例如:

    import sqlite from 'sqlite3'
    let databasePath = 'C:\\Users\\ywj\\Desktop\\note\\note.db'
    let database = new sqlite.Database(databasePath, (err) => {
      if (err) {
        console.error('Failed to open database:', err);
        return; // 数据库连接失败的处理逻辑
      }
      app.provide('$db', database); // 确保数据库连接成功后再提供数据库对象
    });
    

    其次,你可以尝试在你的自定义hooks中直接引用数据库连接而不是使用inject('$db')。这可能可以解决在异步操作中由于数据库连接已经关闭导致的问题。这样做会使得你的自定义hooks函数依赖具体的数据库实例,可能涉及到更复杂的架构和模块拆分的问题。这只是一个思路上的尝试,需要根据你的实际项目结构进行考虑和调整。例如:

    export default function ({database}) { // 直接接收数据库实例作为参数
      // ... 其他代码 ...
    }
    

    最后,关于你在组件中使用这个hooks的问题,你可以尝试将setConfig函数的调用放在onMounted生命周期钩子中。这是因为在Vue组件的生命周期中,onMounted会在组件被挂载后立即执行,此时可以保证数据库连接已经成功建立并可以使用。同时,你也可以尝试在调用setConfig函数之前检查数据库连接是否有效。例如:

    <script setup>
      import {ref, onMounted, inject} from 'vue'
      onMounted(() => { // 将setConfig函数放在onMounted钩子中调用
        const database = inject('$db'); // 检查数据库连接是否有效
        if (database) { // 确保数据库连接存在并且有效再调用setConfig函数
          setConfig('STORE_PATH', storePath.value); 
        } else { 
          console.error('Failed to access database.'); 
        } 
      }) 
    </script>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 7月31日
  • 已采纳回答 7月23日
  • 创建了问题 7月16日

悬赏问题

  • ¥100 科大讯飞语音唤醒词,unbuntu环境,报错
  • ¥15 可以实现这个有不同背景颜色的九九乘法表吗?
  • ¥50 python写segy数据时出错2
  • ¥20 关于R studio 做精确稳定检验的问题!(语言-r语言)
  • ¥50 用贝叶斯决策方法,设计CAD程序
  • ¥20 关于#目标检测#的问题:(qq收集表到时间才能填写,填写的份数有上限)
  • ¥50 ZYNQ7020双核FLAHS烧写的问题
  • ¥20 ue 5 中想要实现第一人称人物左右行走摆动的效果,摄像头只向右摆动一次(关键词-结点)
  • ¥15 AD9164瞬时带宽1.8G,怎么计算出来?
  • ¥15 鼠标右键,撤销删除 复制 移动,要怎样删除? HKEY_CLASSES_ROOT*\shellex\ContextMenuHandlers 没用