看了一個禮拜的 vue.js ,不得不說,入門是很容易的,學習曲線也相對平緩。數據的雙向綁定也另開發順暢,特別是一些交互比較複雜的項目。
來簡單說一下利用 vue-cli 腳手架
進行項目開發,我我的的一些實戰總結吧,項目是基於 vue2.0
作開發的。css
vue-cli 腳手架項目的目錄 build 下有 3個基礎配置文件:
webpack.base.conf.js
webpack.dev.conf.js
webpack.prod.conf.js ,
html
用來構建 運行時項目,和構建發佈時項目
一、webpack.base.conf.js
基礎配置文件前端
module: { loaders: [ { test: /\.vue$/, loader: 'vue' }, { test: /\.js$/, loader: 'babel', include: projectRoot, exclude: /node_modules/ }, { test: /\.json$/, loader: 'json' }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url', query: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url', query: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] },
module 下面的配置其中須要說明的一點是 配置中有對 10000b 的圖片大小進行base64轉換,折算一下就是 9.765625kb
,因此項目中對一下小的 icon 沒必要作圖片精靈處理。vue
在 webpack.base.conf.js 文件的結尾處還有這麼一段配置:node
vue: { loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }), postcss: [ require('autoprefixer')({ browsers: ['last 2 versions'] }) ] }
爲何單獨拿出來講呢,由於在項目開發的時候遇到一點小坑 , autoprefixer
一個瀏覽器自動兼容插件,browsers: ['last 2 versions']
意思是隻對主流瀏覽器的最新兩個版本(其實也就是不作兼容了,現代最新的瀏覽器基本都不須要兼容了呀),因此我在寫一個 css3 動畫
的時候就發現較低版本的Android設備竟然不運行。
配置以下就行了:意思是 對 主流瀏覽器的最新五個版本和對Android4.0以上
的版本作兼容webpack
vue: { loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }), postcss: [ require('autoprefixer')({ browsers: ['last 5 versions', 'Android >= 4.0'] }) ] }
二、webpack.dev.conf.js
當咱們在項目運行 npm run dev
就會執行這個腳本進行項目構建,值得一提的是配置文件中有個html-webpack-plugin
插件,用於熱刷新瀏覽器,當你編輯完 .vue文件
,command+s
保存一下瀏覽器就會自動刷新了。css3
三、webpack.prod.conf.js
當咱們要上線項目能夠用 npm run build
對我們的項目進行構建,webpack 會幫咱們壓縮css 和js文件,並加上哈希值,還有生成對應文件的 SourceMap 文件
,由於壓縮後的css或js文件你沒辦法看,調試的時候出了錯誤能夠利用SourceMap
來查看代碼對應的位置。 那我項目確保沒bug了怎麼把SourceMap
關掉呢,畢竟線上項目是不想讓別人看到具體源代碼的。
那就找到 項目中config文件夾
下 index.js
文件對應下的配置:web
module.exports = { build: { //... productionSourceMap: false,
將 productionSourceMap
置爲 false
再次 npm run build
同樣就不會構建出 .map 文件
了vue-cli
但願你在看這篇博文的時候是有點 vue 基礎的,對 vue開發有所瞭解,本篇文章不會介紹 vue 的基礎內容, 由於 [vue.js官網][1] 已經很簡單詳細了。 本篇會講一些實戰開發的總體架構,和開發當中的一些實用的 知識點和技巧
一、全局 data
雖然 vue 是對數據雙向綁定,如何管理好你的數據就須要多費點心思考慮一下了,否則到實際項目中,獨立出獨立的組件,而組件之間又存在數據或交互,那麼數據傳遞將會異常的繁瑣。
這裏我建議 在 App.vue (或超父組件) 裏維護一套 全局 data
,以下圖:express
二、父組件給子組件傳遞數據
父組件 appVue.vue
<template> <div id="appVue"> <page1 v-bind:infodata="infodata"></page1> </div> </template> <script type="text/ecmascript-6"> import page1 from './components/page1/page1'; export default { name: 'appVue', data(){ return { infodata:{ ‘name’:’曾田生’, ‘age’:'24' } } }, components: { page1 } } </script> <style lang="scss"> </style>
子組件 page1
<template> <div id="page1"> <p>{{infodata.name}}</p> <p>{{infodata.age}}</p> </div> </template> <script type="text/ecmascript-6"> export default { props: { infodata: { type: Object, default: function () { return{ ‘name’:’xxx’, ‘age’:'111' } } } } } </script> <style lang="scss"> </style>
父組件 經過 v-bind
將組件的 data 數據
綁定在子組件上,子組件再利用 props對象
接收父組件傳遞過來的值,接着就能夠像組件的 data 數據同樣盡情的使用了。
三、props watch
有這麼一個場景是:子組件拿到了父組件給過來的值,但隨着用戶對父組件的操做,數據要反饋到子組件上, 那麼這個場景就可使用 vue 的 watch對象
<template> <div id="page1"> <p>{{infodata.name}}</p> <p>{{infodata.age}}</p> </div> </template> <script type="text/ecmascript-6"> export default { props: { infodata: { type: Object, default: function () { return{ ‘name’:’xxx’, ‘age’:'111' } } } }, watch:{ ’infodata’:function(){ console.log('infodata 數據變化會觸發我這個方法的執行' ); } } } </script> <style lang="scss"> </style>
利用 watch
對象 來監聽 props對象中 infodata屬性的變化 ,固然了,也能夠用來監聽 組件中 data數據的變化
四、父組件調用子組件的方法
有時候我們須要在父組件裏調用子組件的方法,利用強大的 vue 也是很容易作到的
父組件:
給子組件上註冊引用信息 ref="page1"
,拿到改引用信息 this.$refs.page1
,其實也就是獲取子組件的意思, 接着調用子組件的方法 this.$refs.page1.handleParentClick()
; handleParentClick
是方法名,
能夠自定,只要子組件也有對應的方法名便可。
<template> <div id="appVue"> <div class='ddiv' @click="divClick" ></div> <page1 ref="page1" :infodata="infodata"></page1> </div> </template> <script type="text/ecmascript-6"> import page1 from './components/page1/page1'; export default { name: 'appVue', data(){ return { infodata:{ ‘name’:’曾田生’, ‘age’:'24' } } }, methods:{ divClick:function(){ //調用子組件 page1 的 handleParentClick 方法 this.$refs.page1.handleParentClick(); } }, components: { page1 } } </script> <style lang="scss"> </style>
子組件:
子組件在 methods 對象裏聲明 被父組件調用的方法 handleParentClick
<template> <div id="page1"> <p>{{infodata.name}}</p> <p>{{infodata.age}}</p> </div> </template> <script type="text/ecmascript-6"> export default { props: { infodata: { type: Object, default: function () { return{ ‘name’:’xxx’, ‘age’:'111' } } } }, watch:{ ’infodata’:function(){ console.log('infodata 數據變化會觸發我這個方法的執行' ); } }, methods:{ handleParentClick: function () { console.log('父組件喚起了該方法的執行' ); } } } </script> <style lang="scss"> </style>
五、子組件給父組件回傳數據
上面第4點講了父組件能夠調用子組件的方法,可是 子組件是不能調用父組件的方法的,爲了保護父組件 數據不被污染或破壞。但 vue 也用了一套方法 來將子組件的數據回傳給父組件。 組件除了能夠給 div 加上 `v-on:click = 'doSomething'` 來對 div監聽點擊事件外,父組件還能夠 用 `v-on:name='listenChild' `來監聽子組件傳遞給父組件的數據。
父組件:
父組件能夠在使用子組件的地方直接用 v-on
來監聽子組件觸發的事件。
<template> <div id="appVue"> <div class='ddiv' @click="divClick" ></div> <page1 v-on:page-to-appvue='listenChild' ref="page1" :infodata="infodata"></page1> </div> </template> <script type="text/ecmascript-6"> import page1 from './components/page1/page1'; export default { name: 'appVue', data(){ return { infodata:{ ‘name’:’曾田生’, ‘age’:'24' } } }, methods:{ listenChild: function (msg) { console.log('監聽子組件傳遞過來的數據'+msg+‘並觸發改方法的執行’ ); }, divClick:function(){ //調用子組件 page1 的 handleParentClick 方法 this.$refs.page1.handleParentClick(); } }, components: { page1 } } </script> <style lang="scss"> </style>
子組件:
使用 $emit(eventName)
觸發事件
<template> <div id="page1"> <div @click="divClick" ></div> <p>{{infodata.name}}</p> <p>{{infodata.age}}</p> </div> </template> <script type="text/ecmascript-6"> export default { props: { infodata: { type: Object, default: function () { return{ ‘name’:’xxx’, ‘age’:'111' } } } }, watch:{ ’infodata’:function(){ console.log('infodata 數據變化會觸發我這個方法的執行' ); } }, methods:{ divClick:function(){ // 給父組件發送消息 this.$emit('page-to-appvue',{‘name’:’xxx’,‘age’:'111'}); }, handleParentClick: function () { console.log('父組件喚起了該方法的執行' ); } } } </script> <style lang="scss"> </style>
作前端開發通常不會只作靜態頁面,特別是使用 vue 框架的時候,通常是具備複雜點的數據交互你才選擇它。 那就免不了需後臺數據的調試,我們能夠先寫好接口,再模擬一下後臺數據,到時候先後端數據聯調 就會輕鬆多了
一、開發中的調試
在項目的跟目錄下模擬一份json數據:
data.json
{ "userData": { "id": 1, "openid": "oC_mwjjqkqwsjm9Yvoq-Zk06Nntsws", "nickname": "曾田生", "sex": 1, "language": "zh_CN", "city": "Zhangzhou", "province": "Fujian", "country": "China", "headimgurl": "http://wx.qlogo.cn/mmopen/H5nYy4sS0Dt1ChHtmOHwfTX86TjV1b28afBSIDsDoMVttaO213SlZUsmNGAX9h73mtJJvEcruOibbM0tSia6AfBgrqP4ibaXMJyTa/0", "privilege": "", "unionid": "oEexiuGFcp_4a1oPSsKLkMS938Tlg", "goTo": "23,43,12,34,34", "wantTo": "34", "createTime": 1483002136000 } }
當我們執行 npm run dev
的時候會執行項目 build 目錄下的 dev-server.js
的這個 server文件
,
我們就在這個文件裏頭配置一些路由,模擬一些供頁面訪問的接口。
往 dev-server.js
腳本插入以下代碼, 模擬監聽來自 客戶端的請求
var express = require('express') var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // 獲取模擬數據 var appData = require('../data.json'); var userData = appData.userData; // get請求 app.get('/process_get', function (req, res) { // 輸出 JSON 格式 var response = { err:0, data:userData }; res.end(JSON.stringify(response)); }) // post 請求 app.post('/getUserData', function (req,res) { var response = { err:0, data:userData }; res.end(JSON.stringify(response)); });
在客戶端組件裏發起請求:
<template> <div id="appVue"> <div class='ddiv' @click="divClick" ></div> <page1 v-on:page-to-appvue='listenChild' ref="page1" :infodata="infodata"></page1> </div> </template> <script type="text/ecmascript-6"> import VueResource from 'vue-resource'; // 全局註冊 ,將組件添加到 vue 裏面 Vue.use(VueResource); import page1 from './components/page1/page1'; export default { name: 'appVue', data(){ return { infodata:{ ‘name’:’曾田生’, ‘age’:'24' } } }, created(){ // 客戶端 post 請求 this.$http.post('/getUserData', {'openid': urlFrom.openid}).then((response) => { var resData = JSON.parse(response.body); if (resData.err === 0) { // 請求成功,返回數據 } else { console.log('---------ERR-----------'); } }); // 客戶端 get 請求 this.$http.get('/getUserData').then((response) => { response = response.body; } }); } methods:{ listenChild: function (msg) { console.log('監聽子組件傳遞過來的數據'+msg+‘並觸發改方法的執行’ ); }, divClick:function(){ //調用子組件 page1 的 handleParentClick 方法 this.$refs.page1.handleParentClick(); } }, components: { page1 } } </script> <style lang="scss"> </style>
二、線上發佈項目的的調試
這裏我用的是 node.js
來作後端開發 ,在項目的根目錄建個 server.js
文件 :
var express = require('express'); var app = express(); var routar = express.Router(); // get請求 routar.get('/getUserData', function (req, res) { // 輸出 JSON 格式 var response = { err:0, data:userData }; res.end(JSON.stringify(response)); }) // post 請求 routar.post('/getUserData', function (req,res) { var response = { err:0, data:userData }; res.end(JSON.stringify(response)); }); app.use(routar); var server = app.listen(8888, function () { var host = server.address().address; var port = server.address().port; console.log("應用實例,訪問地址爲 http://%s:%s", host, port) })
npm run build
我們的項目 ,會打包編譯完 .vue
文件 ,在項目的跟目錄下回生成 dist 文件夾
,裏面的
資源就是我們要發佈到線上的腳步和網頁文件。
執行 node server.js
便可啓動該執行文件,至此,先後端項目都編譯啓動完成,能夠作線上調試了。
本篇稍微講了一下利用 vue-cli 腳手架進行前端項目開發的大概流程,知識點講的有粗有細,你們能夠對大致流程有所瞭解,對細節知識點不妨去 google 百度 深刻學習。
vue 項目
用微信掃一掃打開: