1 Vue.js與Webpack研究
1.1 vue.js介紹
是一套用於構建用戶界面的漸進式框架,漸進式框架的意思是可以使用vue.js一兩個特性也可以整個項目都用vue.js,一步一步構建,不要求你一下子全都用vue.js
vue.js有什麼用?
1)聲明式渲染
Vue.js 的核心是一個允許採用簡潔的模板語法來聲明式地將數據渲染進 DOM 的系統。
比如:使用vue.js的插值表達式放在Dom的任意地方, 差值表達式的值將被渲染在Dom中。
2)條件與循環
dom中可以使用vue.js提供的v-if、v-for等標籤,方便對數據進行判斷、循環。
3)雙向數據綁定
Vue 提供v-model 指令,它可以輕鬆實現Dom元素和數據對象之間雙向綁定,即修改Dom元素中的值自動修改綁定的數據對象,修改數據對象的值自動修改Dom元素中的值。
4)處理用戶輸入
爲了讓用戶和你的應用進行交互,我們可以用 v-on 指令添加一個事件監聽器,通過它調用在 Vue 實例中定義的方法
5)組件化應用構建
vue.js可以定義一個一個的組件,在vue頁面中引用組件,這個功能非常適合構建大型應用。
怎麼使用Vue.js?
1)在html頁面使用script引入vue.js的庫即可使用。
2)使用Npm管理依賴,使用webpack打包工具對vue.js應用打包。大型應用推薦此方案。
3)Vue-CLI腳手架,使用vue.js官方提供的CLI腳本架很方便去創建vue.js工程雛形。
1.2 vue.js基礎
1.2.1 MVVM模式
vue.js是一個MVVM的框架
MVVM拆分解釋爲:
Model:負責數據存儲
View:負責頁面展示
View Model:負責業務邏輯處理(比如Ajax請求等),對數據進行加工後交給視圖展示
MVVM要解決的問題是將業務邏輯代碼與視圖代碼進行完全分離,使各自的職責更加清晰,後期代碼維護更加簡單
從上圖看出,VM(ViewModel)可以把view視圖和Model模型解耦合,VM的要做的工作就是vue.js所承擔的。
1.2.2 入門程序
本次測試我們在門戶目錄中創建一個html頁面進行測試,正式的頁面管理前端程序會單獨創建工程。
結果:
vue.js常用指令:
1、v-model
v-model僅能在如下元素中使用:
input
select
textarea
components(Vue中的組件)
2、v-text
v-text可以將一個變量的值渲染到指定的元素中,它可以解決插值表達式閃爍的問題,若不用的話則用戶在打開網頁時網速慢的時候會顯示出差值表達式
3、v-on(可以不加v-on,直接寫一個@號)
綁定一個按鈕的單擊事件
現在,從以下可以看出,用vue.js的好處:
4、v-bind(可以不加v-bind,直接寫一個冒號)
作用:
v‐bind可以將數據對象綁定在dom的任意屬性中。
v‐bind可以給dom對象綁定一個或多個特性,例如動態綁定style和class
5、v-if和v-for
1.3 webpack入門
使用vue.js開發大型應用需要使用webpack打包工具
1.3.1 webpack介紹
Webpack 是一個前端資源的打包工具,它可以將js、image、css等資源當成一個模塊進行打包。
作用:
1、模塊化開發
程序員在開發時可以分模塊創建不同的js、 css等小文件方便開發,最後使用webpack將這些小文件打包成一個文件,減少了http的請求次數。
webpack可以實現按需打包,爲了避免出現打包文件過大可以打包成多個文件。
2、將高級的js、css語法打包轉換成瀏覽器可識別的js、css語法
使用:
webpack基於node.js運行,首先需要安裝node.js
node.js是一個JavaScript的運行環境,是一個運行在服務端的框架,用它的好處就是前端和後端都可以採用javascript,即開發一份js程序即可以運行在前端也可以運行的服務端
JavaScript與node.js 關係可類似爲 Java與jdk
然後需要安裝npm(node.js已經集成了npm工具),它是node包管理和分發的工具,node.js用npm來安裝我們所依賴的jar包(比如webpack)
(功能和服務端項目構建工具maven差不多,我們通過npm 可以遠程下載js庫,打包js文件)
不過我們用cnpm,它可以從國內鏡像下載js包
先將nrm指向淘寶鏡像再安裝cnpm,以後需要時再用cnpm下載js
現在可以安裝webpack了
使用過程:
首先先在門戶工程下創建一個文件夾,然後拷貝之前寫好的程序用於測試:
定義model.js:
將本程序使用的加法運算的js方法抽取到一個js文件,此文件就是一個模塊
定義main.js:
main.js是本程序的入口文件
1、在此文件中會引用model01.js模塊
2、引用vue.min.js(它也一個模塊)
3、將html頁面中構建vue實例的代碼放在main.js中。
現在vue_02.html裏的script什麼都沒有:
與沒用webpack前的對比:
至此代碼部分完成
然後進webpacktest01文件夾打開命令行輸入打包語句:
這段指令表示將main.js打包輸出爲 build.js文件
此時工程目錄中就會多出一個build.js文件:
然後在vue_02.html裏引用這個文件:
1.3.2 webpack-dev-server
webpack-dev-server開發服務器,它的功能可以實現熱加載 並且自動刷新瀏覽器
使用 webpack-dev-server需要安裝webpack、 webpack-dev-server和 html-webpack-plugin三個包,然後在package.json中配置script,在webpack.config.js配置模板文件、html-webpack-plugin插件
創建一個文件目錄:
dist放打包好的文件,src放源代碼,html放在大文件夾下面與dist、src同級
1、安裝webpack-dev-server
使用 webpack-dev-server需要安裝webpack、 webpack-dev-server和 html-webpack-plugin三個包。
進入到這個目錄下:
cnpm install [email protected] [email protected] [email protected] --save-dev
安裝完成,會發現程序目錄出現一個package.json文件,此文件中記錄了程序的依賴。
2、配置webpack-dev-server
在package.json中配置script
"scripts": {
"dev": "webpack-dev-server --inline --hot --open --port 5008"
},
–inline:自動刷新
–hot:熱加載
–port:指定端口
–open:自動在默認瀏覽器打開
–host:可以指定服務器的 ip,不指定則爲127.0.0.1,如果對外發布則填寫公網ip地址
3、配置webpack.config.js
在webpacktest02目錄下創建 webpack.config.js, webpack.config.js是webpack的配置文件
var htmlwp = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js', //指定打包的入口文件
output: {
path: __dirname + '/dist', // 注意:__dirname表示webpack.config.js所在目錄的絕對路徑
filename: 'build.js' //輸出文件
},
plugins: [
new htmlwp({
title: '首頁', //生成的頁面標題<head><title>首頁</title></head>
filename: 'index.html', //webpack-dev-server在內存中生成的文件名稱,自動將build注入到這個頁面底部,才能實現自動刷新功能
template: 'vue_02.html' //根據vue_02.html這個模板來生成(這個文件請程序員自己生成)
})
]
}
4、注意html
把script去掉
啓動:
雙擊dev:
啓動成功自動打開瀏覽器:
此時修改src中的任意文件內容,它會自動加載並刷新瀏覽器。
總結:
2 CMS前端工程創建
2.1 導入系統管理前端工程
CMS系統使用Vue-cli腳手架創建, Vue-cli是Vue官方提供的快速構建單頁應用的腳手架
2.2.1 工程結構
如果我要基於Vue-Cli創建的工程進行開發還需要在它基礎上作一些封裝,下面是資料中提供的Vue-Cli封裝工程:(這個工程和門戶工程有區別)
其中src目錄下存放頁面及js代碼:
2.2 單頁面應用介紹
意思爲只有一張web頁面的應用,它是應用於後臺系統的技術方案
單頁面應用的優缺點:
優點:
1、用戶操作體驗好,用戶不用刷新頁面,整個交互過程都是通過Ajax來操作。
2、適合前後端分離開發,服務端提供http接口,前端請求http接口獲取數據,使用JS進行客戶端渲染。
缺點:
1、首頁加載慢
單頁面應用會將js、 css打包成一個文件,在加載頁面顯示的時候加載打包文件,如果打包文件較大或者網速慢則用戶體驗不好。
2、SEO不友好
SEO(Search Engine Optimization)爲搜索引擎優化。它是一種利用搜索引擎的搜索規則來提高網站在搜索引擎排名的方法。目前各家搜索引擎對JS支持不好,所以使用單頁面應用將大大減少搜索引擎對網站的收錄。(但針對後臺類的管理系統,我們是不需要seo的)
總結:本項目的門戶、課程介紹不採用單頁面應用架構去開發,對於需要用戶登錄的管理系統採用單頁面開發。
3 CMS前端頁面查詢開發
3.1 頁面原型
3.1.1 創建頁面
3.1.1.1 頁面結構
在model目錄創建 cms模塊的目錄結構
在page目錄新建page_list.vue
<template>
<!--編寫頁面靜態部分,即view部分,注意這裏必須要加上一個div根元素 -->
<div>
測試頁面顯示...
</div>
</template>
<script>
/*編寫頁面靜態部分,即model及vm部分。*/
</script>
<style>
/*編寫頁面樣式,不是必須*/
</style>
注意:template內容必須有一個根元素,否則vue會報錯,這裏我們在template標籤內定義一個div。
3.1.1.2 頁面路由
現在先配置路由,實現url訪問到頁面再進行內容完善與調試。
1、在cms的router下寫個index.js配置路由
//import中的@表示src,導入文件後命名叫home
import Home from '@/module/home/page/home.vue';
import page_list from '@/module/cms/page/page_list.vue';
export default [{
path: '/',
component: Home,
name: 'CMS',//菜單名稱
hidden: false,
children:[
{path:'/cms/page/list',name:'頁面列表',component: page_list,hidden:false}
]
}
]
2、在base目錄下的router導入cms模塊的路由
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
// 定義路由配置
let routes = []
let concat = (router) => {
routes = routes.concat(router)
}
// // 導入路由規則,要導首頁和cms頁面,所以有兩個import
import HomeRouter from '@/module/home/router'
import CmsRouter from '@/module/cms/router'
// 合併路由規則
concat(HomeRouter)
concat(CmsRouter)
export default routes;
結果:
3.1.2 Table組件測試
本項目使用Element-UI來構建界面,Element是一套爲開發者、設計師和產品經理準備的基於 Vue 2.0 的桌面端組件庫。
需要使用時,進入Element-UI官方,找到對應組件,拷貝源代碼到vue頁面中即可
我們這裏先把所需要的表單組件的template、script部分拷貝好,再根據自己的需要改script裏面的數據
在page_list.vue裏測試一下:
<template>
<div>
<el-button type="primary" size="small">主要按鈕</el-button>
<el-table
:data="tableData"
stripe
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀區金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀區金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀區金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀區金沙江路 1516 弄'
}]
}
}
}
</script>
結果:
注意:上面的王小虎是假數據,我們真正的數據是從數據庫查出來的。但查出來的數據有哪些列呢?不知道屬性就不知道有什麼列,也就不好寫表格,那麼此時我們就要用到swagger了
先把微服務的工程啓動起來,然後打開瀏覽器進去swagger,點開接口然後隨便找點數據測試查看跑出來的結果中的屬性:
然後根據這些屬性在cms前端工程的vue文件的template裏寫自己想要展示的列名:
結果:
沒有數據怎麼看效果?
此時再拿剛纔swagger測出來的數據放上去看看效果:
"list": [
{
"siteId": "5a751fab6abb5044e0d19ea1",
"pageId": "5a754adf6abb500ad05688d9",
"pageName": "index.html",
"pageAliase": "首頁",
"pageWebPath": "/index.html",
"pageParameter": null,
"pagePhysicalPath": "F:\\develop\\xc_portal_static\\",
"pageType": "0",
"pageTemplate": null,
"pageHtml": null,
"pageStatus": null,
"pageCreateTime": "2018-02-03T05:37:53.256+0000",
"templateId": "5a962b52b00ffc514038faf7",
"pageParams": null,
"htmlFileId": "5a7c1c54d019f14d90a1fb23",
"dataUrl": null
}
],
結果:(我放了3條數據在裏面)
3.2 Api調用
3.2.1 Api方法定義
在api下寫js(cms.js)方法,通過這個方法調用public.js。
//public是對axios的工具類封裝,定義了http請求方法
import http from './../../../base/api/public'
/**
* 頁面查詢
*/
export const page_list = (page,size,params) => {
return http.requestQuickGet('http://localhost:31001/cms/page/list/'+page+'/'+size)
}
axios是一個http的類庫,實現了http方法的封裝,可通過它向服務端發起http請求
url是從swagger拿的,這個url拿到的是數據庫裏的數據,我們定義上面這個cms.js來將數據插到前端展示的表格裏
3.2.2 Api調用
前端頁面(page_list.vue)導入cms.js,調用js方法請求服務端頁面查詢接口。
然後在query方法中調用 page_list方法
<script>
// 導入js
import * as cmsApi from '../api/cms'
export default {
data() {
return {
list: [],
total: 50,
params: {
page: 1,//頁碼
size: 10//每頁顯示個數
}
}
},
methods: {
//分頁查詢
changePage: function () {
this.query()
},
//查詢
query: function () {
cmsApi.page_list(this.params.page,this.params.size).then((res)=>{
// 將res結果數據賦值給數據模型對象
this.list = res.queryResult.list;
this.total = res.queryResult.total;
})
}
}
}
</script>
cmsApi.page_list(this.params.page,this.params.size).then((res)=>{
前面向服務端發起調用,後面.then就表示服務端返回成功調then的回調方法,res爲服務端響應的結果,它的數據爲swagger測試結果中的response body
3.3 跨域問題解決
測試 上邊的代理 :
點擊查詢,但報錯了
結果 報錯如下 :
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
出現這個錯誤就說明出現跨域問題了
原因:瀏覽器的同源策略不允許跨域訪問,所謂同源策略是指協議、域名、端口相同。
解決:採用proxyTable解決。
proxyTable是vue-cli提供的解決vue開發環境下跨域問題的方法,proxyTable的底層使用了http-proxymiddleware,它是http代理中間件,它依賴node.js,基本原理是用服務端代理解決瀏覽器跨域:
具體的配置如下:
1、修改cms.js
//public是對axios的工具類封裝,定義了http請求方法
import http from './../../../base/api/public'
let sysConfig = require('@/../config/sysConfig')
let apiUrl = sysConfig.xcApiUrlPre;
/**
* 頁面查詢
*/
export const page_list = (page,size,params) => {
return http.requestQuickGet(apiUrl+'/cms/page/list/'+page+'/'+size)
}
特別注意url的前面那裏改成apiUrl
2、在config/index.js下配置proxyTable
最後重啓一下dev,再點擊查詢就可以訪問到數據庫了:
原理:
apiUrl的屬性裏有/api
所以它拼接出來的url是/api/cms/page/list/…
然後又配置了proxyTable的路徑,讓它指向31001的地址
下面這句拼接出來本來應該是 http://localhost:31001/api/cms/…,但是因爲真正能訪問到數據庫的是http://localhost:31001/cms/…,沒有/api,所以在下面pathRewrite中把它配成空字符串
3.4 分頁查詢測試
3.5 進入頁面立即查詢
目前實現的功能是進入頁面點擊查詢按鈕向服務端表求查詢,實際的需求是進入頁面立即查詢。
如何實現?
這要用到vue的鉤子函數,每個 Vue 實例在被創建時都要經過一系列的初始化過程——例如,需要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。同時在這個過程中也會運行一些叫做生命週期鉤子的函數,這給了用戶在不同階段添加自己的代碼的機會。
通常使用最多的是created和mounted兩個鉤子:
created:vue實例已創建但是DOM元素還沒有渲染生成。
mounted:DOM元素渲染生成完成後調用。
在methods下面寫鉤子:
4 前後端請求響應流程小結
1、在瀏覽器輸入前端url
2、前端框架vue.js根據url解析路由,根據路由找到page_list.vue頁面
3、首先執行page_list.vue中的鉤子方法
4、在鉤子方法中調用query方法。
5、在query方法中調用cms.js中的page_list方法
6、cms.js中的page_list方法通過axios請求服務端接口
7、採用proxyTable解決跨域問題,node.js將請求轉發到服務端(http://localhost:31001/cms/page/list)
8、服務端處理,將查詢結果響應給前端
9、成功響應調用then方法,在then方法中處理響應結果,將查詢結果賦值給數據模型中的total和list變量。
10、vue.js通過雙向數據綁定將list數據渲染輸出。