Nuxt3 初始化加载 models 快速开发秘诀,减少import model 声明

这半年公司要我们使用nuxt3来开发,虽然Nuxt 都靠定死的路径自动化,但是就是没做好一样东西,也就是自动models, 上网查了,竟然没有人问这问题?也找不到一个接近的样本,于是我花了有点时间探索最后被我发现一些秘诀,要load 所有的 models, 可以在 server/plugins/loadModels.js 那边靠 fs.readdir 来load 所有的 sequelize models

条件是:

  1. 需要用到 import, 和 .js 需换去 .mjs 才有效import 所有的 model mjs 文件,否则会报错。
  2. 请用 POST来判断,需要 useFetch method:POST 来读取资料,使用 POST也相对安全一些。
  3. import 得到的,必须打入对象 {}, 比如 const models = {}, 把 modelName 最为对象的 key, 比如 models[‘member’],过后每次查询就这样,const res = await models[‘member’].findAll() 就可以了。
  4. pathToFileUR 这里的转换是为了支持windows 和 ios,否则 windows 会报错。

server/plugins/loadModels.js

import fs from 'fs/promises';
import path from 'path';
import { pathToFileURL } from 'url';
export default defineNitroPlugin((nitroApp) => {
    nitroApp.hooks.hook('request', async (event) => {
        const dir = 'data';
        const __dirname = path.resolve();
        const modelsDirectory = path.join(__dirname, 'models', dir);

        const models = {};
        const files = await fs.readdir(modelsDirectory);
        await Promise.all(
            files.map(async (file) => {
                const modelPath = path.join(modelsDirectory, file);
                const {href: importModelPath} = pathToFileURL(modelPath);
                const { sequelize } = await import(importModelPath);
                models = sequelize.models;
            })
        );
        // console.log("models", models);
        event.models = models;
    })
})

server/api/menu.post.js

export default defineEventHandler(async (event) => {
    const models = event.models;
    const model = models['menu'];
    const results = await model.findAll({
        attributes: ['id', 'iconName', 'link', 'title'],
        order: [
            ['ordering', 'ASC']
        ]
    });
    return {
        code: 200,
        msg: 'success',
        data: results
    }
})

components/menu.vue

const menus = ref([]);
sync function loadMenus(){
  try {
    const { data: response } = await useFetch(`/api/menu`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    if (response.value.code === 200) {
      menus.value = response.value.data;
    } else {
      console.error('Error: load menu error!');
    }
  } catch (error) {
    console.error('An error occurred while making the request:', error);
  }
}
await loadMenus();

models/data/menu.mjs

import { Model, DataTypes, Sequelize } from 'sequelize';
import { sequelize } from './database.mjs';

class Menu extends Model {
}

Menu.init({
    id: {
        field: 'MenuID_PK',
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true,
        comment: 'Menu ID',
    },
    iconName: {
        field: 'IconName',
        type: DataTypes.STRING(40),
        allowNull: false,
    },
    link: {
        field: 'Link',
        type: DataTypes.STRING(60),
        allowNull: false,
    },
    title: {
        field: 'Title',
        type: DataTypes.STRING(60),
        allowNull: false,
    },
    ordering: {
        field: 'Ordering',
        type: DataTypes.DECIMAL(6, 2),
        allowNull: false,
    },
    createdAt: {
        field: 'CreatedAt',
        type: DataTypes.DATE,
        defaultValue: Sequelize.literal('NOW()'),
    },
    updatedAt: {
        field: 'UpdatedAt',
        type: DataTypes.DATE,
        defaultValue: Sequelize.literal('NOW()'),
    },
}, {
    sequelize,
    modelName: 'menu',
    tableName: 'menus',
    timestamps: false,
});
export { Menu, sequelize };
本作品采用《CC 协议》,转载必须注明作者和本文链接
全栈程序员(Blockchain, Web3, Nuxt3+, vue3+, React18+, PHP, MySQL, HTML, CSS, JavaScrIpt/JQuery)
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!