1. 程式人生 > >【資料售賣平臺】—— Vue2.0入門學習專案爬坑

【資料售賣平臺】—— Vue2.0入門學習專案爬坑

前言:這個專案是我從零學習Vue2.0時用於練習基礎知識的入門專案,包含了Vue2.0幾乎所有專案都會用到的基礎功能,是新手用來練手的好專案,這裡溫故知新對功能點做一個總結。


 

平臺首頁 登入註冊
一、安裝配置

 

 

1淘寶映象cnpm:

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

2、v-cli開發環境搭建:

npm install
-g vue-cli vue init webpack my-project cd my-project npm install npm run dev

3、建立vue專案時:嚴格遵守Enlint語法選擇No

  • WebStorm javascript 版本更改為 ES6

4、新版本vue-cli不需要下載vue-router,舊版本需要:

 npm install vue-router --save

5、main.js入口檔案中配置vue-Router:

import VueRouter from 'vue-router'

vue.use(VueRouter)
      
let router 
= new VueRouter({ mode: 'history', //router路由版本 routers: [ //router路由map { path: '/', component:IndexPage } ] })

7.layout.vue主元件中使用router-view:

<div class="app-content">
        <keep-alive>   //建立快取,來回切換時可保持狀態
             
<router-view></router-view> </keep-alive> </div>

 

二、根元件layout.vue

 

 

在公用元件資料夾components目錄下:

1.所有reset css都放到layout.vue<style>中: 去掉scoped  讓樣式應用到全域性

2.head、contentfoot三個div包含在一個div才可以一起掛載到index.html中的掛載點上

3.content內容div:用來切換顯示路由

<div class="app-content">
        <keep-alive>
             <router-view></router-view>
        </keep-alive>
</div>

 

三、首頁index.vue

 

 

在頁面元件資料夾pages目錄下:

1.<style>為了避免樣式汙染 一定記得加scoped

2.webpack中每一個圖片都會被當做一個模組module

  • 首頁中用到的圖片都要事先放置在assets檔案中,否則圖片缺失都會報模組錯誤

3.列表都是迴圈渲染的:

  • a標籤繫結href屬性時要用v-bind:href 或者縮寫href
<a :href="item.url">{{item.name}}</a>

4.新版本的vue-cli中v-for="item in items":

  • 後面都需要跟:key="item.name",key值必須是唯一的,如果有item屬性不唯一的時候,使用:key="index"一定不會報錯

5.使用 index 將迴圈模組中的圖片一一對應上

  • 這要求 在圖片命名時以index的順序命名 1234
v-for="(item, index) in boardList"

      注:當圖片關聯性強的時候 在資料中定義id欄位

id="car" //圖片路徑根據id值命名
:class="[{'line-last': index % 2 !== 0},'index-board-' + item.id]">
.index-board-car .index-board-item-inner{
    background: url(../assets/images/1.png) no-repeat;
}

6.迴圈出的四個模組 “田”字形排列,有兩個模組樣式不同

  • 另外加一個‘line-last'class,使margin-right=0;
  • 需要藉助index找到index%2!===0的兩個模組賦予class
 <div class="index-board-item"
      v-for="(item, index) in boardList"
      :key="item.title"
      :class="{'line-last': index % 2 !== 0}">

 

四、(方法一)json-server模擬資料

 

 

vue-resource實現Ajax獲取資訊資料從後端獲取資料

1.安裝vue-resource

npm install vue-resource --save

注:每次install完外掛等之後需要重新啟動專案

2.main.js檔案中引入vue-resouce:

 import VueResource from 'vue-resource'

 Vue.use(VueResource)

之後就可以在專案任何地方:使用this.$http命令

3.index.vue元件中傳送get請求:

created: function () {
      this.$http.get('api/getNewsList')//傳送get請求           
          .then(function(res){//.then方法  請求完成後呼叫
                              //第一個函式是請求成功後方法
          }, function (err) { //第二個函式是請求失敗後方法

          })
},
  • 如果傳送post請求(有時會報錯)
this.$http.post('postList',{userId: 123})

4.安裝json-server工具

npm install json-server --save

5.舊版本在build->dev.server.js檔案中進行擴充套件,新版本在build->webpack.dev.conf.js中進行配置

const jsonServer = require('json-server')
const apiServer = jsonServer.create()
const apiRouter = jsonServer.router('db.json')//資料關聯server
const middlewares = jsonServer.defaults()

apiServer.use(middlewares)
apiServer.use('/api',apiRouter)

apiServer.listen(8081, function (err) { //監聽埠,存在跨域
      if (err) {                          
          console.log(err)
          return
      }
      console.log('Lisening at http://localhost:8081/')
})

注:db.json是當前訪問頁面index.html同級的json資料檔案

6.config->index.js檔案中配置代理埠

proxyTable: {
      '/api': 'http://localhost:8081' //配置代理埠
},                       //json-server被代理到8081埠
  • 重新啟動專案,執行json-server:
 npm run dev
  • 此時檢查http://localhost:8081 如果看到JSON Server頁面即訪問成功
  • 訪問getNewList JSON資料 http://localhost:8081/api/getNewsList

7.請求傳送成功後,將獲取的資料res.data賦值給data資料中的newsList

created: function () {
   this.$http.get('api/getNewsList')
       .then((res) => {
           this.newsList = res.data
       }, (err) => {

       })
},  
  • 此時data中的newsList應為空陣列
  • 坑:此處用箭頭函式=> this才表示環境中的this;  如果用的是傳統函式 因為閉包的影響,需要在外面定義一個變數
created: function () {
      let me = this
      this.$http.get('api/getNewsList')
             .then(function (res) {
                    me.newsList = res.data
              }, function (err) {

              })
},

 

五、(方法二)通過express本身獲取資料

 

 

express是通用方法:不用json-server

  • json-server只能通過get請求獲取資料,無法通過post請求
  • express獲取資料,get/post請求都可以

1.同樣舊版本在build->dev.server.js檔案中進行擴充套件,新版本在build->webpack.dev.conf.js中進行配置

var express = require('express')

var app = express()

var apiServer = express()
var bodyParser = require('body-parser') apiServer.use(bodyParser.urlencoded({ extended: true })) apiServer.use(bodyParser.json())
var apiRouter = express.Router() var fs = require('fs') apiRouter.route('/:apiName') .all(function (req, res) { fs.readFile('./db.json', 'utf8', function (err, data) { if (err) throw err
var data = JSON.parse(data)
if (data[req.params.apiName]) { res.json(data[req.params.apiName]) }else { res.send('no such api name') } }) }) apiServer.use('/api', apiRouter); apiServer.listen(port + 1, function (err) { if (err) { console.log(err) return } console.log('Listening at http://localhost:' + (port + 1) + '\n') })

2. 同上6.7

 

五、幻燈片元件(公用元件)


 

 

第三方元件庫:awesome-vue  查詢vue元件的一種方式  github官方的一個集合

https://github.com/vuejs/awesome-vue   ctrl+F 搜尋slider

1.新建components->slideShow.vue元件

2.插入index.vue

import slideShow from '../components/slideShow'

3.使用components選項宣告:需要保證宣告名與匯入名一致

components: {
    slideShow
},

4.使用自定義元件名渲染到模板中:

 <slide-show></slide-show>

————————————以上建立公用元件的四個基本步驟

5.傳:slides屬性  在不同的地方使用同一組件時顯示不同內容

6.圖片通過js引入,必須使用require

 src: require('../assets/slideShow/pic1.jpg'),
  • 這個圖片會由webpack解析到相應的位置

注:如果不用require webpack不會識別為模組,不會打包到最終的檔案裡,就不會顯示到相應的位置

7.props:{ } 表示這個元件要接收一些什麼樣的屬性(從父元件)

props: {
      slides: {
         type: Array,
         default: function () {
              return []
         }
     }
}
  • 檢查資料是否拿到:
mounted () {
   console.log(this.slides)
}
<slide-show :slides="slides"></slide-show>
  • 動態繫結的屬性: slides 就是子元件props中的屬性
  • 繫結的資料 slides 是父元件datas中的陣列資料

坑:vue props 傳Array/Object型別值,子元件報錯解決辦法

        Array/Object的預設返回值要用工廠形式返回

8.定義資料變數nowIndex,設定預設值為0

 data () {
        return {
            nowIndex: 0
        }
 },
  • 在模板中渲染出slides中對應的資料項
<template>
       <div class="slide-show">
            <div class="slide-img">
            <a :href="slides[nowIndex].href">
                <img :src="slides[nowIndex].src">
            </a>
       </div>
       <h2>{{slides[nowIndex].title}}</h2>
       <ul class="slide-pages">
          <li><</li>
          <li v-for="(item, index) in slides"
              :key="index"
              @click="goto(index)">
             <a :class="{on : index === nowIndex}">{{index + 1}}</a>
          </li>
          <li>></li>
       </ul> 
</div>
</
template>
  •  定義重置nowIndex的方法:
 methods () {
    goto (index) {
        this.nowIndex = index
    }
 }
  • 標記當前顯示標籤高亮:動態繫結class屬性on 並判斷顯示的條件
<a :class="{on : index === nowIndex}">{{index + 1}}</a>

 9.點選兩個箭頭跳轉到前一張和後一張

   方法一: 分別建立 gotopre() 和 gotonext() 方法 執行+1,-1

   方法二: 使用vue的計算屬性computed:    

computed: {
         prevIndex () {
              if (this.nowIndex === 0) {
                    return this.slides.length - 1
              }else{
                    return this.nowIndex - 1
              }
         },
         nextIndex () {
              if (this.nowIndex === this.slides.length -1) {
                    return 0
              }else{
                    return this.nowIndex + 1
              }
         }
}
  • 計算屬性的 prevIndex 和 nextIndex 對應的都是資料 nowIndex
  • 返回重置後的 nowIndex 可以直接作為方法 goto(index) 的引數
<li @click="goto(prevIndex)"><</li>
<li @click="goto(nextIndex)">></li>   

10.自動輪播-setInterval

methods: {
        runInv () {
            this.invId = setInterval(() => {
                   //console.log(123)
                  this.goto(this.nextIndex)
            },this.inv)
        },

        clearInv () {
             clearInterval(this.invId)
        }
}
  • 方法在mounted鉤子中呼叫:元件掛載完成後執行的第一個業務邏輯
mounted () {
       console.log(this.slides)
       this.runInv()
}
  • this.inv:時間間隔資料仍然從父元件中獲取
  • 動態繫結的屬性: inv 就是子元件props中的屬性
  • 繫結的資料 slideSpeed 是父元件 datas 中的陣列資料
  • 滑鼠移入時 清除 Interval,滑鼠移出時 執行自動輪播
 <div class="slide-show" @mouseover="clearInv" @mouseout="runInv">

11.高階效果--移入移除動畫

更新Img部分:一定有一個時刻是同時顯示兩張圖片的

<transition name="slide-trans">
           <img v-if="isShow" :src="slides[nowIndex].src">
</transition>

<transform name="slide-trans-old">
           <img v-if="!isShow" :src="slides[nowIndex].src">
</transform>
  • datas資料中定義
isShow:true  //控制顯示的切換
  • 坑: 如果沒有用 v-if 判斷 isShow 條件,無法應用vue自己的 transition動畫

方法methods中:

 goto (index) {
        //this.nowIndex -- 舊值
        this.isShow = false

        setTimeout(() => {
            this.isShow = true
            this.nowIndex = index   //新值
        }, 10)
}
  • <transform>動畫元件對應css屬性:
 .slide-trans-enter-active {
        transition: all .5s;
 }
 .slide-trans-enter {
        transform: translateX(900px);
 }
 .slide-trans-old-leave-active {
        transition: all .5s;
        transform: translateX(-900px);
 }

坑:transition 對絕對定位的l eft/right 是無效的

       transition 最好是配合 transform 屬性使用

12.子元件向父元件傳遞資料、事件

  • slideShow.vue中:this.$emit() 方法傳遞 onchange事件 和 index引數
goto (index) {
       this.isShow = false

       setTimeout(() => {
           this.isShow = true
           this.nowIndex = index
           this.$emit('onchange', index)
       }, 10)
}

index.vue中:

<slide-show :slides="slides"
            :inv="slideSpeed"
            @onchange="doSomethingOnSlideChange">

methods: {
        doSomethingOnSlideChange () {
            console.log('doSomethingOnSlideChange run!')
        }
},

 

七、首頁彈窗元件

  

 

1.同一個父元件中插入的所有子元件,掛載的節點(div)都必須一致

<template>
        <div></div>
</template>

2.layout.vue檔案中使用子元件:

 import Dialog from '../components/base/dialog'

 <my-dialog></my-dialog>  

 components: {
         MyDialog: Dialog
 }

注:子元件標籤命名:不要和一些html本身的元素重名,否則會報錯

3.dialog.vue檔案中:

<template>
      <div class="dialog-wrap">
            <div class="dialog-cover" @click="closeMyself"></div>
            <div class="dialog-content">
                 <p class="dialog-close" @click="closeMyself">x</p>
                 <slot>empty</slot>
             </div>
      </div>
</template>
  • 通過插槽 <slot>empty</slot> 向 <my-dialog></my-dialog> 插入內容
  • 通過props接收父元件的isShow屬性,判斷彈窗是否顯示
props: {
      isShow: {
             type: Boolean,
             default: false
      }
}
  • 通過this.$emit()向父元件傳送事件,觸發父元件中的方法
methods: {
     closeMyself () {
          this.$emit('on-close')
     }
}

4.layout.vue檔案中:

<li @click="logClick">登入</li>

<my-dialog :isShow="isShowLogDialog"
                @on-close="closeDialog('isShowLogDialog')">
               <p>Log</p>
</my-dialog>
data () {
      return {
            isShowLogDialog: false,
      }
},

methods: {
      logClick () {
            this.isShowLogDialog = true
      },

      closeDialog (attr) {
             this[attr] = false
      }
}

 

八、登入表單-logForm.vue檔案

 

 

1.作為一個表單最重要的是input通過v-model雙向繫結資料

<input type="text"
       v-model="usernameModel"
       placeholder="請輸入使用者名稱">

<input type="password"
       v-model="passwordModel"
       placeholder="請輸入密碼">
  • 繫結的資料中兩個Model:
data () {
     return {
         usernameModel: '',
         passwordModel: ''
         errorText: ''
     }
}

2.表單另一個重要功能:驗證資料是否通過

<span class="error">
          {{ userErrors.errorText }}
</span>

<span class="error">
           {{ passwordErrors.errorText }}
</span>
  • 通過v-model的改變進行驗證,通過計算屬性computed關聯v-model,

定義一個錯誤資料的物件,包括出錯狀態、出錯文字(———計算屬性的第二種用法)

computed: {
       userErrors () {
          let errorText, status

          if(!/@/g.test(this.usernameModel)){
               status = false
               errorText = '不包括@'
          }
          else {
               status = true
               errorText = ''
          }

          if (!this.userFlag){
               errorText = ''
               this.userFlag = true
          }

          return {
              status,
              errorText
          }
       }
}
  • usernameModel每一次改變,都會先進行驗證,驗證通過傳送請求:
methods: {
     onLogin () {
       if (!this.userErrors.status || !this.passwordErrors.status) {
          this.errorText = '使用者名稱或密碼錯誤'
       }else {
          this.errorText = ''
          this.$http.get('api/login')
               .then((res) => {
                    this.$emit('has-log', res.data)
                }, (error) => {
                console.log(error)
          })
       }
    }
}

3.layout.vue檔案中:

<log-form @has-log="onSuccessLog"></log-form>

onSuccessLog (data) {
    this.username = data.username
    this.isShowLogDialog = false
}

 

購買詳情頁

 

九、購買詳情頁——新增路由/巢狀路由

 

    

1.router -> index.js檔案中配置 路由地圖

import Annalysis from '../pages/detail/analysis'
import Count from '../pages/detail/count'
import Forecast from '../pages/detail/forecast'
import Publish from '../pages/detail/publish'

 
{
      path: '/detail',
      component: DetailPage,
      children: [
        {
          path: 'annalysis',  //子路由中不可以帶‘/’符號,表示根目錄
          component: Annalysis
        },
        {
          path: 'count',
          component: Count
        },
        {
          path: 'forecast',
          component: Forecast
        },
        {
          path: 'publish',
          component: Publish
        }
    ]

2. layout的路由的其中一個子頁面元件--detail.vue檔案中:

<div class="detail-right">
    <keep-alive>
          <router-view></router-view>
    </keep-alive>
</div>

3. 頁面跳轉:vue-router的內建元件<router-link></router-link>

<ul>
    <router-link v-for="item in products"
                 :key="item.name"
                 :to="{ path: item.path }"
                 tag="li"
                 active-class="active">
         {{ item.name }}
    </router-link>
</ul>
  • 對應datas:
 products: [
          {
            name: '資料統計',
            path: 'count',
            icon: require('../assets/images/1.png'),
            active: false
          },
          {
            name: '資料預測',
            path: 'forecast',
            active: false
          } 
  ]

4. 頭圖的對映:隨路由的迴圈而對應顯示不同的圖片

<img :src="productIcon">
  • 資料datas中:
imgMap: {
          '/detail/count': require("../assets/images/1.png"),
          '/detail/forecast': require("../assets/images/2.png"),
          '/detail/analysis': require("../assets/images/3.png"),
          '/detail/publish': require("../assets/images/4.png")
}
  • 使用計算屬性通過 $router.path 獲取 imgMap 中對應的圖片路徑:
computed: {
        productIcon () {
            return this.imgMap[this.$router.path]
        }
}
  • 外層detail頁面給它的子路由頁面共享樣式<style>不可以加scope

6.路由導航,也可以直接通過<a>標籤直接跳轉

  • index.vue首頁  資料datas中:
href: 'detail/analysis'
  • 瀏覽器可直接訪問

7.不希望使用者訪問到/detail 頁面:detail.vue只作為一箇中介的元件

  • 在路由map中,將所有訪問到/detail redirect一下,訪問預設頁面
path: '/detail',
component: DetailPage,
redirect: '/detail/count',

 

十、購買詳情頁——select選項元件

 

 

<div class="selection-component">
      <div class="selection-show" @click="toggleDrop">
           <span>{{ selections[nowIndex].label }}  </span>
           <div class="arrow"></div>
      </div>

      <div class="selection-list" v-if="isDrop">
          <ul>
             <li v-for="(item, index) in selections"
                  :key="item.label"
                   @click="chooseSelection(index)">
              {{ item.label }}
            </li>
          </ul>
      </div>
</div>
  •  關鍵:通過規定 nowIndex 標記當前選中的選項
data () {
      return {
         nowIndex: 0,
         isDrop: false
      }
}  
  • 兩個方法:顯示隱藏、切換selection
methods: {
       toggleDrop () {
           this.isDrop = !this.isDrop
       },

       chooseSelection (index) {
           this.nowIndex = index
           this.isDrop = false
           this.$emit('on-change', this.nowIndex)  
                //傳到元件外面,告訴外面要購買的是什麼
       }
}
  • 從父元件獲取到的props資料型別、格式:
 props: {
       selections: {
          type: Array,
          default: [{
             label: 'test',
             value: 0
          }]
       }
 }

 

十一、購買詳情頁——可多選項元件

 

 

<template>
       <div class="chooser-component">
           <ul class="chooser-list">
              <li v-for="(item, index) in selections"
                  @click="toggleSelection(index)"
                  :title="item.label"
                  :class="{active: checkActive(index)}"
              >{{ item.label }}</li>
           </ul>
       </div>
</template>

1.關鍵:nowIndex 是一個數組,可以多選

data () {
      return {
          nowIndexs: [0]
      }
}

2、Lodash:是一個一致性、模組化、高效能的 JavaScript實用工具庫。        

  • 通過降低 array、number、objects、string等等的使用難度,從而讓 JavaScript變得更簡單。
 $ npm i --save lodash
import _ from 'lodash'
methods: { toggleSelection (index) { if (this.nowIndexes.indexOf(index)){ this.nowIndexes.push(index) } else { this.nowIndexes = _.remove(this.nowIndexes, (idx) => { return idx !== index }) } this.$emit('on-change', this.nowIndexes) } }

坑:vue2.0 刪除了 vue1.0 中的 $remove方法,官方文件推薦使用第三方工具庫

       _remove實現,如上:從陣列中刪除index為this.nowIndexes的值

 

3.使用一個方法返回是否active,實現多個選項同時active 被啟用

 :class="{active: checkActive(index)}"
checkActive (index) {
      return this.nowIndexes.indexOf(index) !== -1
}
  •  方法判斷index在nowIndexes陣列中是否存在。
  •  返回true,則active:true 選項被啟用,返回false.則選項不被啟用

 

十二、購買詳情頁——陣列元件

 

 

<template>
   <div class="counter-component">
       <div class="counter-btn" @click="minus"> - </div>
       <div class="counter-show">
            <input type="text" v-model="number" @keyup="fixNumber">
       </div>
       <div class="counter-btn" @click="add"> + </div>
  </div>
</template>

1.最大值和最小值 由props定義預設值,在不同的呼叫處由父元件給到

 props: {
    max: {
       type: Number,
       default: 5
    },

    min: {
       type: Number,
       default: 1
    } 
 }

2.輸入框和資料雙向繫結 number, 給定預設值為當前資料的最小值

data () {
    return {
      number: this.min
    }
}

3.watch監聽number 每次改變的時候,都會執行$emit->on-change

  •  使用監聽資料,可以不管資料是在哪兒變的,以及怎麼變的
watch: {
    number () {
        this.$emit('on-change', this.number)
    }
}

4.方法中執行‘加’、‘減’以及更換資料

  • 當輸入框輸入String型別時替換掉其中不為數字的部分,然後轉為Number
methods: {
    fixNumber () {
      let fix

      if (typeof this.number === 'string') {
        fix = Number(this.number.replace(/\D/g, ''))
      }else {
        fix = this.number
      }

      if(fix > this.max || fix < this.min) {
        fix = this.min
      }

      this.number = fix
    },

    minus () {
      if (this.number <= this.min) {
        return
      }
      this.number --
    },

    add () {
      if (this.number >= this.max) {
        return
      }
      this.number ++
    }
  }

 

十三、購買詳情頁——總價計算

 

 

1.關鍵: 依據每一個頁面中所有元件傳出來的值,進行計算

counter.vue

this.$emit('on-change', this.number)

selection.vue:

this.$emit('on-change', this.selections[this.nowIndex])

chooser.vue:

this.$emit('on-change', this.selections[index])

2.analysis.vue頁面元件中:

  • 呼叫對應的子元件:
<v-counter @on-change="onParamChange('buyNum', $event)">
</v-counter>

<v-selection :selections="buyTypes"
             @on-change="onParamChange('buyType',$event)">
</v-selection>

<v-chooser :selections="periodList"
           @on-change="onParamChange('period', $event)">
</v-chooser>

<v-mul-chooser :selections="versionList"
               @on-change="onParamChange('versions'$event)">
</v-mul-chooser>
  • 各子元件統一使用on-change事件觸發同一個引數處理函式
onParamChange (attr, value) {
        this[attr] = value
        //console.log(attr, this[attr])
        this.getPrice()
}

在傳參時:

     第一個引數attr,用'元件資料如buyType'來標識是哪個元件呼叫的方法

     第二個引數value,用$event來表示 事件on-change帶出來的值  

 

3.元件渲染完成之後,第一次進入頁面時元件資料都顯示預設資料

mounted () {
     this.buyNum = 1
     this.buyType = this.buyTypes[0]
     this.versions = [this.versionList[0]]
     this.period = this.periodList[0]
     this.getPrice()
}

4.一般規定一個介面,傳給服務端,處理完成後再通過Ajax傳出來金額

  • 使用lodash和vue-resource傳送post請求:
getPrice () {
      let buyVersionsArray = _.map(this.versions, (item) => {
           return item.value
      })

      let reqParams = {
          buyNum: this.buyNum,
          buyType: this.buyType.value,
          period: this.period.value,
          version: buyVersionsArray.join(',')
      }

      //通過vue-resource 傳送Ajax請求

      this.$http.post('/api/getPrice', reqParams)
        .then((res) => {
             //console.log(res)
             //let data = JSON.parse(res.data)
             this.price = res.data.buyNum * 20
      })
}

 

十四、購買詳情頁——購買彈窗、選擇銀行

 

 

選擇銀行:四個頁面統一,不隨頁面本身的選擇而改變  

——抽出來  以獨立的方式載入

 

訂單列表

 

十五、訂單列表——日曆元件

 

 

安裝第三方日曆控制元件-awesome 工具庫

npm install vue-date-picker  --save //記錄到專案裡   

引入:

import VueDatePicker from 'vue-date-picker'

components: {
      VueDatePicker
}

不足:這個元件只支援vue1.0版本的,需要自己再擴充套件一下

重新擴充套件:複製到自己新建的datepicker.vue檔案中

修復bug:

   1.在script->props中增:

styleObj: { type: Object, default: null }

   2.在vue1.0中value是直接傳過來的 :value="value",需要改成

v-model="showValue"  

     datas中對應: 

showValue: ' ',

   3.在vue1.0中允許給傳入的value賦值,但在vue2.0中是不允許的,會報錯

this.value = this.stringify(); //後面通過$emit將value值傳出來
 
this.showValue = this.stringify();
this.$emit('on-change', this.showValue);

使用元件:

<v-date-picker  fromat="YYYY-MM-DD"
                @change="changeStartDate">
</v-date-picker>

 

十六、訂單列表

 

 

watch監聽關鍵詞搜尋input框中的query:

<input type="text" v-model.lazy="query" class="order-query">  
  • 加修飾符 .lazy 使得移除後才觸發watch中方法
datas: { query: '', }  
watch: {
     query () {
        console.log('on query change')
     }
}

 

十七、訂單列表

 

 

關鍵:兩次遍歷——第一次遍歷每一條資料物件,包含一行中所有資料

                                第二次遍歷每一條中每一列的單個數據

基礎:兩個迴圈渲染——渲染表頭<th>、渲染表列<td>

<table>
       <tr>
          <th v-for="head in tableHeads" :key="head.label">
              {{ head.label }}
          </th>
       </tr>

       <tr v-for="item in tableData" :key="item.period">
          <td v-for="head in tableHeads" :key="head.key">
               {{ item[head.key] }}
          </td>
       </tr>
</table>
  • 點選表頭,實現排序:
changeOrder (headItem) {
        this.tableHeads.map((item) => {   //常用使點選項高亮顯示的方法
            Item.active = false
            return item
        })

        headItem.active = true

        if (this.currentOrder === 'asc') {
           this.currentOrder = 'desc'
        } 
        else if (this.currentOrder === 'desc') {
           this.currentOrder = 'asc'
        }

        this.tableData = _.orderBy(this.tableData, headItem.key,
      this.currentOrder)

       //_.orderBy的三個引數分別是:
       //要排序的資料、排序根據的列數、排序的方式(正序,倒序)
}
  • checkOrder.vue檔案:在元件內部進行路由跳轉的通用的方法
toOrderList () {
         this.$router.push({path: '/orderList'})
}
//和<router-link>裡面to的跳轉是一樣的

 版權宣告:本文原創,未經本人允許不得轉載