哈嘍你們週一好,今天的內容比較多,主要就是包括:把前端頁面的展現頁給搭出來,而後調通接口API,能夠添加數據,這兩天我也一直在開發,原本想一篇一篇的寫,發現可能會比較簡單,就索性把項目搭建的過程簡化,一次寫好了,在開發 Nuxt.js 框架的過程當中,我發現相比以前仍是有些變化的,若是你是讀過我第一個先後端分離系列的小夥伴,可能看過我簡單說過Nuxt框架的一些知識《Nuxt.js 是什麼?》,我發現如今在項目搭建的過程當中,已經優化了一些功能,今天就重頭搭建一下。css
若是你沒有看過以前的文章,能夠簡單看看,主要是看看理論方面,若是是隻想看搭建過程,直接看這個便可了,畢竟如今已是最新的了,老的方案能夠捨棄,不過我的建議,前邊那幾篇能夠花幾分鐘看看,瞭解下,好比:什麼是SSR渲染,爲啥要使用它,是如何進行渲染的等等,畢竟不少基礎概念我這裏不會再說了,由於這是一個只有四篇的小系列,在上個系列都會有說到,這裏就很少敘述了,直接進行項目的搭建。html
今天是從簡到繁的過程,並不會把每一個頁面的說明都寫上,由於頁面是千篇一概的,項目設計只寫這一篇吧,下一篇重點說如何服務端部署。如今已經基本完成了(由於我尚未來得及發佈,若是你想如今查看具體的效果,能夠下載下來運行便可,注意要配置我們的Blog.Core 項目,也能夠關注的 Github 地址 https://github.com/anjoy8/Nuxt.tBug,這兩天我會發布一版本,在線地址:http://123.206.33.109:7090/):前端
這裏咱們就直接使用了官方腳手架工具建立,固然你也能夠一步一步的建立,手動建立比較麻煩,不適合新手,想了解更多,查看官網:新手模板。vue
這裏默認你的電腦上已經安裝了 npm 環境了,若是不肯定是否安裝了,能夠查使用命令查看 npm -v:ios
不只如此,若是你想使用官方腳手架搭建項目,要確保npm版本在 5.2+ ,目前已是6.5.0了,個人本地是 5.6.0 ,符合要求,開始動手搭建。git
首先你找好一個放置你項目的文件夾做爲你的倉庫,而後經過CMD或者 PowerShell 來建立項目,很簡單 :github
npx create-nuxt-app 項目名
在安裝的過程當中,會出現幾個選項,這裏先放上個人動圖,具體如何選,圖下我會解釋:web
具體的選擇是這樣的:數據庫
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 樣式框架。這相對之前的版本,已經有很大的改觀了,我認爲很棒的。npm
這樣咱們就等待安裝成功了,中間可能大概須要2~5分鐘,看我的網絡而定。
安裝好後,咱們會看到生成的所有文件夾,並且是已經安裝好依賴包的:
若是你稍微有一些 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 結構對比下,看看少了一個什麼配置。
你們看上邊的文檔架構層次圖,你可能會發現,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' } ] }
具體的請查看官網:路 由
我在webstorm 中運行上邊搭建好的項目,能夠看到初始歡迎頁:
下邊咱們就正式對這個頁面進行完善,進行總體設計。
下邊我就簡要的寫了,具體的代碼,請看個人 Github 地址就行。我這裏先把 pages/index.vue 的默認內容清空,
這個時候你能夠先練習練習,佈局頁面在哪裏配置?先停下來想想,或者看看剛剛建立的文件夾,沒錯,就是 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 中引用麼,但是你爲啥直接就能夠用呢?能提這個問題的,表示真的是已經看懂了,彆着急,請往下看。
首先,咱們應該清楚插件是什麼?
插件其實就是一個 .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 了專題的數據,剩下的就是首頁結構了。
這裏由於和 vue 中開發組件或頁面是同樣的,就很少說了,具體的代碼能夠參考個人 Github 代碼,這裏把結構說一下:
其中最重要的,就是 asyncData 異步數據加載,這個和 vue 仍是不一樣的:
asyncData
方法會在組件(限於頁面組件)每次加載以前被調用。它能夠在服務端或路由更新以前被調用。 在這個方法被調用的時候,第一個參數被設定爲當前頁面的上下文對象,你能夠利用asyncData
方法來獲取數據,Nuxt.js 會將asyncData
返回的數據融合組件data
方法返回的數據一併返回給當前組件。
是在頁面加載以前,加載數據,而後融合着 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"] },
除了上邊的首頁之外,還有詳情頁,分類頁,以及數據添加頁,這裏就過多的說明了,其中主要說的是:
這個其實很簡單的,就是在 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 上拉加載很類似,具體的能夠查看個人代碼。
這裏若是你有必定的 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() 是很像的,經過操做,把數據返回到頁面裏,這裏只是要注意兩點:
一、必定要是異步的 await;
二、必定注意返回的數據格式,你能夠用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 數據,相信很快你會遊刃有餘了。
關於富文本編輯器,我也找了幾個作對比,由於平時更喜歡用 markdown ,因此,就選用了這個 mavon-editor 編輯器了,使用方法很簡單,仍是插件三步走:
一、安裝依賴:
npm install mavon-editor --save
二、在plugins中建立vue-markdown.js
import Vue from 'vue' import mavonEditor from 'mavon-editor' Vue.use(mavonEditor)
三、在nuxt.config.js中引入
具體如何在詳情頁展現呢,我用的是 highlight.js 和 marked 來實現的,使用方法很簡單,安裝過包之後,在頁面內引用,而後對咱們添加的 content 代碼進行 marked() 方法便可,具體使用請查看個人代碼。
這個上傳圖片仍是比較簡單的,只不過須要有一些細節須要注意下,我這裏有兩個版本的上傳圖片的方法 ,一個是 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; } }
而後看看前端是怎麼操做的:
一、element-ui 的 upload 上傳圖片方法:
這個很簡單,官方栗子中,已經說的很明白了,幾乎不用作任何的修改就能達到目的,只須要咱們修改下後端的api地址便可,注意這裏有跨域的問題,我直接用的是本地代理的地址:
注意注意下邊三個問題就好了:
一、接口地址配置在 action;
二、必定要跨域,本項目使用的是本地代理 proxy,你也可使用後端的CORS實現跨域;
三、記得要在後端配置使用靜態資源文件 app.UseStaticFiles(); ,由於我把圖片放到了wwwroot裏了;
其餘的和官方地址如出一轍的。http://element-cn.eleme.io/#/zh-CN/component/upload
二、mavon 富文本編輯器上傳圖片 :
這個徹底照搬官方文檔便可,幾乎不用修改什麼,只不過注意事項仍是上邊的那三個,跨域+靜態資源使用,很少說:圖片上傳詳情點擊這裏...,或者看個人Github代碼。
我這裏使用了異步的統一泛型返回數據模型,你們也都能看懂,由於第一個系列已經說的不少了:
/// <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")],數據庫配置,我本地簡單試了試,仍是挺好用的,到時候也會嘗試下滑動過時等問題的解決方案。
到這裏咱們已經把項目的結構定義好了,並且也自適應了設備,內容簡單,主要的就是講解了:
一、如何經過 nuxt 官方腳手架搭建項目;二、頁面是如何加載的;三、插件的使用;四、異步數據運行;五、使用富文本編輯器以及上傳圖片等等,做爲展現。
這幾天把總體頁面都設計好了,也上傳到Github上了,下篇開始部署,發佈到服務器。