私は最近、権限が備わっていますバックエンド管理システムを完成実現しますが、すべてのメニューを考える左バックされているシステム、メニューの拡大を制限するので、私は3つのメニューの表示を改善しました。
能力の機能を実現します
権限ルートアイデア:ロールルーティングテーブルへのアクセスを生成するように構成された比較フィルタにおけるユーザのログイン情報ロールのルーティング情報に従って、アクセスを動的に実現するために、ルーティングテーブルrouter.addRoutes(store.getters.addRouters)を追加することができメニューバーの上部と左側に表示されます。
実装手順:
1.メニューのそれぞれの役割にデフォルト情報を設定します。
デフォルトロールの設定情報を、対応するメニューのルータ/ index.jsに、次のように:メタ:{役割:[「管理者」、「エディタ」]}、そして異なるメニューに設定され、「アクセス許可」許可をメタ::{役割:[「管理者」]}、そして唯一の「管理者」は、メニューを見ることができると言った、そのサブメニュー「ボタン当局に、そのサブメニュー「ページ権限」に設定したアクセス権を、役割が見ることができます「セット権限:メタ:{役割:[ 『エディタ』]}、およびのみを表し、」編集「は、メニューを見ることができます。
権限router.beforeEachを(傍受2.フィルタリングおよびルーティング)。
コードは以下の通りであります:
// permission judge function
function hasPermission(roles, permissionRoles) {
if (roles.indexOf('admin') >= 0) return true // admin permission passed directly
if (!permissionRoles) return true
return roles.some(role => permissionRoles.indexOf(role) >= 0)
}
const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
NProgress.start()
// 设置浏览器头部标题
const browserHeaderTitle = to.meta.title
store.commit('SET_BROWSERHEADERTITLE', {
browserHeaderTitle: browserHeaderTitle
})
// 点击登录时,拿到了token并存入了vuex;
if (getToken()) {
/* has token*/
if (store.getters.isLock && to.path !== '/lock') {
next({
path: '/lock'
})
NProgress.done()
} else if (to.path === '/login') {
next({ path: '/' }) // 会匹配到path:'',后面的path:'*'还没有生成;
NProgress.done()
} else {
if (store.getters.roles.length === 0) {
store.dispatch('GetInfo').then(res => { // 拉取用户信息
const roles = res.roles
store.dispatch('GenerateRoutes', { roles }).then(() => { // 根据roles权限生成可访问的路由表
router.addRoutes(store.getters.addRouters) // 动态添加可访问权限路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch((err) => {
store.dispatch('FedLogOut').then(() => {
Message.error(err || 'Verification failed, please login again')
next({ path: '/' })
})
})
} else {
// 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓
if (hasPermission(store.getters.roles, to.meta.roles)) {
next()//
} else {
next({ path: '/401', replace: true, query: { noGoBack: true }})
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
// 点击退出时,会定位到这里
next('/login')
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done() // 结束Progress
setTimeout(() => {
const browserHeaderTitle = store.getters.browserHeaderTitle
setTitle(browserHeaderTitle)
}, 0)
})
复制代码
ユーザー後のビジネス・ロジック解析は、ログインをクリック:
1、ログインユーザインタフェースの転送、取得されたトークン、後藤経路。
図2に示すように、フックrouter.beforeEachによって誘導経路((から、次)=> {}に)次のように、次のジャンプロジック機能を決定します。
2.1、用户已经登录成功并返回token值;
2.1.1、lock 锁屏场景;
2.1.2、用户重新定位到登录页面;
2.1.3、根据用户是否有roles信息,进行不同的业务逻辑,如下:
(1)、初始情况下,用户roles信息为空;
通过store.dispatch('GetInfo')调取接口,获取用户信息;
获取到roles信息后,将roles,name,avatar保存到vuex;
同时,通过store.dispatch('GenerateRoutes', { roles })去重新过滤和生成路由,并将重新生成之后的权限路由'routes'保存到vuex;
最后,通过router.addRoutes()合并路由表;
如果在获取用户信息接口时,出现错误,则调取store.dispatch('FedLogOut')接口,返回到login页面;
用户FedLogOut之后,需要情况vuex和localStorage中的token信息;
(2)、用户已经拥有roles信息;
点击页面路由,通过roles权限判断 hasPermission();
如果用户有该路由权限,直接跳转对应的页面;如果没有权限,则跳转至401提示页面;
2.2、用户没有获取到token值;
2.2.1、如果设置了白名单用户,则直接跳转到相应的页面;反之,则跳转至登录页面;
复制代码
3.フック関数router.afterEach()を介して、ナビゲーションのルートは、仕事を終えます
次のように:
3.1、NProgress.done() // 结束Progress
3.2、获取到title并设置title;
复制代码
詳細は、ご相談くださいSRC / permission.jsを
4.権利デモンストレーションショー
テストアカウント:
。(1)ユーザー名:管理者パスワード:123456;管理者は、ページとボタンのすべてを見ることができる最高の権限を有しています。
。(2)ユーザ名:エディタ、パスワード:123456;のみの権限ページとボタン与えられたエディタが見ることができます。
トップショーで3つのナビゲーションメニューバー
示されているように、一般的なバックグラウンドシステムの完成が二ナビゲーションメニューの機能を持っていた後、私は、バックエンド管理システムの多くは、3つのナビゲーションメニューを持っていますが、あなたが考えている場合3レベルのメニューを行うには、左側のメニューに足を踏み入れたことがわかります配置は、よりコンパクトになりますので、私は、メニューの一番上に3つのすべてを置くことは良い選択だと思います。
1.開発が必要です:
メニュー(上部のメニューバー)、それらに対応する上部のナビゲーションバーへの排出量を見つけ、左のメニューをクリックします。
2.開発ステップ:
1.トップナビゲーションコンポーネントtopMenu.vueを定義します。
要素-UIによって行われる、NavMenuナビゲーションメニューは、トップバーと提供サイドバーとの間の差に注意し、トップメニューを表示し、ヘッドアセンブリheadNav.vueを参照しながら、
2.データルータ/ topRouter.jsをルーティングトップバーを定義します。
形式は次のとおりです。
export const topRouterMap = [
{
'parentName':'infoShow',
'topmenulist':[
{
path: 'infoShow1',
name: 'infoShow1',
meta: {
title: '个人信息子菜单1',
icon: 'fa-asterisk',
routerType: 'topmenu'
},
component: () => import('@/page/fundList/moneyData')
}
]
},
{
'parentName':'chinaTabsList',
'topmenulist':[
{
path:'chinaTabsList1',
name:'chinaTabsList1',
meta:{
title:'区域投资子菜单1',
icon:'fa-asterisk',
routerType:'topmenu'
},
component: () => import('@/page/fundList/moneyData')
}
]
}
]
复制代码
ルーティングはtopRouterMap基の総数として定義される。parentNameによる経路の左側面との接触を確立するために、topmenulistによってトップフィールドルートの値を表し、meta.routerType値で「トップメニュー」または「leftmenuは」ルートを区別するトップフィールドであり、または左ルート側。
3. headNav.vueがデータをレンダリングする準備。
アイデア:表示されるメニューの上部に対応する、左のメニューをクリックしてください。左側のメニューでは、接触してトップメニューを確立しているため。ユーザーのログはユーザーのロール情報の権限に従ってフィルタリングされたときに私たちは、そのナビゲーションメニューを知って、その後、濾過前の権利ルーティングデータに、我々は)すべての3つのメニューがaddTopRouterを追加することによってフィルタリングすることができます(、添加が完了し、引き続き役割フィルタは、トップメニューも除外されることを保証する権限を持つことはできません。
// 通过循环过滤,生成新的二级菜单
function addTopRouter(){
asyncRouterMap.forEach( (item) => {
if(item.children && item.children.length >= 1){
item.children.forEach((sitem) => {
topRouterMap.forEach((citem) => {
if(sitem.name === citem.parentName){
let newChildren = item.children.concat(citem.topmenulist);
item.children = newChildren;
}
})
})
}
})
return asyncRouterMap;
}
复制代码
ナビゲーションルートから4と対応するフィルタリングされたデータを表示します。
次のようにtopMenu.vueコンポーネントで、ユーザまたはデフォルトでは、左のメニュートリガsetLeftInnerMenu()関数を来ります:
setLeftInnerMenu(){
if(this.$route.meta.routerType == 'leftmenu'){ // 点击的为 左侧的2级菜单
this.$store.dispatch(''ClickLeftInnerMenu,
{'name':this.$route.name}
);
}else{ // 点击顶部的菜单
this.$store.dispatch('ClickTopMenu',
{'title':this.$route.meta.title}
);
}
}
复制代码
この経路によって、このストアトリガー非同期動作「ClickLeftInnerMenu」現在のルーティング情報state.topRoutersをフィルタリングすることによって=においてパラメータ「名前」、vuex filterTopRouters(state.routers、データ)を渡し、コードは次のように
// 获取到当前路由对应顶部子菜单
function filterTopRouters(data){
let topRouters = topRouterMap.find((item)=>{
return item.parentName === data.name
})
if(!mutils.isEmpty(topRouters)){
return topRouters.topmenulist;
}
}
复制代码
計算によってtopMenu.vue:トップに表示するための対応するルーティングデータ{... mapGetters([ 'topRouters'])}。ユーザーは、左のメニューをクリックするたびに、トップルートは再割り当てし、データの正確性を保証するためにレンダリングされています。
トップメニュー完璧。
データは、メニューの一番上が大きすぎる場合は、我々は、水平スクロールバーを設定し、スクロールバーのスタイルを設定する必要があります。図:
詳細なモックデータ
簡単なモックを使用
1. 簡単にモックの説明:
- 簡単にモックは、視覚的で、かつ迅速にアナログデータの永続性サービスを生成することができ、
- 簡単にモックサポート闊歩は、時間に基づいてインターフェイスを作成手動で保存するプロジェクトを作成します。
- 簡単に言えば:簡単なモックは、モックオンラインサービスのプラットフォームを作成するために、あなたの設定を救うために、インストールを、サービス、メンテナンスから、人々はモックデータ交換や複雑な一連の動作を協力しないで、それは1秒で行うことができますすべてのための時間にあなたがしたいです。
詳しい使い方は、などの新しいプロジェクト、基本的な構文、データプレースホルダ、闊歩の導入および使用が含まれている、を参照してください。詳細なドキュメント
2.easy-モック、このプロジェクトでは、使用しています:
1.公式文書によると、個人的なプロジェクトVUE-touzi管理者を作成します。
ユーザインタフェース情報を取得することと、「/ユーザー/ログイン」:ユーザーがログインインタフェース:プロジェクトのニーズに応じて、インターフェイスを作成した「/ユーザー/情報を」;ユーザーがインタフェースログオフ:「/ユーザー/ログアウト」;すべてのユーザーインタフェースのリストを取得します: "/ユーザー/ getUserList";図:
次のようにログイン・インターフェース・ロジック簡単にモックエンドを用意します:
{
code: function({
_req
}) {
if (_req.body.username === "admin" || _req.body.username === "editor" && _req.body.password === "123456") {
return 200
} else {
return -1
}
},
message: function({
_req
}) {
if (_req.body.username !== "admin" || _req.body.username !== "editor") {
return "账号或密码有误!"
}
},
data: function({
_req
}) {
if (_req.body.username == "admin" && _req.body.password === "123456") {
return {
code: 0,
roles: ['admin'],
token: 'admin',
introduction: '我是超级管理员',
name: 'Super Admin'
}
} else if (_req.body.username === 'editor' && _req.body.password === "123456") {
return {
code: 0,
roles: ['editor'],
token: 'editor',
introduction: '我是编辑',
name: 'Normal Editor'
}
} else {
return "账号或密码有误!"
}
}
}
复制代码
2.開発環境と本番環境のアドレスの設定は、
開発環境:NODE_ENV =開発、生産環境、NODE_ENV =生産;、次のとおりです。
NODE_ENV = development
VUE_APP_URL = "https://easy-mock.com/mock/5cd03667adb0973be6a3d8d1/api"
复制代码
インターフェースパッケージの3例。
次のように:
import request from '@/utils/axios'
import baseUrl from '@/utils/env'
export function login(username, password) {
return request({
url: baseUrl.app_url+'/user/login',
method: 'post',
data: {
username,
password
}
})
}
复制代码
mockjs使用
1.背景:
簡単モックアナログデータを使用して、それが固定されたフォームデータがそれによって使用mockjsを選択し、CRUD等を達成することができないことがわかりました。
2.はじめと機能:
Mock.jsは、ユニットテストを書くため、バックエンド開発のフロントエンド包囲部門が独立して支援するために設計されたシミュレーションデータジェネレータです。アナログ機能には、以下の機能を提供します。
1.メソッドmockjsが提供するアナログデータを生成するデータテンプレートによると、あなたは簡単にランダムなテキスト、数値、ブール、日付、その上の電子メール、リンク、画像、色との多くを作成することができます。
2.アナログAjaxリクエスト、アナログデータを生成して返す、mockjsは、強力なAjaxの傍受することができます。などの要求、URLへのアクセス、リクエストパラメータの種類を決定することができます次に、あなたは偽のデータ、または、独自のプログラムJSONファイルを模擬するために戻ることができます。親しみパワフル。
3. HTMLテンプレートに基づいてシミュレートされたデータを生成します
このプロジェクトで使用3.mockjs:
1. mockjsをインストールします。
npm install mockjs --save-dev
复制代码
2.モックフォルダ構造を作成し、関連する機能モジュールを定義します。
図:
import Mock from 'mockjs'
import tableAPI from './money'
// 设置全局延时 没有延时的话有时候会检测不到数据变化 建议保留
Mock.setup({
timeout: '300-600'
})
// 资金相关
Mock.mock(/\/money\/get/, 'get', tableAPI.getMoneyList)
Mock.mock(/\/money\/remove/, 'get', tableAPI.deleteMoney)
Mock.mock(/\/money\/batchremove/, 'get', tableAPI.batchremoveMoney)
Mock.mock(/\/money\/add/, 'get', tableAPI.createMoney)
Mock.mock(/\/money\/edit/, 'get', tableAPI.updateMoney)
复制代码
mockjs / money.js、関連する関数を定義し、アナログデータ、金融データフローを変更して再検索などの欠失などのビジネスロジック、;生成されたルールデータを参照mockjsネットワーク公式文書を、そこには、構文上で詳細に記載されています。
良いmockjsの定義に組み込まれた3 main.js。
次のように:
import './mockjs' //引用mock
复制代码
4.mockjs、APIインタフェースパッケージ。
パッケージへの統一されたインタフェース、ページに対応する関数呼び出しのSRC / API / money.js、取得したアナログデータに対応します。コードは以下の通りであります:
import request from '@/utils/axios'
export function getMoneyIncomePay(params) {
return request({
url: '/money/get',
method: 'get',
params: params
})
}
export function addMoney(params) {
return request({
url: '/money/add',
method: 'get',
params: params
})
}
复制代码
5.組み立て、インターフェース呼び出し、データ収集は、ページをレンダリングします。
VUE-cli3.0レコードをアップグレード
VUE-CLI 3.0統合WebPACKの構成、および多くを行ってパフォーマンスを最適化する上で、早期使用VUE-cli2.0プロジェクトは、プロジェクト、面倒なWebPACKの設定の必要性を構築するので。このプロジェクトは、ビルドしてアップグレードするVUE-cli3.0を使用しているので。ノートは今、次のように、詳細なドキュメントは、を参照してください概要を説明する公式サイト。
1.vue-cli3.0は、導入の前提を使用します
VueのCLIパッケージ名は/ CLI A VUE-CLIの@ VUEに変更しました。すでにグローバルVUE-CLI(1.xまたは2.xの)の古いバージョンをインストールしている場合は、NPMのアンインストールVUE-CLI -g、または糸グローバル削除VUE-CLIによってそれをアンインストールする必要があります。VueのCLIは、Node.jsのバージョン8.9以降(推奨8.11.0+)が必要です。あなたはNVM NVM-ウィンドウを使用することができますまたはノードは、同じコンピュータ上で複数のバージョンを管理します。
インストールと使用2.vue-cli3.0
1.vue-cli3.xインストール
npm install -g @vue/cli
# OR
yarn global add @vue/cli
复制代码
あなたもVUE-cli2.x文法を維持するか、テンプレート2.xのを使用したい場合は、CLI-INITをインストールすることをお勧めします
npm install -g @vue/cli-init
# OR
yarn global add @vue/cli-init
复制代码
2. VUE-cli3.xを使用してプロジェクトを作成します。
vue create 项目名称;
完了するまで、関連する構成情報を選択するステップを取り付けます。
3.新しいプロジェクトは、環境変数とコンフィギュレーションモードを必要とします
ルートディレクトリと.env.development .env.production、開発環境で新しいファイルをそれぞれ生成する環境の構成は、主に環境変数を定義するために使用される、またはNPMの実行によってインタフェースのためのさまざまな環境に統合NPMの実行ビルドを、サーブ呼び出します。コードは以下の通りであります:
.env.development
NODE_ENV = development
VUE_APP_URL = "https://easy-mock.com/mock/5cd03667adb0973be6a3d8d1/api"
复制代码
.env.production
NODE_ENV = production
VUE_APP_URL = "https://easy-mock.com/mock/5cd03667adb0973be6a3d8d1/api"
复制代码
次のようにutilsの/ env.jsコードに配置され、本プロジェクトにおけるような使用は、次のとおりです。
// development和production环境是不同的
let app_url = process.env.VUE_APP_URL
export default {
app_url
}
复制代码
我々は簡単にモックシミュレーションデータを使用しているので、そこにはクロスドメインの問題はありませんので、devServer.proxyを設定する必要、直接使用することができます。使用中のAPI次のように:
import request from '@/utils/axios'
import baseUrl from '@/utils/env'
export function login(username, password) {
return request({
url: baseUrl.app_url+'/user/login',
method: 'post',
data: {
username,
password
}
})
}
复制代码
4.詳細設定コンパイラパッケージvue.config.js
WebPACKのために、所望であれば使用VUE-cli3.x生成プログラムは、そのようなことができる新しいファイルvue.config.jsルート特定の構成に必要な項目の具体的な構成として、構成のWebPACKのnode_moduleに統合された文書を参照する、以下これは、基本的な構成です。
const TerserPlugin = require('terser-webpack-plugin') // 用于在生成环境剔除debuger和console
const path = require('path');
const resolve = dir => {
return path.join(__dirname, dir);
};
const env = process.env.NODE_ENV
let target = process.env.VUE_APP_URL // development和production环境是不同的
module.exports = {
publicPath: '/',
outputDir: './dist',
lintOnSave: false, // 关闭eslint
// 打包时不生成.map文件
productionSourceMap: false,
devServer: {
open: true,
host: '0.0.0.0',
port: 8808
// 由于本项目数据通过easy-mock和mockjs模拟,不存在跨域问题,无需配置代理;
// proxy: {
// '/v2': {
// target: target,
// changeOrigin: true
// }
// }
},
// webpack相关配置
chainWebpack: (config) => {
config.entry.app = ['./src/main.js'];
config.resolve.alias
.set('@', resolve('src'))
.set('cps', resolve('src/components'))
},
configureWebpack:config => {
// 为生产环境修改配置...
if (process.env.NODE_ENV === 'production') {
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true, // Must be set to true if using source-maps in production
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
}
})
} else {
// 为开发环境修改配置...
}
},
// 第三方插件配置
pluginOptions: {
}
}
复制代码
良いプロジェクトの設定が完了し、すべての依存関係をインストールします。開発環境パッケージのコマンドの実装:NPMプロジェクトを実行することができ、サーブ実行します。実行環境生成包装コマンド:ビルドを実行NPM、本番環境のファイルを生成することができます。
技術的なQ&A
プロジェクトの説明:
リトル愛ADMINは、完全統合ソリューションは、バックエンド管理システムテンプレートに直接関連適用することができます無料のオープンソース管理システムであり、多くの場所は、詳細なメモと説明の焦点です。あなたは同じフロントエンドの開発と同様に、グループ内で議論/研究グループへの参加を歓迎した場合はQ&A、株式学習教材することができ; Q QQのグループへの参加を歓迎します:602 515 030
ます。https://juejin.im/post/5d0b4d28f265da1baf7cf293で再現