前言
哈嘍大家周一好,今天的內容比較多,主要就是包括:把前端頁面的展示頁給搭出來,然后調通接口API,可以添加數據,這兩天我也一直在開發,本來想一篇一篇的寫,發現可能會比較簡單,就索性把項目搭建的過程簡化,一次寫好了,在開發 Nuxt.js 框架的過程中,我發現相比之前還是有些變化的,如果你是讀過我第一個前后端分離系列的小伙伴,可能看過我簡單說過Nuxt框架的一些知識《Nuxt.js 是什么?》,我發現現在在項目搭建的過程中,已經優化了一些功能,今天就重頭搭建一下。
如果你沒有看過之前的文章,可以簡單看看,主要是看看理論方面,如果是只想看搭建過程,直接看這個即可了,畢竟現在已經是最新的了,老的方案可以舍棄,不過個人建議,前邊那幾篇可以花幾分鍾看看,了解下,比如:什么是SSR渲染,為啥要使用它,是如何進行渲染的等等,畢竟很多基礎概念我這里不會再說了,因為這是一個只有四篇的小系列,在上個系列都會有說到,這里就不多敘述了,直接進行項目的搭建。
今天是從簡到繁的過程,並不會把每個頁面的說明都寫上,因為頁面是千篇一律的,項目設計只寫這一篇吧,下一篇重點說如何服務端部署。現在已經基本完成了(因為我還沒有來得及發布,如果你想現在查看具體的效果,可以下載下來運行即可,注意要配置咱們的Blog.Core 項目,也可以關注的 Github 地址 https://github.com/anjoy8/Nuxt.tBug,這兩天我會發布一版本,在線地址:http://123.206.33.109:7090/):

一、Nuxt項目搭建
1、通過腳手架工具初始化項目
這里我們就直接使用了官方腳手架工具創建,當然你也可以一步一步的創建,手動創建比較麻煩,不適合新手,想了解更多,查看官網:新手模板。
這里默認你的電腦上已經安裝了 npm 環境了,如果不確定是否安裝了,可以查使用命令查看 npm -v:

不僅如此,如果你想使用官方腳手架搭建項目,要確保npm版本在 5.2+ ,目前已經是6.5.0了,我的本地是 5.6.0 ,符合要求,開始動手搭建。
首先你找好一個放置你項目的文件夾作為你的倉庫,然后通過CMD或者 PowerShell 來創建項目,很簡單 :
npx create-nuxt-app 項目名
在安裝的過程中,會出現幾個選項,這里先放上我的動圖,具體如何選,圖下我會解釋:

具體的選擇是這樣的:
Project name TiBug.Nuxt //項目名稱 Project description //項目描述 Use a custom server framework //選擇通用的服務端渲染模板框架:none,是默認服務 Nuxt default serve Use a custom UI framework //選擇通用UI框架:Element Choose rendering mode //選擇渲染模式:SSR或SPA Use axios module //是否使用 axios 進行http請求:yes Use eslint //是否使用代碼格式糾錯: no,會各種格式警告 Use prettier //是否代碼美化:yes Author name //作者名 Choose a package //選擇一個包管理:npm
你可以根據情況自己去選擇,比如你不喜歡用 nuxt 自帶的服務器渲染,想使用 Express ,比如你可以直接在這里就選擇好你喜歡的樣式,比如我就喜歡 ElementUI 樣式框架。這相對以前的版本,已經有很大的改觀了,我認為很棒的。
這樣我們就等待安裝成功了,中間可能大概需要2~5分鍾,看個人網絡而定。
2、項目整體目錄結構
安裝好后,我們會看到生成的全部文件夾,而且是已經安裝好依賴包的:

如果你稍微有一些 Vue 的開發經驗,應該都能知道大概的文件夾包含的意思,比如Component,Pages,Store等,咱們具體說說每一個文件夾都是干啥的:
├── assets // 資源文件。用於組織未編譯的靜態資源入LESS、SASS 或 JavaScript │ └── logo.jpg // 默認logo圖片 ├── components // 組件。用於自己編寫的Vue組件,比如滾動組件,日歷組件,分頁組件 │ └── AppLogo.vue // 默認logo組件 ├── layouts // 布局。頁面都需要有一個布局,默認為 default。它規定了一個頁面如何布局頁面。所有頁面都會加載在布局頁面中的 <nuxt /> 標簽中。 │ └── default.vue // 默認模板頁面,類似mvc中的layout ├── middleware // 中間件。存放中間件。可以在頁面中調用: middleware: 'middlewareName' 。 ├── pages // 頁面。一個 vue 文件即為一個頁面。 │ └── index.vue // 默認首頁面 ├── plugins // 用於存放JavaScript插件的地方 │ └── element-ui.js // 上邊我們安裝的UI框架 ├── static // 用於存放靜態資源文件,比如圖片,此類文件不會被 Nuxt.js 調用 Webpack 進行構建編譯處理。 服務器啟動的時候,該目錄下的文件會映射至應用的根路徑 / 下。 ├── store // 用於組織應用的Vuex 狀態管理。 ├── .editorconfig // 開發工具格式配置 ├── .eslintrc.js // ESLint的配置文件,用於檢查代碼格式 ├── .gitignore // 配置git不上傳的文件 ├── nuxt.config.js // 用於組織Nuxt.js應用的個性化配置,比如網站title,已便覆蓋默認配置 ├── package.json // npm包管理配置文件 └── README.md // 說明文檔
其實整理看起來,和之前的沒多少差別,至少在頁面結構上沒太大差別,主要更新是把項目搭建前的配置交給了開發者了,不過有一個地方是被去掉了的,你先和 Vue 結構對比下,看看少了一個什么配置。
3、路由根據頁面定
大家看上邊的文檔架構層次圖,你可能會發現,nuxt 和 vue 還是有些不一樣的,這里沒有了 路由Route 的配置,發現了么?
這個就是 nuxt 框架的獨到之處,為了能實現更好的SSR渲染,它使用的是根據頁面結構,自動路由,所以你的文件名,就是你的路由名稱:
在 Nuxt.js 里面定義帶參數的動態路由,需要創建對應的以下划線作為前綴的 Vue 文件 或 目錄。
以下目錄結構:
pages/ --| _slug // 以下划線開頭的文件夾,代表參數 -----| comments.vue -----| index.vue --| users/ -----| _id.vue //以 下划線 開頭的頁面,動態路由 --| index.vue
Nuxt.js 生成對應的路由配置表為:
router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'users-id', path: '/users/:id?', component: 'pages/users/_id.vue' }, { name: 'slug', path: '/:slug', component: 'pages/_slug/index.vue' }, { name: 'slug-comments', path: '/:slug/comments', component: 'pages/_slug/comments.vue' } ] }
具體的請查看官網:路 由
4、項目加載歡迎頁面
我在webstorm 中運行上邊搭建好的項目,可以看到初始歡迎頁:

下邊我們就正式對這個頁面進行完善,進行整體設計。
二、首頁結構布局
下邊我就簡要的寫了,具體的代碼,請看我的 Github 地址就行。我這里先把 pages/index.vue 的默認內容清空,
1、創建布局模板
這個時候你可以先練習練習,布局頁面在哪里配置?先停下來想一想,或者看看剛剛創建的文件夾,沒錯,就是 layouts 文件夾下的 default.vue 頁面,咱們看看這個初始的是什么樣子:
<template>
<div>
<nuxt/> //這個就是頁面入口,其他頁面就是在這里進行嵌入的,可以對比MVC中 layout.cshtml 中的 @RenderBody()
</div>
</template>
<style>
</style>
我們直接對其進行改造,設計模板結構,
<template> <div id="app"> <el-row :gutter="0" > <el-col class="nav"> <el-col class="nav-bar" :sx="22" :sm="22" :md="22" :lg="16"> <div class="nav-bar-body"> <div class="nav-bar-inner"> <div id="logo"> <img src="../assets/logoa.png" /> </div> </div> ............ </el-row> <div class="footer">京ICP備xxxxxxxx號</div> </div> </template>
因為我已經在安裝的時候,選擇了ElementUI 框架,所以可以直接使用相關 el 組件,而不用在各種配置和引用了,你一定會問:之前在開發 Vue 的時候,也使用過 ElementUI 呀,不是應該先安裝,然后在 Mian.js 中引用么,可是你為啥直接就可以用呢?能提這個問題的,表示真的是已經看懂了,別着急,請往下看。
2、插件是如何運行的
首先,我們應該清楚插件是什么?
插件其實就是一個 .js 文件,將我們需要的組件注入到我們的項目中去,可拔插,很方便替換任何一個我們需要的。
其實,我們應該了解插件是在哪里定義:
(同樣,你這里也可以先停一停,自己去文件夾里找找,感覺哪一個像是定義插件的),在腳手架整體結構中,我們知道每一個文件夾都有自己的作用,其中 plugins 文件夾,就是用來存放我們的插件的,插件目錄 plugins 用於組織那些需要在 根vue.js應用 實例化之前需要運行的 Javascript 插件。說人話就是,我們的vue項目想要運行,必須實例化 vue,這個大家肯定都知道,那實例化之前,當然就必須要加載插件了,就是這個目的。
我們在上邊用官方腳手架搭建的時候,已經安裝了 elementUI 的插件,所以我們會在 plugins 文件夾里,看到這個 elemengt-ui.js 文件:

以后我們如果還需要建立其他組件的話,都在這里處理,比如以后我們會對axios請求訪問進行封裝插件,如果你不是很明白,這里舉個栗子:
如果你是一直看我的文章,一定知道我在第一個系列的 Vue 項目里,為了進行 axios 請求,創建了一個 http.js 的問題,這個其實就是一個插件:

我定義好以后,並在 main.js 中注冊引入,這樣在其他頁面內,就可以隨心使用了。
最后,我們應該知道如何注冊這些插件:
這個時候,就用到我們的配置文件: nuxt.config.js 了,這里邊就是我們整個項目的配置文件,比如 head 中的 title 、icon呀,還有css,還有跨域本地代理,最后,當然就是我們的插件注冊了:

這個時候,我們重新運行下我們的項目(注意:如果修改了nuxt.config.js,要重新編譯下),這個時候我們看下效果:


嗯,很正常的顯示了,並且已經支持了SSR渲染,感覺很開心,就是樣式太丑,那我們就需要添加進一個樣式文件,在根目錄下新建 style 文件夾,並添加 style.css,具體的直接從 Github 拉取即可,不過,不僅僅要添加這個文件,還要在配置文件中,進行注冊引用,

頁面 Banner 最終的效果是這樣的:

我們頁面的模板已經加載好了,並且也 mock 了專題的數據,剩下的就是首頁結構了。
3、首頁正文結構布局
這里因為和 vue 中開發組件或頁面是一樣的,就不多說了,具體的代碼可以參考我的 Github 代碼,這里把結構說一下:

其中最重要的,就是 asyncData 異步數據加載,這個和 vue 還是不同的:
asyncData方法會在組件(限於頁面組件)每次加載之前被調用。它可以在服務端或路由更新之前被調用。 在這個方法被調用的時候,第一個參數被設定為當前頁面的上下文對象,你可以利用asyncData方法來獲取數據,Nuxt.js 會將asyncData返回的數據融合組件data方法返回的數據一並返回給當前組件。
4、異步數據加載
是在頁面加載之前,加載數據,然后融合着 data ,一起返回,最后渲染頁面。注意:由於asyncData方法是在組件 初始化 前被調用的,所以在方法內是沒有辦法通過 this 來引用組件的實例對象。
我這里通過編譯后的代碼,可以看到是異步請求數據是這樣的,下文中,我會配合着 axios 異步請求,一起說說:
data: function data() { return { data: 0, }; }, asyncData: function () { var _asyncData = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2___default()( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(_ref) { var params, tag, _ref2, data; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: params = _ref.params; _context.prev = 1; tag = params.tag; _context.next = 5;//axios http數據請求 return _plugins_axios__WEBPACK_IMPORTED_MODULE_3__["default"].get("/api/TopicDetail?page=1&tname=".concat(tag)); case 5: _ref2 = _context.sent; data = _ref2.data.data; console.log(data); debugger; return _context.abrupt("return", { tagList: data.data, tagtitle: tag, fadetitle: true, notfound: !data.data.length }); case 12: _context.prev = 12; _context.t0 = _context["catch"](1); case 14: case "end": return _context.stop(); } } }, _callee, this, [[1, 12]]); })); function asyncData(_x) { return _asyncData.apply(this, arguments); } return asyncData; }(), components: { ArticleList: _components_ArticleList__WEBPACK_IMPORTED_MODULE_4__["default"] },
三、其他頁面說明
除了上邊的首頁以外,還有詳情頁,分類頁,以及數據添加頁,這里就過多的說明了,其中主要說的是:
1、上拉加載分頁
這個其實很簡單的,就是在 mounted() 中,注冊瀏覽器滾動事件就好了,如果這里你不知道 mounted 是vue生命周期的什么時候的話,就應該好好的再學學了,因為生命周期鈎子是很重要的,至少我個人任務是這樣的:
在created的時候,視圖中的html並沒有渲染出來,所以此時如果直接去操作html的dom節點,一定找不到相關的元素而在 mounted中,由於此時html已經渲染出來了,所以可以直接操作dom節點。
這個時候我們就自定義事件:
//頁面渲染完畢后,監聽滾動事件 mounted() { window.addEventListener('scroll', this.handleScroll) }, methods: { //處理方法,在頁面具體底部30像素的時候,觸發事件 handleScroll() { const jrscrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollT let scrollBottom = document.body.clientHeight - window.innerHeight - jrscrollTop if (scrollBottom < 30) { if (this.ScrollFirst) { this.nextpage() //觸發這個,下拉加載分頁事件 } } } }, //記得在銷毀當前頁面的時候,也就是切換的時候,把監聽去掉 beforeDestroy() { window.removeEventListener('scroll', this.handleScroll, fa }
整體很簡單,和我們的平時的 JS 上拉加載很相似,具體的可以查看我的代碼。
2、設計 axios 插件對接API(兩種方式)
這里如果你有一定的 Vue 開發基礎,應該能會八成以上,為什么是八成呢,因為可能還是會有一些小問題需要注意,比如重點的就是異步數據加載了。
因為 Nuxt.js 是基於SSR渲染的,所以必須先獲取到數據,然后生成 Html 片,才能去渲染,這個和客戶端渲染還是不一樣的,客戶端兩者可以同步,甚至先渲染,再去進行 axios 數據請求,但是這樣不能實現 SEO 的作用,所以就在原先 axios 請求的基礎上,封裝了一個異步請求,這樣就能達到目的。但是這個在使用的時候,可能不是很順手,因為很多人已經習慣了直接用當然組件的 data() 中的數據了,在上邊我們也看到了,asyncData 編譯后的模板,它其實也是當前組件頁面中 data 的一部分,我們甚至就可以當成 data 來使用,只不過這個data里,可以寫邏輯,可以進行 axios 異步請求,那下邊咱們就看看具體用法:
首先我們應該說說如何定義這個插件,當然,我們在每一個頁面,通過引入 axios 也行,但是這樣有一些問題,除了不方便以為,還有一個就是無法定義一些公共的東西,比如 api 域名路徑,所以,我們需要定義一個插件:
A:首先,我們在 plugins 文件夾中定義 axios.js 插件:
import axios from 'axios'//引入 axios 服務 let options = {} if (process.server) { // 配置基路由 options.baseURL = 'http://localhost:5000' // http://123.xx.xx.xx:5000(服務端地址) } export default axios.create(options) // 注意這里是直接 export 了一個對象實例,而不是 Vue.use,這個插件不需要注冊
B:在頁面中使用:

這里聰明的你可能看到了,為什么沒有像 element-ui 插件那樣,沒有在 nuxt.config.js 中配置這個插件???
這里說下,因為這里是直接返回的一個對象,我們不需要關心是不是要去安裝它,它不像 element和下邊的markdown那樣,我們只有安裝了才能用,因為element和 markdown 不是一個返回值的狀態,而是 Vue.use ,是直接集成到了 vue 對象內的,所以需要在項目配置文件中進行安裝,這里的 axios.js 插件就不需要安裝,如果你還不明白的話,我用 http.js 也封裝了一個插件,一個就像 element那樣,集成到vue 的插件:

這樣的話,我們在組件頁面中,就可以直接這么用:
const {data: {response}} = await Vue.http.get('/api/TopicDetail/'+ id);//這個就是使用到了 Vue 對象
所以這個就需要安裝,因為我們必須在 app(也就是vue)被實例化之前,安裝這個插件:

如果你還看不懂 axios.js插件(返回對象,可直接使用)和 http.js插件(集成到vue對象里,需要注冊),這兩者之間的區別的話,請留言,或者加群,我詳細給你說說。
C:最后為了使用接口,我們需要進行跨域,使用 proxy 代理:
proxy: [ ['/api', { target: 'http://localhost:5000' }], ['/images', { target: 'http://localhost:5000' }],// 將圖片也代理到本地,下文的<上傳圖片>欄目會說到 // ['/api', { target: 'http://123.xx.xx.xx:3080' }],//服務端配置 ]
//還有這里
modules: [
// Doc: https://github.com/nuxt-community/axios-module#usage
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
D:接下來我們就說說如何進行異步獲取數據
就拿我們的首頁數據加載來說,我們的需求是加載出來全部的 Bug 數據,首先 index.vue 中肯定有一些基本的數據,比如當前頁數等常量參數,這些參數不需要我們異步去獲取,因為它們在頁面渲染之前已經被定義了:
//當前組件中的數據變量 data() { return { page: 0, lastpage: true, ScrollFirst: true, }; },
但是,上邊我們也說了,我們為了實現 SSR 渲染,必須在渲染前就要異步獲取數據,所以這里我們就使用到了異步數據加載 asyncData:
// 一共有三種方法,這個最常用的一種方法,asyncData() 方法 async asyncData({ params }) { try { // 路由參數 const { tag } = params // 獲取異步得到的數據,必須使用 {} 大括號包裹 let { data } = await axios.get(`/api/TopicDetail/24`) console.log(data) // 如果想要獲取返回數據 data 中的某一個屬性,可以這么嵌套 const { data: { article } } = await axios.get(`/api/TopicDetail?page=1`) console.log(article) // 然后將得到的數據返回過去,其實和本身的 data() 有異曲同工之妙 return { articleList: article, tagtitle: tag, fadetitle: true, notfound: !article.length } } catch (err) { error({statusCode: 404}) } },
提示:如果你不需要使用異步的話,直接用 let data= axios.get(`/api/TopicDetail/24`) 就可以了。
其實通過這里,你應該也能看的明白,這個異步獲取數據,本身和 data() 是很像的,通過操作,把數據返回到頁面里,這里只是要注意兩點:
1、一定要是異步的 await;
2、一定注意返回的數據格式,你可以用debugger 或者 console 來查看,也可以直接用 mock 數據測試。
最后,就是像 data 數據一樣,直接在頁面其他地方進行使用了,
<el-col :xs="24" :sm="24" :md="24" :lg="12" v-for="item in articleList" :key="item.id" class="artitem" >
如果你是第一次使用,肯定會遇到找不到數據而報錯的情況,用我說的方法,斷點調試+mock 數據,相信很快你會游刃有余了。
3、選擇Mavon-Editor富文本編輯器
關於富文本編輯器,我也找了幾個做對比,因為平時更喜歡用 markdown ,所以,就選用了這個 mavon-editor 編輯器了,使用方法很簡單,還是插件三步走:
1、安裝依賴:
npm install mavon-editor --save
2、在plugins中創建vue-markdown.js
import Vue from 'vue' import mavonEditor from 'mavon-editor' Vue.use(mavonEditor)
3、在nuxt.config.js中引入

具體如何在詳情頁展示呢,我用的是 highlight.js 和 marked 來實現的,使用方法很簡單,安裝過包以后,在頁面內引用,然后對我們添加的 content 代碼進行 marked() 方法即可,具體使用請查看我的代碼。
4、上傳圖片
這個上傳圖片還是比較簡單的,只不過需要有一些細節需要注意下,我這里有兩個版本的上傳圖片的方法 ,一個是 element-upload 上傳用戶頭像的,一個是 mavon 富文本編輯器中的上傳圖片的方法,后台方法是同一個,只不過前端控制稍微不同罷了,這里先說下后端API:
[HttpPost] [Route("Pic")] public async Task<MessageModel<string>> InsertPicture([FromServices]IHostingEnvironment environment) { var data = new MessageModel<string>(); string path = string.Empty; string foldername = "images"; var files = Request.Form.Files; if (files == null || files.Count() <= 0) { data.Msg = "請選擇上傳的文件。"; return data; } //格式限制 var allowType = new string[] { "image/jpg", "image/png", "image/jpeg" }; string folderpath = Path.Combine(environment.WebRootPath, foldername); if (!System.IO.Directory.Exists(folderpath)) { System.IO.Directory.CreateDirectory(folderpath); } if (files.Any(c => allowType.Contains(c.ContentType))) { if (files.Sum(c => c.Length) <= 1024 * 1024 * 4) { //foreach (var file in files) var file = files.FirstOrDefault(); string strpath = Path.Combine(foldername, DateTime.Now.ToString("MMddHHmmss") + file.FileName); path = Path.Combine(environment.WebRootPath, strpath); using (var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { await file.CopyToAsync(stream); } data = new MessageModel<string>() { Response = strpath, Msg = "上傳成功", Success = true, }; return data; } else { data.Msg = "圖片過大"; return data; } } else { data.Msg = "圖片格式錯誤"; return data; } }
然后看看前端是怎么操作的:
1、element-ui 的 upload 上傳圖片方法:
這個很簡單,官方栗子中,已經說的很明白了,幾乎不用做任何的修改就能達到目的,只需要我們修改下后端的api地址即可,注意這里有跨域的問題,我直接用的是本地代理的地址:

注意注意下邊三個問題就行了:
1、接口地址配置在 action;
2、一定要跨域,本項目使用的是本地代理 proxy,你也可以使用后端的CORS實現跨域;
3、記得要在后端配置使用靜態資源文件 app.UseStaticFiles(); ,因為我把圖片放到了wwwroot里了;
其他的和官方地址一模一樣的。http://element-cn.eleme.io/#/zh-CN/component/upload
2、mavon 富文本編輯器上傳圖片 :
這個完全照搬官方文檔即可,幾乎不用修改什么,只不過注意事項還是上邊的那三個,跨域+靜態資源使用,不多說:圖片上傳詳情點擊這里...,或者看我的Github代碼。
四、服務端接口設計
1、設計統一數據結構接口
我這里使用了異步的統一泛型返回數據模型,大家也都能看懂,因為第一個系列已經說的很多了:
/// <summary> /// 獲取Bug數據列表(帶分頁) /// </summary> /// <param name="page">頁數</param> /// <param name="tname">專題類型</param> /// <returns></returns> [HttpGet] public async Task<MessageModel<PageModel<TopicDetail>>> Get(int page = 1, string tname = "") { var data = new MessageModel<PageModel<TopicDetail>>(); int intTotalCount = 6; int TotalCount = 0; int PageCount = 1; List<TopicDetail> topicDetails = new List<TopicDetail>(); //總數據,使用AOP切面緩存 topicDetails = await _topicDetailServices.GetTopicDetails(); if (!string.IsNullOrEmpty(tname)) { var tid = (await _topicServices.Query(ts => ts.tName == tname)).FirstOrDefault()?.Id.ObjToInt(); topicDetails = topicDetails.Where(t => t.TopicId == tid).ToList(); } //數據總數 TotalCount = topicDetails.Count; //總頁數 PageCount = (Math.Ceiling(topicDetails.Count.ObjToDecimal() / intTotalCount.ObjToDecimal())).ObjToInt(); //當前頁數據 topicDetails = topicDetails.OrderByDescending(d => d.Id).Skip((page - 1) * intTotalCount).Take(intTotalCount).ToList(); return new MessageModel<PageModel<TopicDetail>>() { Msg = "獲取成功", Success = topicDetails.Count >= 0, Response = new PageModel<TopicDetail>() { page = page, pageCount = PageCount, dataCount = TotalCount, data = topicDetails, } }; }
通用返回信息類 和 通用分頁類:
/// <summary> /// 通用返回信息類 /// </summary> public class MessageModel<T> { /// <summary> /// 操作是否成功 /// </summary> public bool Success { get; set; } = false; /// <summary> /// 返回信息 /// </summary> public string Msg { get; set; } = "服務器異常"; /// <summary> /// 返回數據集合 /// </summary> public T Response { get; set; } } /// <summary> /// 通用分頁信息類 /// </summary> public class PageModel<T> { /// <summary> /// 當前頁數 /// </summary> public int page { get; set; } = 1; /// <summary> /// 總頁數 /// </summary> public int pageCount { get; set; } = 6; /// <summary> /// 數據總數 /// </summary> public int dataCount { get; set; } = 0; /// <summary> /// 返回數據 /// </summary> public List<T> data { get; set; } }
五、對接口進行配置權限
因為我們的TiBug 1.0 還沒有設計用戶登錄問題,所以,這一塊還沒有,不過別慌,過些天我會加上,這幾天先把1.0版本發布到服務器。
然后開始開發 TiBug 1.5版本,設計管理后台,初步是基於VueAdmin的,主要是用戶管理和Bug管理,權限管理等,大家也看到了,目前的版本是只能添加不能修改,還是基於我們之前設計的 [Authorize("Permission")],數據庫配置,我本地簡單試了試,還是挺好用的,到時候也會嘗試下滑動過期等問題的解決方案。
六、結語
到這里我們已經把項目的結構定義好了,而且也自適應了設備,內容簡單,主要的就是講解了:
1、如何通過 nuxt 官方腳手架搭建項目;2、頁面是如何加載的;3、插件的使用;4、異步數據運行;5、使用富文本編輯器以及上傳圖片等等,作為展示。
這幾天把整體頁面都設計好了,也上傳到Github上了,下篇開始部署,發布到服務器。
七、Github
https://github.com/anjoy8/Nuxt.tBug
https://github.com/anjoy8/Blog.Core
