Nuxt3 初始化加载 models 快速开发秘诀,减少import model 声明
这半年公司要我们使用nuxt3来开发,虽然Nuxt 都靠定死的路径自动化,但是就是没做好一样东西,也就是自动models, 上网查了,竟然没有人问这问题?也找不到一个接近的样本,于是我花了有点时间探索最后被我发现一些秘诀,要load 所有的 models, 可以在 server/plugins/loadModels.js 那边靠 fs.readdir 来load 所有的 sequelize models
条件是:
- 需要用到 import, 和 .js 需换去 .mjs 才有效import 所有的 model mjs 文件,否则会报错。
- 请用 POST来判断,需要 useFetch method:POST 来读取资料,使用 POST也相对安全一些。
- import 得到的,必须打入对象 {}, 比如 const models = {}, 把 modelName 最为对象的 key, 比如 models[‘member’],过后每次查询就这样,const res = await models[‘member’].findAll() 就可以了。
- 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 协议》,转载必须注明作者和本文链接