您好,登錄后才能下訂單哦!
作者: 何全,github地址: https://github.com/hequan2017 QQ交流群: 620176501
通過此教程完成從零入門,能夠獨(dú)立編寫一個(gè)簡單的CMDB系統(tǒng)。
目前主流的方法開發(fā)方式,分為2種:mvc 和 mvvc方式。本教程為 mvvc(前后端分離)的入門教程。
教程項(xiàng)目地址: https://github.com/hequan2017/panda/
教程文檔地址: https://github.com/hequan2017/pandaAdmin
相較于react, vue入門更簡單,基于模板語法,適合從mvc方式 循序漸進(jìn)到 mvvc方式。
模板選擇為 基于element的模板. iview現(xiàn)在已經(jīng)轉(zhuǎn)為收費(fèi)方式,不太適合個(gè)人開發(fā)者練習(xí)使用。antd vue版本 沒有合適的 admin模板,所以放棄了.
vue-element-admin 和 d2admin 差不多,資料文檔都非常全。看個(gè)人選擇。
vue
https://fairyever.com/d2-admin/doc/zh/ #具體模板詳細(xì) 可以 看這個(gè)文檔,非常詳細(xì)
git clone https://github.com/d2-projects/d2-admin-start-kit
├─.DS_Store
├─.browserslistrc ------------------- // 目標(biāo)瀏覽器配置
├─.env ------------------------------ // 基礎(chǔ)環(huán)境變量配置
├─.env.development ------------------ // 開發(fā)模式下的環(huán)境變量配置
├─.env.netlify ---------------------- // Netlify 構(gòu)建時(shí)的環(huán)境變量
├─.env.nomock ----------------------- // 無 mock 數(shù)據(jù)構(gòu)建模式下的環(huán)境變量
├─.env.travis ----------------------- // Travis 構(gòu)建時(shí)的環(huán)境變量
├─.eslintignore --------------------- // ESLint 的忽略目錄配置
├─.eslintrc.js ---------------------- // ESLint 的配置文件
├─.github --------------------------- // Github 配置
│?└─ISSUE_TEMPLATE ------------------ // GitHub issue 模板
├─.gitignore ------------------------ // git 的忽略配置
├─.postc***c.js --------------------- // postcss 插件設(shè)置
├─.travis.yml ----------------------- // Travis 配置文件
├─LICENSE --------------------------- // 開源協(xié)議
├─README.md ------------------------- // 介紹
├─README.zh.md ---------------------- // 中文介紹 在碼云倉庫下自動(dòng)加載這個(gè)文件
├─babel.config.js ------------------- // babel 設(shè)置
├─cdnrefresh-dirs.txt --------------- // 自動(dòng)構(gòu)建后在七牛 CDN 上刷新的目錄
├─d2-admin.babel -------------------- // 多國語設(shè)置軟件 BabelEdit 的項(xiàng)目文件
├─doc ------------------------------- // 文檔素材
│?└─image
├─jest.config.js -------------------- // 單元測試配置
├─jsconfig.json --------------------- // 指定根文件和 JavaScript 語言服務(wù)提供的功能選項(xiàng)
├─package-lock.json ----------------- // 鎖定依賴版本
├─package.json ---------------------- // 項(xiàng)目信息和依賴
├─public ---------------------------- // 靜態(tài)資源文件夾,不經(jīng)過 webpack 處理
│?├─html ---------------------------- // 用于演示加載靜態(tài)頁面的資源
│?├─icon.ico ------------------------ // 網(wǎng)站圖標(biāo)
│?├─image
│?│?├─baidu-pan-logo.png
│?│?├─loading ----------------------- // index.html 使用的加載圖標(biāo)
│?│?└─theme ------------------------- // 主題圖片資源
│?│? ├─d2
│?│? ├─line
│?│? ├─star
│?│? ├─tomorrow-night-blue
│?│? └─violet
│?├─index.html ---------------------- // 網(wǎng)站的基礎(chǔ)頁面模板
│?├─lib ----------------------------- // 靜態(tài)依賴
│?│?└─UEditor ----------------------- // 編輯器
│?└─markdown ------------------------ // 用于展示 Markdown 遠(yuǎn)程加載資源的文件
├─qiniu-config ---------------------- // 用于構(gòu)建展示網(wǎng)站的七牛設(shè)置
├─qshell ---------------------------- // 七牛 SDK
├─src ------------------------------- // 主要的代碼目錄
│?├─App.vue ------------------------- // 項(xiàng)目根組件
│?├─api ----------------------------- // 請(qǐng)求接口
│?├─assets -------------------------- // 資源文件夾
│?│?├─style ------------------------- // 樣式資源
│?│?│?├─animate --------------------- // 頁面過渡動(dòng)畫
│?│?│?├─fixed ----------------------- // 覆蓋一些組件庫的默認(rèn)樣式
│?│?│?├─public-class.scss ----------- // 導(dǎo)出可以直接使用的 class
│?│?│?├─public.scss ----------------- // 導(dǎo)出所有公用的 scss 資源
│?│?│?├─theme ----------------------- // 主題樣式相關(guān)
│?│?│?│?├─d2
│?│?│?│?├─line
│?│?│?│?├─register.scss ------------- // 注冊(cè)所有主題樣式
│?│?│?│?├─star
│?│?│?│?├─theme-base.scss ----------- // 每個(gè)主題共用的樣式
│?│?│?│?├─theme.scss ---------------- // 每個(gè)主題特有的設(shè)置
│?│?│?│?├─tomorrow-night-blue
│?│?│?│?└─violet
│?│?│?└─unit ------------------------ // scss 的基礎(chǔ)變量
│?│?└─svg-icons --------------------- // svg 圖標(biāo)
│?│? ├─icons ----------------------- // 用來存放圖標(biāo)的文件夾
│?│? └─index.js -------------------- // 自動(dòng)導(dǎo)入所有符合條件的圖標(biāo)
│?├─components ---------------------- // 組件
│?│?├─d2-container
│?│?├─d2-container-frame
│?│?├─d2-count-up
│?│?├─d2-highlight
│?│?├─d2-icon
│?│?├─d2-icon-select
│?│?├─d2-icon-svg
│?│?├─d2-icon-svg-select
│?│?├─d2-link-btn
│?│?├─d2-markdown
│?│?├─d2-mde
│?│?├─d2-module-index-banner
│?│?├─d2-module-index-menu
│?│?├─d2-quill
│?│?├─d2-ueditor
│?│?├─highlight-styles -------------- // 代碼高亮樣式
│?│?└─index.js ---------------------- // 組件注冊(cè)
│?├─i18n.js ------------------------- // 國際化配置
│?├─layout -------------------------- // 布局
│?│?└─header-aside ------------------ // 具有頂欄加側(cè)邊欄的布局
│?├─libs ---------------------------- // 一些通用的方法
│?│?├─util.cookies.js
│?│?├─util.db.js
│?│?├─util.import.development.js ---- // 開發(fā)環(huán)境下使用的頁面導(dǎo)入方法
│?│?├─util.import.production.js ----- // 開發(fā)環(huán)境下使用的頁面導(dǎo)入方法
│?│?├─util.js
│?│?└─util.log.js
│?├─locales ------------------------- // 國際化語言配置
│?│?├─en.json
│?│?├─ja.json
│?│?├─zh-chs.json
│?│?└─zh-cht.json
│?├─main.js ------------------------- // 程序主入口
│?├─menu ---------------------------- // 靜態(tài)的菜單數(shù)據(jù)
│?│?├─index.js
│?│?└─modules
│?│? ├─demo-business.js
│?│? ├─demo-charts.js
│?│? ├─demo-components.js
│?│? ├─demo-d2-crud.js
│?│? ├─demo-element.js
│?│? ├─demo-frame.js
│?│? ├─demo-playground.js
│?│? └─demo-plugins.js
│?├─mock
│?│?├─api --------------------------- // 需要注冊(cè)的接口
│?│?├─d2-mock ----------------------- // 簡化接口注冊(cè)的工具
│?│?└─index.js ---------------------- // mock 數(shù)據(jù)自動(dòng)注冊(cè)
│?├─plugin -------------------------- // 插件
│?│?├─axios ------------------------- // 網(wǎng)絡(luò)請(qǐng)求
│?│?├─d2admin ----------------------- // 統(tǒng)一注冊(cè)系統(tǒng)必須的資源
│?│?├─error ------------------------- // 錯(cuò)誤攔截
│?│?├─log --------------------------- // 日志
│?│?└─open -------------------------- // 新窗口打開
│?├─router -------------------------- // 路由
│?│?├─index.js ---------------------- // 注冊(cè)路由以及設(shè)置攔截規(guī)則
│?│?├─modules ----------------------- // 預(yù)先設(shè)置好的靜態(tài)路由
│?│?│?├─business.js
│?│?│?├─charts.js
│?│?│?├─components.js
│?│?│?├─d2-crud.js
│?│?│?├─element.js
│?│?│?├─frame.js
│?│?│?├─playground.js
│?│?│?└─plugins.js
│?│?└─routes.js --------------------- // 導(dǎo)入所有路由
│?├─setting.js ---------------------- // 全局設(shè)置
│?├─store --------------------------- // vuex
│?│?├─index.js ---------------------- // vuex 注冊(cè)主入口
│?│?└─modules ----------------------- // 模塊目錄
│?│? └─d2admin --------------------- // 系統(tǒng)自帶模塊,業(yè)務(wù)模塊建議在同級(jí)新建
│?│? ├─index.js ------------------ // 模塊主入口
│?│? └─modules ------------------- // 子模塊
│?│? ├─account.js -------------- // 用戶身份
│?│? ├─color.js ---------------- // 主題顏色
│?│? ├─db.js ------------------- // 本地?cái)?shù)據(jù)庫
│?│? ├─fullscreen.js ----------- // 全屏
│?│? ├─gray.js ----------------- // 灰度模式
│?│? ├─log.js ------------------ // 日志
│?│? ├─menu.js ----------------- // 菜單
│?│? ├─page.js ----------------- // 多頁面控制
│?│? ├─releases.js ------------- // 版本
│?│? ├─search.js --------------- // 全局搜索
│?│? ├─size.js ----------------- // 全局尺寸
│?│? ├─theme.js ---------------- // 主題
│?│? ├─transition.js ----------- // 過渡效果
│?│? ├─ua.js ------------------- // 瀏覽器信息
│?│? └─user.js ----------------- // 用戶信息
│?└─views --------------------------- // 頁面視圖
│? ├─demo -------------------------- // 演示頁面
│? │?├─business -------------------- // 業(yè)務(wù)頁面演示
│? │?│?├─index
│? │?│?├─issues
│? │?│?└─table
│? │?├─charts ---------------------- // 圖表
│? │?│?├─index
│? │?│?└─list
│? │?│? ├─_data
│? │?│? ├─_mixin
│? │?│? ├─bar
│? │?│? ├─candle
│? │?│? ├─funnel
│? │?│? ├─gauge
│? │?│? ├─heatmap
│? │?│? ├─histogram
│? │?│? ├─line
│? │?│? ├─map
│? │?│? ├─pie
│? │?│? ├─radar
│? │?│? ├─ring
│? │?│? ├─sankey
│? │?│? ├─scatter
│? │?│? ├─tree
│? │?│? └─waterfall
│? │?├─components ------------------ // 內(nèi)置組件演示
│? │?│?├─container
│? │?│?├─contextmenu
│? │?│?├─countup
│? │?│?├─editor-quill
│? │?│?├─editor-simpleMDE
│? │?│?├─editor-ueditor
│? │?│?├─highlight
│? │?│?├─icon
│? │?│?├─index
│? │?│?├─json-tree
│? │?│?├─layout
│? │?│?└─markdown
│? │?├─d2-crud --------------------- // D2CRUD 表格封裝演示
│? │?├─element --------------------- // Element UI 組件
│? │?├─frame ----------------------- // 嵌套第三方頁面演示
│? │?├─playground ------------------ // 試驗(yàn)臺(tái)
│? │?│?├─add-routes ---------------- // 動(dòng)態(tài)添加路由
│? │?│?├─db ------------------------ // 數(shù)據(jù)持久化
│? │?│?├─env ----------------------- // 環(huán)境變量
│? │?│?├─index
│? │?│?├─locales ------------------- // 多國語
│? │?│?├─log ----------------------- // 日志
│? │?│?├─page-argu ----------------- // 頁面參數(shù)
│? │?│?├─page-cache ---------------- // 頁面緩存
│? │?│?└─store --------------------- // 全局狀態(tài)控制
│? │?│? ├─fullscreen
│? │?│? ├─gray
│? │?│? ├─menu
│? │?│? ├─page
│? │?│? ├─size
│? │?│? ├─theme
│? │?│? ├─transition
│? │?│? └─ua
│? │?└─plugins --------------------- // 插件演示
│? │? ├─better-scroll
│? │? ├─clipboard-polyfill
│? │? ├─day
│? │? ├─export
│? │? ├─import
│? │? ├─index
│? │? ├─js-cookie
│? │? └─mock
│? └─system ------------------------ // 系統(tǒng)頁面
│? ├─error
│? ├─function
│? │?├─redirect ------------------ // 重定向
│? │?└─refresh ------------------- // 刷新
│? ├─index
│? ├─log
│? └─login
├─tests ----------------------------- // 單元測試
├─tools
│?└─vue-filename-injector ----------- // 用于對(duì)每個(gè)組件注入源代碼位置的插件
└─vue.config.js --------------------- // vue-cli3 的項(xiàng)目配置文件
try {
AccountLoginInfo(res.token)
.then(resinfo => {
const data = resinfo.data /* 獲取后端用戶信息*/
console.log(resinfo)
dispatch(
'd2admin/user/set',
{
name: resinfo.name
},
{ root: true }
)
resolve(data)
})
.catch(err => {
reject(err)
})
} catch (error) {
reject(error)
}
import request from '@/plugin/axios'
export function AccountLogin (data) {
return request({
url: '/api/token',
method: 'post',
data
})
}
export const AccountLoginInfo = token => {
return request({
url: '/system/api/user_info',
data: {
token
},
method: 'post'
})
}
// 請(qǐng)求攔截器
service.interceptors.request.use(
config => {
// 在請(qǐng)求發(fā)送之前做一些處理
const token = util.cookies.get('token')
// 讓每個(gè)請(qǐng)求攜帶token-- ['X-Token']為自定義key 請(qǐng)根據(jù)實(shí)際情況自行修改
// config.headers[''] = token
if (token) {
config.headers['Authorization'] = `token ${token}`
}
return config
},
error => {
// 發(fā)送失敗
console.log(error)
return Promise.reject(error)
}
)
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState('d2admin/user', [
'info'
])
},
/* info 為 上面保存的信息,這里可以在用戶登錄后 直接讀取*/
{{info.name ? `你好 ${info.name}` : '未登錄'}}
路由
import request from '@/plugin/axios'
export const TestGetList = parameter => {
return request({
url: `/system/test?${parameter}`,
method: 'get'
})
}
export const TestCreate = data => {
return request({
url: '/system/test',
data: data,
method: 'post'
})
}
export const TestGetInfo = id => {
return request({
url: `/system/test/${id}`,
method: 'get'
})
}
export const TestUpdate = (id, data) => {
return request({
url: `/system/test/${id}`,
data: data,
method: 'PUT'
})
}
export const TestDelete = id => {
return request({
url: `/system/test/${id}`,
method: 'delete'
})
}
<template>
<d2-container>
<template slot="header">演示頁面</template>
<el-input v-model="input"
placeholder="請(qǐng)輸入姓名"
prefix-icon="el-icon-search"
clearable></el-input>?
<el-button type="primary"
icon="el-icon-search"
@click="search">搜索</el-button>
<br /><br />
<d2-crud ref="d2Crud"
:columns="columns"
:data="data"
add-title="資產(chǎn)管理"
:add-template="addTemplate"
:form-options="formOptions"
:add-rules="addRules"
:edit-rules="addRules"
:edit-template="editTemplate"
:rowHandle="rowHandle"
@row-add="handleRowAdd"
@row-edit="handleRowEdit"
@row-remove="handleRowRemove"
:pagination="pagination"
@dialog-cancel="handleDialogCancel"
@el-icon-more="handleInfo"
@pagination-current-change="paginationCurrentChange">
<el-button slot="header"
@click="addRow">新增</el-button>
</d2-crud>
</d2-container>
</template>
<script>
import { TestGetList, TestCreate, TestUpdate, TestDelete, TestGetInfo } from '@api/sys.login'
export default {
data () {
return {
columns: [
{
title: '日期',
key: 'date'
},
{
title: '姓名',
key: 'name'
},
{
title: '地址',
key: 'address'
}
],
data: [
],
input: '',
addTemplate: {
date: {
title: '日期',
value: '2016-05-05'
},
name: {
title: '姓名',
value: '王小虎'
},
address: {
title: '地址',
value: '上海市普陀區(qū)金沙江路 1520 弄'
}
},
formOptions: {
labelWidth: '80px',
labelPosition: 'left',
saveLoading: false
},
pagination: {
currentPage: 1,
pageSize: 10,
total: 0
},
addRules: {
date: [{ required: true, message: '請(qǐng)輸入日期', trigger: 'blur' }],
name: [{ required: true, message: '請(qǐng)輸入姓名', trigger: 'blur' }],
address: [{ required: true, message: '請(qǐng)輸入地址', trigger: 'blur' }]
},
rowHandle: {
columnHeader: '編輯表格',
edit: {
icon: 'el-icon-edit',
type: 'primary',
text: '編輯',
size: 'small',
show (index, row) {
return true
},
disabled (index, row) {
return false
}
},
custom: [
{
text: '詳情',
type: 'info',
size: 'small',
fixed: 'right',
emit: 'el-icon-more'
}
],
remove: {
icon: 'el-icon-delete',
size: 'small',
fixed: 'right',
confirm: true,
show (index, row) {
return true
},
disabled (index, row) {
return false
}
}
},
editTemplate: {
date: {
title: '日期',
value: ''
},
name: {
title: '姓名',
value: ''
},
address: {
title: '地址',
value: ''
},
forbidEdit: {
title: '禁用按鈕',
value: false,
component: {
show: false
}
},
showEditButton: {
title: '顯示按鈕',
value: true,
component: {
show: false
}
}
}
}
},
created () {
this.test_get_list()
},
methods: {
handleInfo ({ index, row }) {
TestGetInfo(row.id).then(res => {
this.$alert(`${res.date} ${res.address}`, `${res.name}`, {
confirmButtonText: '確定'
}).catch(err => {
console.log(`獲取信息錯(cuò)誤 ${err}`)
})
})
},
test_get_list (parameter) {
TestGetList(parameter).then(res => {
console.log(res)
this.data = res.results
this.pagination.total = res.count
}).catch(err => {
console.log(`獲取信息錯(cuò)誤 ${err}`)
})
},
paginationCurrentChange (currentPage) {
TestGetList(`page=${currentPage}`).then(res => {
console.log(res)
this.data = res.results
this.pagination.total = res.count
}).catch(err => {
console.log(`獲取信息錯(cuò)誤 ${err}`)
})
this.pagination.currentPage = currentPage
// this.fetchData()
},
addRow () {
this.$refs.d2Crud.showDialog({
mode: 'add'
})
},
search () {
this.test_get_list(`name=${this.input}`)
},
handleRowAdd (row, done) {
this.formOptions.saveLoading = true
TestCreate(row).then(res => {
}).catch(err => {
console.log(err)
})
setTimeout(() => {
this.$message({
message: '保存成功',
type: 'success'
})
done()
this.formOptions.saveLoading = false
this.test_get_list()
}, 300)
},
handleDialogCancel (done) {
this.$message({
message: '取消',
type: 'warning'
})
done()
},
handleRowEdit ({ index, row }, done) {
this.formOptions.saveLoading = true
this.addTemplate.data = row.data
this.addTemplate.name = row.name
this.addTemplate.address = row.address
TestUpdate(row.id, row).then(res => {
}).catch(err => {
console.log(err)
})
setTimeout(() => {
this.$message({
message: '編輯成功',
type: 'success'
})
done()
this.formOptions.saveLoading = false
this.test_get_list()
}, 300)
},
handleRowRemove ({ index, row }, done) {
TestDelete(row.id).then(res => {
}).catch(err => {
console.log(err)
})
setTimeout(() => {
console.log(index)
console.log(row)
this.$message({
message: '刪除成功',
type: 'success'
})
done()
this.test_get_list()
}, 300)
}
}
}
</script>
const frameIn = [
{
path: '/',
redirect: { name: 'index' },
component: layoutHeaderAside,
children: [
// 首頁
{
path: 'index',
name: 'index',
meta: {
auth: true
},
component: _import('system/index')
},
// 演示頁面
{
path: 'asset',
name: 'asset',
meta: {
title: '演示頁面',
auth: true
},
component: _import('asset/index')
},
{
path: 'log',
name: 'log',
meta: {
title: '前端日志',
auth: true
},
component: _import('system/log')
},
// 刷新頁面 必須保留
{
path: 'refresh',
name: 'refresh',
hidden: true,
component: _import('system/function/refresh')
},
// 頁面重定向 必須保留
{
path: 'redirect/:route*',
name: 'redirect',
hidden: true,
component: _import('system/function/redirect')
}
]
}
]
npm install
npm run dev
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。