이 글의 내용은 vue-manage-system 백그라운드 관리 시스템의 개발 과정(코드)에 관한 것입니다. 필요한 친구들이 참고할 수 있기를 바랍니다.
vue.js 및 element-ui를 기반으로 하는 백엔드 관리 시스템 템플릿인 vue-manage-system은 2016년 말 첫 커밋 이후 거의 2년이 지났습니다. GitHub에도 별 5,000개가 있습니다. 이것도 나에게 업데이트를 계속할 동기를 주었고, 나는 또한 많은 함정을 밟았는데, 이에 대해 여기서 요약하겠다.
github 주소: vue-manage-system
element-ui에는 비교적 적은 수의 글꼴 아이콘이 제공되며, 일반적인 것 중 상당수는 사용할 수 없으므로 원하는 글꼴 아이콘을 도입해야 합니다. 가장 인기 있는 아이콘 라이브러리인 Font Awesome에는 전체 675개의 아이콘이 있지만 이로 인해 상대적으로 큰 글꼴 파일이 생성되므로 프로젝트에서 너무 많은 아이콘을 사용할 필요가 없습니다. 그렇다면 이때 Alibaba Icon Library는 매우 좋은 선택입니다.
먼저 Ali 아이콘에 대한 프로젝트를 생성하고, el-icon-lx와 같은 아이콘 접두사를 설정하고, lx-iconfont와 같은 글꼴 모음을 설정하고, 프로젝트에 사용해야 하는 아이콘을 추가하고, 여기에서 글꼴 클래스를 선택합니다. 온라인 링크를 생성하려면 모든 페이지가 아이콘을 사용해야 하기 때문에 index.html에 직접 CSS 링크를 추가하면 됩니다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>vue-manage-system</title> <!-- 这里引入阿里图标样式 --> <link rel="stylesheet" href="//at.alicdn.com/t/font_830376_qzecyukz0s.css"> </head> <body> <p id="app"></p> </body> </html>
그런 다음 lx-iconfont 글꼴을 사용하려면 el-icon-lx 접두어를 사용하여 아이콘 클래스 이름을 설정해야 합니다.
[class*="el-icon-lx"], [class^=el-icon-lx] { font-family: lx-iconfont!important; }
그런데 이 스타일은 어디에 배치해야 할까요? 이것은 아무렇게나 넣을 수 있는 것이 아닙니다. main.js에는 element-ui 스타일이 도입되었으며 스타일에 CSS 조각이 있습니다.
[class*=" el-icon-"], [class^=el-icon-]{ font-family: element-icons!important; speak: none; font-style: normal; font-weight: 400; font-variant: normal; text-transform: none; line-height: 1; vertical-align: baseline; display: inline-block; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
분명히 이 CSS 조각이 사용자 정의 스타일 다음에 실행되면 사용자 정의 아이콘을 덮어쓰게 됩니다. 표시되지 않습니다. 프로젝트를 빌드할 때 APP.vue의 스타일이 app.css에 패키징된 다음, main.js에서 참조되는 스타일이 뒤에 추가됩니다. 그런 다음 사용자 정의 스타일을 CSS 파일에 넣은 다음 main.js에 element-ui CSS를 도입한 후 이를 도입하면 기본 글꼴을 덮어쓸 수 있으며 <i class="el-icon-lx-people"></i>
를 통해 프로젝트에서 아이콘을 사용할 수 있습니다.
똑똑한 사람은 내 맞춤 아이콘의 접두사에 el-icon-이 포함되어 있지 않으면 그런 문제가 없다는 것을 발견했습니다. 예, 원본 글꼴과 동일한 스타일을 유지하려면 CSS 전체를 복사해야 합니다
/* 假设前缀为 el-lx */ [class*="el-lx-"], [class^=el-lx-]{ font-family: lx-iconfont!important; speak: none; font-style: normal; font-weight: 400; font-variant: normal; text-transform: none; line-height: 1; vertical-align: baseline; display: inline-block; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
element-ui 탐색 메뉴에 대한 문서도 매우 자세하지만 일부 사람들은 여전히 문제를 제기하거나 추가합니다. QQ는 나에게 질문한다: 3차 메뉴 만드는 법 등등. 또한 특정 메뉴 항목은 권한에 따라 서버에서 반환하는 특정 데이터 항목일 수 있으므로 템플릿에 하드 코딩할 수 없습니다.
먼저 다음과 같이 메뉴 데이터의 형식을 결정합니다. 서버에서 반환되는 형식이 이와 같지 않더라도 프런트 엔드에서는 이를 다음 형식으로 처리해야 합니다.
export default { data() { return { items: [{ icon: 'el-icon-lx-home', index: 'dashboard', title: '系统首页' },{ icon: 'el-icon-lx-calendar', index: '1', title: '表单相关', subs: [{ index: '1-1', title: '三级菜单', subs: [{ index: 'editor', title: '富文本编辑器' }] }] },{ icon: 'el-icon-lx-warn', index: '2', title: '错误处理', subs: [{ index: '404', title: '404页面' }] }] } } }
icon은 메뉴 아이콘이고 위에서 사용자 정의한 아이콘을 사용할 수 있습니다. 색인은 라우팅 주소이고 하위 메뉴는 하위 메뉴입니다. 템플릿은 메뉴에 하위 항목이 포함되어 있는지 여부를 결정하여 두 번째 수준 메뉴와 세 번째 수준 메뉴를 표시합니다.
<el-menu :default-active="onRoutes" :collapse="collapse" router> <template v-for="item in items"> <template v-if="item.subs"> <el-submenu :index="item.index" :key="item.index"> <template slot="title"> <i :class="item.icon"></i><span slot="title">{{ item.title }}</span> </template> <template v-for="subItem in item.subs"> <el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index"> <template slot="title">{{ subItem.title }}</template> <!-- 三级菜单 --> <el-menu-item v-for="(threeItem,i) in subItem.subs" :key="i" :index="threeItem.index"> {{ threeItem.title }} </el-menu-item> </el-submenu> <el-menu-item v-else :index="subItem.index" :key="subItem.index"> {{ subItem.title }} </el-menu-item> </template> </el-submenu> </template> <!-- 没有二级菜单 --> <template v-else> <el-menu-item :index="item.index" :key="item.index"> <i :class="item.icon"></i><span slot="title">{{ item.title }}</span> </el-menu-item> </template> </template> </el-menu>
동적 탐색 메뉴가 완성됩니다.
Header 구성 요소의 버튼을 통해 Sidebar 구성 요소의 확장 또는 축소를 트리거하려면 구성 요소 간 데이터 전달이 필요합니다. 여기서 구성 요소 간의 통신은 Vue.js의 별도 이벤트 센터(Event Bus)를 통해 관리됩니다.
const bus = new Vue();
헤더 구성 요소에서 버튼을 클릭하면 축소 이벤트가 발생합니다.
bus.$emit('collapse', true);
사이드바 구성 요소에서 축소 이벤트 듣기:
bus.$on('collapse', msg => { this.collapse = msg; })
vue-manage-system에서 사용되는 차트 플러그인은 다음과 같습니다. vue-schart. 캔버스 기반 차트 플러그인 chart.js가 캡슐화됩니다. 차트가 너비에 맞춰 조정되도록 하고 창 크기 또는 상위 요소 변경에 따라 다시 렌더링하려면 차트 플러그인에서 이 기능이 구현되지 않은 경우 수동으로 구현해야 합니다.
vue-schart는 차트를 다시 렌더링하기 위한 renderChart() 메서드를 제공합니다. Vue.js에서 상위 구성 요소는 $refs를 통해 호출할 수 있는 하위 구성 요소 메서드를 호출합니다.
<schart ref="bar" canvasId="bar" :data="data" type="bar" :options="options"></schart>
그런 다음 창의 크기 조정 이벤트를 수신하고 renderChart() 메서드를 호출하여 차트를 다시 렌더링합니다.
import Schart from 'vue-schart'; export default { components: { Schart }, mounted(){ window.addEventListener('resize', ()=>{ this.$refs.bar.renderChart(); }) } }
하지만 구성 요소가 삭제되면 리스너를 제거하는 것을 잊지 마세요! Listening Window의 크기 변경이 완료되었는데, 상위 요소의 크기 변경은 어떻게 되나요? 상위 요소의 너비가 백분율로 설정되어 있으므로 사이드바가 축소되면 상위 요소의 너비가 변경됩니다. 그러나 p에는 크기 조정 이벤트가 없으며 너비 변경을 모니터링할 수 없지만 접기가 트리거되는 시점을 알 수 있습니다. 그러면 접힌 부분이 바뀔 때 렌더링 함수를 호출하여 차트를 다시 렌더링하는 것이 가능한가요? 그러면 이벤트 버스를 통해 사이드바의 변경 사항을 모니터링하고 300ms 후에 다시 렌더링하는 것이 좋습니다. 접을 때 300ms 애니메이션 프로세스가 있기 때문입니다
bus.$on('collapse', msg => { setTimeout(() => { this.$refs.bar.renderChart(); }, 300); });
멀티 탭 페이지도 가장 많이 제기된 문제.
当在 A 标签页输入一些内容之后,打开 B 标签再返回到 A,要保留离开前的状态,因此需要使用 keep-alive 进行缓存,而且关闭之后的标签页就不再缓存,避免关闭后再打开还是之前的状态。keep-alive 的属性 include 的作用就是只有匹配的组件会被缓存。include 匹配的不是路由名,而是组件名,那么每个组件都需要添加 name 属性。
在 Tags 组件中,监听路由变化,将打开的路由添加到标签页中:
export default { data() { return { tagsList: [] } }, methods: { setTags(route){ const isExist = this.tagsList.some(item => { return item.path === route.fullPath; }) if(!isExist){ this.tagsList.push({ title: route.meta.title, path: route.fullPath, name: route.matched[1].components.default.name }) } } }, watch:{ $route(newValue, oldValue){ this.setTags(newValue); } } }
在 setTags 方法中,将一个标签对象存到标签数组中,包括title(标签显示的title),path(标签的路由地址),name(组件名,用于include匹配的)。路由地址需要用 fullPath 字段,如果使用 path 字段,那如果地址后面带有参数,就都没保存起来了。
在 Home 组件中,监听到标签的变化,缓存需要的组件。
<keep-alive :include="tagsList"> <router-view></router-view> </keep-alive>
export default { data(){ return { tagsList: [] } }, created(){ // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 bus.$on('tags', msg => { let arr = []; for(let i = 0, len = msg.length; i < len; i ++){ // 提取组件名存到tagsList中,通过include匹配 msg[i].name && arr.push(msg[i].name); } this.tagsList = arr; }) } }
由于该项目中不包含任何业务代码,所以还是相对比较简单的,不过从开发中还是积累了一些经验,在其它项目中可以更加熟练地开发。功能虽然不算多,但是也勉强够用,如果有什么好的建议,可以开 issue 一起讨论。
相关推荐:
ASP.NET MVC5+EF6+EasyUI 后台管理系统微信公众平台开发
基于thinkphp的后台管理系统模板快速搭建,thinkphp后台模板
위 내용은 vue-manage-system 백그라운드 관리 시스템 개발 프로세스(코드)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!