vue項目實戰

看了一個禮拜的 vue.js ,不得不說,入門是很容易的,學習曲線也相對平緩。數據的雙向綁定也另開發順暢,特別是一些交互比較複雜的項目。
來簡單說一下利用 vue-cli 腳手架進行項目開發,我我的的一些實戰總結吧,項目是基於 vue2.0作開發的。css

1、項目編譯的webpack配置簡介:

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

2、項目實戰開發

但願你在看這篇博文的時候是有點 vue 基礎的,對 vue開發有所瞭解,本篇文章不會介紹 vue 的基礎內容,
由於 [vue.js官網][1] 已經很簡單詳細了。 本篇會講一些實戰開發的總體架構,和開發當中的一些實用的
知識點和技巧

一、全局 data

雖然 vue 是對數據雙向綁定,如何管理好你的數據就須要多費點心思考慮一下了,否則到實際項目中,獨立出獨立的組件,而組件之間又存在數據或交互,那麼數據傳遞將會異常的繁瑣。
這裏我建議 在 App.vue (或超父組件) 裏維護一套 全局 data ,以下圖:
clipboard.pngexpress

二、父組件給子組件傳遞數據

父組件 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>

3、nodejs 模擬線上數據調試

作前端開發通常不會只作靜態頁面,特別是使用 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 項目
用微信掃一掃打開:
圖片描述

相關文章
相關標籤/搜索