vue 項目要點總結(二)

靜態logo圖片怎麼引入

<div class="logo">
  <img src="../assets/logo.png"/>
</div>

clipboard.png

對重複元素的遍歷

productList:{
    pc:{
            title:"PC產品",
            list:[
              {title:"數據統計",url:"#",hot:false},
              {title:"數據預測",url:"#",hot:true},
              {title:"流量分析",url:"#",hot:false},
              {title:"廣告發布",url:"#",hot:true}
            ]
        }
},

<dl class="first">
  <dt>{{productList.pc.title}}</dt>
  <dd v-for="item in productList.pc.list">
    <a :href="item.url">{{item.title}}</a>
    <span v-if="item.hot" class="hot">HOT</span>
  </dd>
</dl>
//在重複的部分用v-for

若是某個重複的部分比較分散;可用 <template v-for> </template> 循環,循環是從標籤自己就開始的html

<li v-for="item in news" :title="item.title"><a :href="item.url">{{item.title}}</a></li>

//li 既是 v-for 的載體, 也是item ;:title="item.title" 與v-for 同一個標籤;

:class 的靈活使用

遍歷的時候 class 能夠接受 幾種賦值方式;vue

//直接綁定item的屬性
<li v-for="(item,index) in board" class="bot-item clearfix" :class="item.class">


//經過對象的方式配置
<li v-for="(item,index) in board" class="bot-item clearfix" :class="'red':index==0?true:false}">

//class 是 一個數組;第一項經過對象配置,第二項,利用item.id 拼成特有的字符串類
<li v-for="(item,index) in board" class="bot-item clearfix" 
:class="[{'red':index==0?true:false},'red'+item.id]">

img src屬性 路徑問題

靜態src能夠直接寫成相對路徑webpack

<img src="../assets/icon/1.png"/>

動態src 推薦使用背景圖代替;web

<div :style="{backgroundImage: 'url(' + img + ')'}"></div>

若是動態src 要寫成模板變量,要經過require 函數請求;這樣webpack才能打包出正確的路徑ajax

<img :src="item.icon"/>

board:[
                {
                  "title":"開放產品",
                  "description":"開放產品是一款開放產品",
                  url:"#",
                  icon:require('../assets/icon/1.png'),
                  class:"mr15 mb15"
                }
    ]

icon:require('../assets/icon/1.png') //webpack 能夠打包的路徑

若是要經過ajax請求mock的的img 目前只找到此方法,把img 放在 static 文件下;寫json的時候用絕對路徑express

slides=[{
  "src":"/static/slideShow/pic4.jpg",  //static 文件 與index.html 同級
  "title":"勇攀高峯",
  "href":"#"
}]


 <img v-if="isShow" :src="slides[nowIndex].src">

使用 vue-resource ajax 數據

安裝npm

cnpm install vue-resource --save

引入json

import resource from 'vue-resource'
Vue.use(resource)

使用api

created(){ //建立應用開始的時候;
  this.$http.get('productList').then(function (data) {
    console.log(data);
  },function (err) {
    console.log(err)
  })
}

本地模擬數據 express

早期的vue-lic下面有dev-server.js和dev-client.js兩文件,請求本地數據在dev-server.js裏配置,在vue 2.0 中 最新的vue-webpack-template 中已經去掉了dev-server.js和dev-client.js 改用webpack.dev.conf.js代替數組

具體的配置代碼參考這個文章

http://blog.csdn.net/u0122073...

ajax 數據回來後怎麼處理

export default {
        data: function () {
            return {
               //json數據申請回來以前,模板中其實已經用到了數據結構,
               //因此,在尚未數據的時候,你就須要先寫出數據結構;不然會報錯 typeErr
              productList:{
                    pc:{
                        title:"",  //先定好的數據結構;
                        list:[]     //由於數據中是重複的部分,能夠不定義
                    },
                    app:{
                      title:"",
                      list:[]
                    }
                },
              news:[],
              board:[]
            }
        },
      created (){
          //經過 => 函數,延續this的引入;否者 then() 中的this 並非指向 實例的this;
          this.$http.get('/api/productList').then((res)=> {
          //模擬回來的數據,要看準res的結構;確保讀到數據,並複製給this.data;
            this.productList = res.data.data;      
          },(err)=> {
            console.log(err)
          })
          this.$http.get('/api/news').then( (res)=> {
            this.news = res.data.data;
          }, (err) => {
            console.log(err)
          })
          this.$http.get('/api/board').then((res)=> {
            this.board = res.data.data;
          },(err)=> {
            console.log(err)
          })
        },
    }

寫一個幻燈片組件

完整的代碼是:

父組件

<div class="slide">
    //傳入參數 ,綁定自定義事件
   <slide :slides="slides" :time="2000" @onchange="slideChange"></slide>
</div>

//把資源申請回來

 methods:{
        slideChange(index){
            console.log(index)
        }
      },
 created (){
    this.$http.get('/api/slides').then((res)=> {
        this.slides = res.data.data;
      },(err)=> {
        console.log(err)
      })
}

幻燈片組件完整代碼

<template>
    <div @mouseover="stopEvnet" @mouseout="runEvent">
      <div class="slide-box">
         <div class="img-list clearfix">
            <a :href="slides[imgIndex].href">
              <transition name="slide-trans">
                <img v-if="isShow" :src="slides[imgIndex].src">
              </transition>
              <transition name="slide-trans-old">
                <img v-if="!isShow" :src="slides[imgIndex].src">
              </transition>
            </a>
         </div>
        <div class="tools">
          <div class="li-tools">
            <div class="left" @click="goto(toLeft)"> < </div>
            <ul>
              <li v-for="(item,index) in slides" :class="{'on':index==imgIndex}" @click="goto(index)">{{index+1}}</li>
            </ul>
            <div class="right" @click="goto(toRight)"> > </div>
          </div>
        </div>
        <p class="img-title">{{slides[imgIndex].title}}</p>
      </div>
    </div>
</template>
<script>
    export default {
        data: function () {
            return {
              imgIndex:2,
              timeEv:null,
              isShow:false
            }
        },
        props:{
          slides:{
            type:Array,
            default:[]
          },
          time:{
            type:Number,
            default:1000
          }
        },
        computed:{
          toRight(){
            let a = this.imgIndex+1;
            if(a>3){
              a = 0
            }
            return a
          },
          toLeft(){
            let b = this.imgIndex-1;
            if(b<0){
              b = 3
            }
            return b
          }
        },
        methods:{
          goto (index) {
            this.isShow = false
            setTimeout(() => {
              this.isShow = true
              this.imgIndex = index
              this.$emit('onchange',index)
            }, 10)
          },
          stopEvnet(){
              clearInterval(this.timeEv)
          },
          runEvent(){
            this.timeEv = setInterval(()=> {
              this.goto(this.toRight)
            },this.time);
          }
        },
        mounted(){
          this.runEvent();
        }
    }
</script>
<style scoped>

.slide-trans-enter-active {
  transition: all .5s;
}
.slide-trans-enter {
  transform: translateX(730px);
}
.slide-trans-old-leave-active {
  transition: all .5s;
}
.slide-trans-old-leave-to{
  transform: translateX(-730px);
}

  .slide-box{
    width: 730px;
    height: 436px;
    position: relative;
    overflow: hidden;
  }
  .img-list{
    min-height: 436px;
  }
  .img-list a{
    height: 100%;
  }
  .img-list img{
    width: 730px;
    height: 436px;
    position: absolute;
  }
  .tools{
    width: 100%;
    height: 50px;
    background-color: #000;
    opacity: 0.5;
    position: absolute;
    bottom:0px;
    left: 0;
  }
  .img-title{
    position: absolute;
    bottom:15px;
    left: 10px;
    z-index: 10;
    color: #fff;
  }
  .li-tools{
    position: absolute;
    bottom:12px;
    right: 10px;
  }
  .left,.right,li,ul{
    display: inline-block;
    padding:2px 5px;
    color: #fff;
    cursor: pointer;
    margin:0 5px;
    border-radius: 5px;
  }
  li.on{
    background-color: #12b7f5;
  }
</style>
須要注意的地方有幾個
  • 確保ajax 數據回來後才作渲染

console 出現這種報錯,可是模板渲染正常,一切正常

clipboard.png

緣由就是,ajax 請求的數據還沒回到,模板已經開始渲染,因此讀不到這個href屬性;
處理辦法 是加個判斷;等數據存在後,再去讀值

clipboard.png

  • 清楚觸發定時器的 vue鉤子;
//鼠標進入時
@mouseover="stopEvnet" 

//鼠標出去時
@mouseout="runEvent"
  • 只用了一次for 循環;區別於與 jq幻燈片的寫法

jq的幻燈片 可能咱們習慣把 全部圖片都先遍歷出來,而後 寫js 讓img-box 滾動;

看vue代碼,發現只用了在li 的一次for循環;所有數據 所有依賴於一個變量 imgIndex 讀取;改變imgIndex的值,其它數據自動轉換;

這是利用了vue的雙向綁定機制;只須要更換 index 就會自動 讀取出對應的src,達到換圖片的目的;

注意for循環覺得,讀取數據的寫法

<a :href="slides[imgIndex].href">

<img :src="slides[imgIndex].src">

<p class="img-title">{{slides[imgIndex].title}}</p>
  • 只寫了一個goto 方法實現 點擊切換,左右切換

goto 的功能功能,就是點擊哪一個li,切換到哪一個數據;

利用 vue的 計算屬性功能:監聽一個值,返回一個處理後的值; 監聽left 的click 事件;goto到一個 toLeft 的計算值; 實現優雅的切換;

由於 計算屬性toRight 能夠當作一個數值來使用;因此,計時器切換的時候,模擬點擊 right 能夠寫成

this.timeEv = setInterval(()=> {
  this.goto(this.toRight) //    this.toRight 獲得當前img的下一個數據的index
},this.time);
  • 切換動畫的實現(有點抽象)

讓兩個相同的圖片互斥顯示;

slide-trans 負責進入的動畫; slide-trans-old 負責移出的動畫

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

初始化的時候,讓 isShow = false;就是說,讓負責移出的動畫的img 先渲染;

goto 的時候,先讓 isShow = false 移出動畫會被執行,這時的index是當前的圖片index;意思是,讓當前顯示的img執行 移出動畫

而後延遲 500毫秒,讓isShow = true,移入動畫會被執行,這時的index已經改變爲 goto 參數的index,意思就是將要跳轉到的圖片的index,因此,其實就是讓 要顯示的圖片 執行移入動畫;

goto (index) {
    this.isShow = false
    setTimeout(() => {
      this.isShow = true
      this.imgIndex = index
    }, 500)
  },
  • 切換動畫的寫法

動畫的過程有幾個階段:

v-enter(進入動做初始狀態),
v-enter-active(進入動做到完成進入動做的中間過程)
v-enter-to(進入動做結束的狀態)
v-leave(離開動做初始狀態),
v-leave-active(離開動做到完成離開動做的中間過程)
v-leave-to(離開動做結束的狀態)

參考:https://vuefe.cn/v2/guide/tra...

//slide-trans 動畫的 進入動做 到 完成進入動做 的 中間過程,全部動畫時間爲0.5秒
.slide-trans-enter-active {
  transition: all .5s;
}
// 進入動做初始狀態 translateX(730px)
.slide-trans-enter {
  transform: translateX(730px);
}

//slide-trans-old動畫 離開動做 到 完成離開動做 的中間過程,全部動畫時間爲0.5秒,
// transform: translateX(-730px)爲何寫在這裏?待了解
.slide-trans-old-leave-active {
  transition: all .5s;
  transform: translateX(-730px);
}

直觀上 enter動畫 和 leave 動畫是一個相反的過程,因此也能夠寫成;效果同樣;

.slide-trans-old-leave-active {
  transition: all .5s;
}
.slide-trans-old-leave-to{
  transform: translateX(-730px);
}
相關文章
相關標籤/搜索