1.配置amis页面和web应用菜单的关联关系
最终生成的json如下
[
{
"path": "/develop",//顶部导航栏
"title": "开发中心",
"icon": "md-code-working",
"hideSider": false,
"name": "develop",
"children": [
{
"path": "/develop/datamodel", //侧边栏-目录
"icon": "ios-barcode",
"title": "数据表模型",
"header": "develop",
"children": [
{
"path": "/develop/modelclass",//侧边栏-菜单
"icon": "ios-list-box-outline",
"title": "表模型分类",
"nodeKey": 36,
"meta": {
"auth": true,
"mclass": "base",
"template": "base.modelclass", //绑定的amis页面
"type": "pagetpl",
"iframe": "",
"component": "",
"closable": true
},
"selected": true,
"component": "default/default.tpl",
"name": "develop-modelclass",
"auth": [
"admin",
"superadmin"
],
"nodeClass": "sider",
"target": "_self",
"hideSider": false,
"headerDropdown": false,
"menu": {
"enable": true,
"header": true
},
"divided": false,
"childAddDisabled": true
},
{
"path": "/develop/model",
"icon": "md-menu",
"title": "表模型管理",
"nodeKey": 37,
"meta": {
"auth": true,
"mclass": "base",
"template": "base.modelinfo",
"type": "pagetpl",
"iframe": "",
"component": "",
"closable": true
},
"component": "default/default.tpl",
"selected": false,
"name": "develop-modelinfo",
"auth": [
"admin",
"superadmin"
],
"nodeClass": "sider",
"target": "_self",
"hideSider": false,
"headerDropdown": false,
"menu": {
"enable": true,
"header": true
},
"divided": false,
"childAddDisabled": true
}
],
"nodeKey": 35,
"meta": {
"auth": true,
"type": "folder",
"iframe": "",
"component": "",
"closable": true
},
"selected": false,
"expand": true,
"name": "develop-model",
"nodeClass": "folder",
"target": "_self",
"hideSider": false,
"headerDropdown": false,
"menu": {
"enable": true
},
"divided": false
},
],
"nodeKey": 34,
"expand": true,
"meta": {
"auth": true,
"mclass": "",
"template": "",
"type": "pagetpl",
"iframe": "",
"component": "",
"closable": true
},
"selected": false,
"redirect": "develop-page.pagetemplate",
"headerDropdown": false,
"nodeClass": "header",
"target": "_self",
"menu": {
"enable": true
}
}
]
2.根据关联关系生成动态路由
libs/util.js:
export const getRouterByAppMenu = (list, level) => {
let routers = [];
forEach(list, item => {
let r = {};
item.meta = item.meta || {};
// let mPath = item.path.split("/");
item.meta.auth = (item.auth && item.auth.length>0) ? true : false; //auth为[]时,不需要权限
r = {
// mpath: mPath[mPath.length - 1],
path: item.path,
name: item.name,
meta: item.meta,
}
r.meta.title = item.title || '';
r.meta.notCache = true;
r.meta.actions = item.actions;
r.meta.menu = item.menu;
if (item.redirect) {
r.redirect = { name: item.redirect };
}
if (item.children && item.children.length > 0) {
r.component = vueCompontent[level];
r.children = getRouterByAppMenu(item.children, level + 1);
}
else {
r.component = resolve => require([`@/pages/${item.component || 'default/default.tpl'}.vue`], resolve);
// r.meta.template = r.meta.template || 'none.initpage';
}
routers.push(r);
})
return routers;
}
router/index.js(动态路由)核心代码如下:
import Vue from 'vue';
import VueRouter from 'vue-router';
import util, { getRouterByAppMenu } from '@/libs/util'
import Setting from '@/setting';
import store from '@/store/index';
import routes from './routes';// 路由数据
import { loadApplicationMenu } from "../services/appmenu";
Vue.use(VueRouter);
const router = new VueRouter({
routes,
mode: Setting.routerMode,
base: Setting.routerBase
});
(async () => {
/**
* 路由拦截,权限验证
*/
let app = await loadApplicationMenu(appname); //调用接口获取web应用信息
let ROUTERS = getRouterByAppMenu(app.menu, 0); //封装配置的menu为routes
for (let i in ROUTERS) {
let mRouter = ROUTERS[i];
routes.push(mRouter);
router.addRoute(mRouter);
}
let Router404 = {
path: '*',
name: '404',
meta: {
title: '404'
},
component: () => import('@/pages/system/error/404')
};
routes.push(Router404);
router.addRoute(Router404);
router.beforeResolve((to, from, next) => {
// 判断是否需要登录才可以进入
if (to.matched.some(_ => _.meta.auth)) {
// 这里依据 token 判断是否登录,可视情况修改
if (token && token !== 'undefined') {
next();
} else {
// 没有登录的时候跳转到登录界面, 携带上登陆成功之后需要跳转的页面完整路径
next({
name: 'login',
query: {
redirect: to.fullPath
}
});
}
} else {
// 不需要身份校验 直接通过
next();
}
});
router.afterEach(to => {
// 多页控制 打开新的页面
store.dispatch('admin/page/open', to);
// 更改标题
util.title({
title: to.meta.title
});
// 返回页面顶端
window.scrollTo(0, 0);
});
})();
export default router;
3.渲染amis页面
pages/default/default.tpl.vue(amis页面渲染器)核心代码如下:
import axios from "axios";
import store from '@/store';
import router from '@/router';
import {Notice,Message} from 'view-design';
import { loadPageTemplate } from "./services/system";
const amis = amisRequire("amis/embed");
import Setting from "@/setting";
axios.interceptors.response.use(
res => res, //res为axios封装后的结果,amis底层会进行.data取出接口数据
error => {
if (error.response.status == 401) { // token 过期
router.app._route.name !== 'login' && store.dispatch('admin/account/logout');
}
return Promise.reject(error)
});
const amisEnv =
{
// api接口调用fetcher实现
fetcher: ({
url, // 接口地址
method, // 请求方法 get、post、put、delete
data, // 请求数据
responseType,
config, // 其他配置
headers // 请求头
}) => {
config.withCredentials = true;
responseType && (config.responseType = responseType);
if (config.cancelExecutor) {
config.cancelToken = new (axios).CancelToken(
config.cancelExecutor
);
}
config.headers = headers || {};
config.headers["Authorization"]= `Bearer ${token}`;
if (method !== 'post' && method !== 'put' && method !== 'patch') {
if (data) {
config.params = data;
}
return (axios)[method](url, config);
} else if (data && data instanceof FormData) {
// config.headers['Content-Type'] = 'multipart/form-data';
} else if (
data &&
typeof data !== 'string' &&
!(data instanceof Blob) &&
!(data instanceof ArrayBuffer)
) {
data = JSON.stringify(data);
config.headers['Content-Type'] = 'application/json';
}
return (axios)[method](url, data, config);
},
isCancel: (value) => { (axios).isCancel(value) },
copy: content => {
copy(content);
toast.success('内容已复制到粘贴板');
},
// 用来实现通知,不传则使用amis内置
notify: (type, msg) => {
if (msg != 'Response is empty!') {
let mtype = {
success: '成功',
error: '错误',
info: '信息',
warning: '警告',
warn: '警惕'
}
Notice[type](
{
title: mtype[type],
desc: msg.toString()
}
);
}
},
// 用来实现提示,不传则使用amis内置
alert: content => {
Message.info({
content: content,
duration: 3,
closable: true
});
},
// 用来实现确认框,不传则使用amis内置。
// confirm: content => {}
// 主题,默认是 default,还可以设置成 cxd 或 dark,但记得引用它们的 css,比如 sdk 目录下的 cxd.css
theme: "ang"
}
//tracker可以在监听到指定事件触发后,进行相关处理。
// const tracker = (eventTrack, props) => {
// //tracker监听到FormItem改变后, 更新到vue中,可以用来做参数配置器
// if (eventTrack.eventType == 'formItemChange') {
// const formData = this.amisScoped.getComponentByName("mpage.mform")?.getValues();
// }
// }
// amisEnv.tracker = tracker;
// amisEnv.session = "global"
export default {
watch: {
"$route.meta.template": {
handler(template) {
this.loadInit(template);
},
immediate: false,
},
},
async mounted() {
this.loadInit(this.$route.meta.template);
},
beforeDestroy() {
this.amisScoped?.unmount();
},
methods: {
async loadInit(id) {
let pl = await loadPageTemplate(id); //获取amis页面信息
const m = pl.data;
if (m) {
this.amisScoped?.unmount();
const amisJSON = JSON.parse(template);
amisJSON.data = { ...amisJSON.data, appname, user: this.userInfo }
if(this.$refs["vnode"]){
this.amisScoped = amis.embed(
this.$refs["vnode"],
amisJSON,
{ theme: "ang" },
amisEnv
);
}
}
}
}
}
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » vue中使用amis(做管理后台渲染器)
发表评论 取消回复