1. 程式人生 > >學習筆記之vue高仿餓了麼課程專案--vue.js篇

學習筆記之vue高仿餓了麼課程專案--vue.js篇

歡迎大家來訪問我的github哦:my-github

現把專案中學到的知識和遇到的問題做一整理。這篇是vue.js篇

vue-cli

vue-cli是vue的腳手架工具,官方命令列工具,可快速搭建大型單頁應用。下面是使用方法(前提是已經安裝node)

  • 全域性安裝
cnpm install  -g vue-cli
  • 列出可以用的模板
vue list
  • 建立一個基於webpack模板的新專案
vue init webpack my-project
  • 進入專案資料夾
cd my-project
  • 安裝所需依賴,生成node-modules資料夾
cnpm install
  • 開發環境下執行
cnpm run dev

webpack(3.6.0)

1.webpack.base.conf.js是vue開發環境下的webpack的配置檔案,可以在其中的resolve下設定縮略路徑,這樣方便後面引用。

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {  //別名,用前面替代後面,加上path.resolve則表示入口檔案地址
      'src': path.resolve(__dirname, '../src'),
      'common': path.resolve(__dirname, '../src/common'),
      'components': path.resolve(__dirname, '../src/components')
    }
  },
2.webpack.dev.conf.js也可以被修改,從而可以mock資料
  • 增加以下程式碼,從而可以從data.jason檔案中獲取資料賦值給各變數
const appData=require('../data.json')
const seller=appData.seller
const goods=appData.goods
const ratings=appData.ratings
  • webpack.dev.conf.js中的devServer是一個nodejs.express伺服器在其中加入以下程式碼便可以從介面獲取資料
devServer: {
    before(app) {
      app.get('/api/seller', function(req, res) {    //express路由的形式
        res.json({
          errno: 0,
          data: seller
        })
      });
      app.get('/api/goods', function(req, res) {
        res.json({
          errno: 0,
          data: goods
        })
      });
      app.get('/api/ratings', function(req, res) {
        res.json({
          errno: 0,
          data: ratings
        })
      });
    },
           其他
        }
  • 在命令列下輸入
cnpm run dev
  • 在瀏覽器輸入http://localhost:8080/api/seller便可看到jason格式的資料

3.修改config下的index.js檔案中的host如下,便可以以ip地址訪問專案

host: '0.0.0.0'

vue-router(3.0.1)

1.安裝使用

  • 進入專案資料夾下
cnpm install vue-router --save
  • 在router資料夾下的index.js檔案中引用和全域性註冊
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);

2.可以使訪問頁面直接跳轉到商品頁面

{
    path: '/',
    redirect: '/goods'
  },

3.<router-link to="/goods">商品</router-link>其實是一個a標籤,所以寫樣式時是給a標籤加樣式,

& > a
          display: block
          font-size: 14px
          color: rgb(77, 85, 93)
          &.active
            color: rgb(240, 20, 20)
在路由設定如下,則當選中一個路由時,加在上面的class樣式會被啟用
export default new Router({
  linkActiveClass: 'active',    //當選中一個路由時,加在上面的class樣式會被啟用
  routes
});

4.元件切換保留狀態

<keep-alive>
      <router-view :seller="seller"></router-view>
</keep-alive>
vue-resource
  • 在專案資料夾下安裝
cnpm install vue-resource --save
  • 在main.js中引用和全域性註冊
import VueResource from 'vue-resource';
Vue.use(VueResource);
  • 在created鉤子函式(例項被建立之後)中使用ajax非同步請求拿到資料
created() {
      this.$http.get('/api/seller').then((response) => {
        response = response.body;             //response.body返回的是jason物件
        if (response.errno === ERR_OK) {
          this.seller = response.data;  
          console.log(this.seller);
        }
      });
    },

元件

1.元件的引用

  • 每個元件都寫成一個.vue檔案,這個檔案中包含元件模板,元件樣式,元件的vue例項選項
<template>
</template>
<script type="text/ecmascript-6">
  export default {   //子元件傳出
 };     
</script>
<style lang="stylus" rel="stylesheet/stylus">
</style>
  • 在父元件中引入子元件並註冊元件,才能使用元件
<template>                   //注意,template下只有一個根元素
  <div id="app">
    <v-header></v-header>    //使用元件
  </div>
</template>
<script>
   import header from 'components/header/header.vue';    //引用元件
   export default {
       components: {
          'v-header': header     //註冊元件。由於header是html5原生的標籤,所以得重新取個名v-header
      }
   };
</script>
<style>
</style>

2.父子元件之間的資料傳遞:使用v-bind來動態地將 prop 繫結到父元件的資料。每當父元件的資料變化時,該變化也會傳導給子元件。

//父元件中
<v-header :sellerSon="sellerParent"></v-header>
//子元件中
props: {
      sellerSon: {
        type: Object
      }
    }
3.子元件使用父元件傳來的資料時,需要注意該資料是非同步請求的
<div class="avatar">
  <img width="64" height="64" :src="seller.avatar">      //使用v-bind繫結資料
</div>
<div v-if="seller.supports" class="support">   
    //需要確定seller.supports已經獲取,才能取到它的屬性,否則undefined
  <span class="icon" :class="classMap[seller.supports[0].type]"></span>
  <span class="text">{{seller.supports[0].description}}</span>
</div>
4.父子元件間的通訊

  • 在子元件controlcart中使用$emit觸發一個add事件,事件的引數是另一事件的target,即操作的DOM元素。
this.$emit('add', event.target);
  •  父元件中使用v-on來監聽子元件觸發的事件
<cartcontrol @add="addFood"></cartcontrol>
  • 父元件一旦監聽到add則觸發addFood。addFood把父元件拿到的target傳給_drop方法
addFood(target) {
        this._drop(target);
      },
  • 父元件在_drop方法裡呼叫子元件shopcart裡實現的drop方法。父元件要想使用子元件的方法,則在引用子元件的地方使用ref
<shopcart ref="shopcart"></shopcart>
 _drop(target) {
        this.$nextTick(() => {
          this.$refs.shopcart.drop(target);
        });
      },

新增欄位

1.給物件加一個屬性欄位

Vue.set(Object, 'attribute-name', init-value);
2.Object.assign(target,source)
  • 用於將所有可列舉屬性的值從一個或多個源物件複製到目標物件,返回目標物件
//官網示例
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
//合併物件,將this.seller和response.data合併在一起,複製給了空物件
this.seller = Object.assign({}, this.seller, response.data);
transition

1.使用javascript鉤子實現過渡

  • 在transition元件中宣告javascript鉤子
<transition name="drop" @before-enter="beforeDrop" @enter="dropping" @after-enter="afterDrop">
  • 在方法中實現鉤子
methods: {
  beforeDrop: function (el) {
    // ...
  },
  // 此回撥函式done是可選項的設定
  // 與 CSS 結合時使用
  //當只用 JavaScript 過渡的時候, 在 enter 和 leave 中,回撥函式 done 是必須的 。否則,它們會被同步呼叫,過渡會立即完成。
  dropping: function (el, done) {
    // ...
     el.addEventListener('transitionend', done);
  },
  afterDrop: function (el) {
    // ...
  }
  },

vue繫結動態class

1.在本次專案中,動態綁定了多種型別的class

  • class繫結一個物件,如果totalCount>0,則highlight為true,則class="highlight"
<div class="logo" :class="{'highlight':totalCount>0}">
  • class繫結一個計算屬性
<div class="pay" :class="payClass">
  • class繫結一個數組
<span :class="classMap[item.type]">

filters

<div class="time">{{rating.rateTime | formatDate}}</div>
//使用過濾器formatDate處理rating.rateTime
//過濾器實現
filters: {
     formatDate(time) {
        ...
     }
}

阻止冒泡事件的發生

<div class="content-right" @click.stop.prevent="pay">