Vue-travel學(xué)習(xí)筆記

vue去哪網(wǎng)跟學(xué)筆記

記錄學(xué)習(xí)點(diǎn)滴

1. 初始化項(xiàng)目

1.1 手機(jī)顯示配適

minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" 阻止用戶手滑發(fā)大縮小頁面

1.2 初始化樣式 -->引入reset.css

1.3 移動(dòng)端多倍屏邊框不準(zhǔn)的問題 --> 引入 border.css

1.4 解決click延遲300ms的問題 --> 引入 fastclick 庫

  • npm install fastclick --save
  • 在main.js中引入fastclick import fastClick from 'fastclick'
  • fastClick.attach(document.body)

1.5 注冊阿里的iconfont并創(chuàng)建travel項(xiàng)目

2. 首頁的開發(fā)

2.1 準(zhǔn)備工作&注意事項(xiàng)

(1).項(xiàng)目中使用stylus來編寫css樣式

npm install stylus --save npm install stylus-loader --save

  • 要學(xué)習(xí)stylus語法
  • 學(xué)習(xí)flex布局 rem布局的用法

(2). iconfont的使用和代碼的優(yōu)化

  • 如何使用iconfont
  1. 進(jìn)入iconfont官網(wǎng),選擇圖標(biāo),加入購物車放入項(xiàng)目中
  2. 下載zip包并解壓,把字體文件放入src/assets/styles/iconfont文件夾中
    把iconfont.css放在src/assets/styles中,把css中的文件路徑改一下(因?yàn)榇藭r(shí)>css和字體文件不在同一目錄下了,默認(rèn)的css和字體文件在一個(gè)文件夾內(nèi))
  3. 在main.js中引入字體文件 import './assets/styles/iconfont.css'
  4. 上述完成后,在想要使用圖標(biāo)的標(biāo)簽上加入 iconfont 類名,就可以在頁面中使用 >圖標(biāo)了,可以用每一個(gè)圖標(biāo)類名來引用,也可以使用編碼的形式來使用,每一個(gè)圖標(biāo)的編碼
    都在 iconfont官網(wǎng)我的項(xiàng)目圖標(biāo)里面,點(diǎn)擊復(fù)制圖標(biāo)就能得到圖標(biāo)編碼;
  • 優(yōu)化代碼

有些代碼的樣式是多變的,我們可以將可變的css放入assets styles文件夾的varibles.styl文件中,方便以后的更愛--》改一處全部就改的效果

例如:
我們的背景色就是一個(gè)可改變的css參數(shù),我們可以在varibles.styl中定義 $bgcolor = #00bcd4 背景色
而后在樣式里引入這個(gè)styl文件即可
@import '../../../assets/styles/varibles.styl';
background-color $bgcolor

但是@import文件引入的前綴非常長,在可以使用@符號可以優(yōu)化此問題
因?yàn)槲覀冊趙ebpack配置js文件中制定'@': resolve('src'), 制定了@就是src目錄
但是我們在css中引入css文件是 需要使用src的時(shí)候 要在@前面再多加一個(gè)~符號

相同的 我們的sytles文件夾多次使用 我們可以在webapck.config.js文件中定義
'styles': resolve('src/assets/styles'),
這樣我們使用styles目錄的時(shí)候就可以簡化了

(3). 在github上創(chuàng)建新分支

在企業(yè)級的開發(fā)里,每一個(gè)新功能或新模塊的開發(fā)都是在一個(gè)新的分支上進(jìn)行
開發(fā)完成后再合并到master主分支上

在github上創(chuàng)建倉庫:
Create a new repository on the command line

touch README.md
git init
git add README.md
git commit -m "first commit"
git remote add <name> <url> 
git push -u origin master

在本地新建一個(gè)分支: git branch Branch1
切換到你的新分支: git checkout Branch1
將新分支發(fā)布在github上: git push origin Branch1
在本地刪除一個(gè)分支: git branch -d Branch1
在github遠(yuǎn)程端刪除一個(gè)分支: git push origin :Branch1   (分支名前的冒號代表刪除)

(4).管理分支的一些語法

  1. 查看分支
  • 查看本地分支
$ git branch
* master
  • 查看遠(yuǎn)程分支
    git branch -r
  • 查看所有分支
    git branch -a
  1. 本地創(chuàng)建新的分支
    git branch [branch name]

  2. 切換到新的分支
    git checkout [branch name]

  3. 創(chuàng)建+切換分支
    git checkout -b [branch name]
    git checkout -b [branch name] 的效果相當(dāng)于以下兩步操作:
    git branch [branch name] + git checkout [branch name]

  4. 將新分支推送到github
    git push origin [branch name] orgin是你遠(yuǎn)程倉庫的名字

  5. 刪除本地分支
    git branch -d [branch name]

  6. 刪除github遠(yuǎn)程分支
    git push origin :[branch name] 分支名前的冒號代表刪除。

  7. 合并分支

git checkout master
git merge <name>/<new-branch-name>
git push

2.2 首頁輪播

首頁輪播圖,采用vue-awesome-swiper插件

vue-awesome-swiper github

npm裝包

npm install vue-awesome-swiper@2.6.7 --save

使用方法和使用步驟參考官網(wǎng)

在swiper-slide標(biāo)簽里填入img屬性并引入src 加入類swiper-img 在style里定義width的寬度為100% 即可適應(yīng)輪播

此時(shí)的頁面在網(wǎng)速不好的情況下會(huì)發(fā)生頁面抖動(dòng) 如何解決
在輪播元素的最外層加一個(gè)class為wrapper的div 然后定義.wrapper的樣式

  .wrapper
    overflow hidden
    width 100%
    height 0
    padding-bottom: 26.67%
    background #eee
    .swiper-img
      width 100%

這樣就能把輪播圖的位置保持撐起,就不會(huì)發(fā)生頁面抖動(dòng)了

此時(shí),又有一個(gè)問題,我們需要導(dǎo)航點(diǎn),怎么實(shí)現(xiàn)

swiperOption: {
        pagination: '.swiper-pagination'
      }

在swiperOption里添加pagination配置項(xiàng)就可以了

此時(shí)的導(dǎo)航激活狀態(tài)是藍(lán)色的 怎么更改為白色?
我們可以在頁面查看小原點(diǎn)的類名為swiper-pagination-bullet-active,我們?nèi)绻苯釉跇邮街行薷倪@個(gè)樣式的background,是達(dá)不到更改效果的,為什么,因?yàn)榇藭r(shí)的樣式是當(dāng)前組件的樣式,而這個(gè)小圓點(diǎn)屬于swiper組件的樣式
這時(shí),我們可以使用穿透樣式來實(shí)現(xiàn)
在樣式的最前面編寫如下代碼

.wrapper >>> .swiper-pagination-bullet-active
    background: #eee

這樣,就能達(dá)到從一個(gè)組件穿刺到另一個(gè)組件的樣式更改

最后 使用v-for 對圖標(biāo)進(jìn)行列表渲染循環(huán),把數(shù)據(jù)保存到data的swiperList對象中

2.3 圖標(biāo)區(qū)域頁面布局

初始化

  • git創(chuàng)建分支
  • 新建icons.vue
  • Home.vue中引入組件

圖標(biāo)區(qū)域邏輯實(shí)現(xiàn)

當(dāng)頁面圖標(biāo)大于八個(gè) 可以左右拖動(dòng)

  1. 在圖標(biāo)元素外加入swiper-slide標(biāo)簽和swiper標(biāo)簽

2.4 首頁推薦組件開發(fā)

2.5 周末游組件開發(fā)

3 使用ajax傳遞數(shù)據(jù)

3.1 準(zhǔn)備工作

vue官方推薦使用axios來完成ajax數(shù)據(jù)的請求

  • 裝包: npm install axios --save
  • home組件中引入axios
  • 結(jié)合vue的mouted生命周期鉤子來完成請求

如果每個(gè)子組件都發(fā)送一個(gè)ajax請求來獲取數(shù)據(jù)的話,一個(gè)首頁就要請求多個(gè)ajax請求,會(huì)使我們的程序效率下降,我們可以在home組件請求一個(gè)ajax請求,把數(shù)據(jù)傳給子組件,這樣就能提高效率

怎么模擬后臺(tái)的數(shù)據(jù)呢?

因?yàn)槲覀冺撁嬲苯釉L問static文件夾,所以我們可以在static下創(chuàng)建一個(gè)mock文件夾,里面定影json文件來模擬后臺(tái)數(shù)據(jù)

但是我們并不想提交我們的數(shù)據(jù)到github,所以我們可以在gitnore文件中排除文件

我們上線后的ajax請求地址都是基本都是相對路徑'/api/下的json文件,但是此時(shí)我們的文件在static/mock文件夾中,我們可以把a(bǔ)xios的請求地址改成我們本地的static/mock,但是這樣做的話以后上線前要更改代碼,這是不可取的

即使用api文件目錄,又能獲取到static中的文件,怎么辦?

我們可以使用vue基于webpack-dev-serve的一個(gè)配置選項(xiàng)來解決這個(gè)問題,在vuecli生成的config文件夾中index.js文件有一個(gè)proxyTable配置選項(xiàng)
我們可以這樣來替換我們的請求地址:

proxyTable: {
      '/api': {
        target: 'http://localhost:8080',
        pathRewrite: {
          '^/api': '/static/mock'
        }
      }
    }

這樣,就能完美解決我們的問題了

注意,json格式的每一項(xiàng)的最后一項(xiàng)不要加帶分號,這樣可能會(huì)導(dǎo)致json數(shù)據(jù)解析失敗

3.2 首頁父子組件數(shù)據(jù)傳遞

由于home組件獲取json數(shù)據(jù)后,應(yīng)該向子組件傳遞數(shù)據(jù),這就涉及到父組件向子組件傳值的問題
父組件通過屬性向子組件傳值,子組件props接受數(shù)據(jù)

methods: {
  getHomeInfo () {
    axios.get('/api/index.json') // 返回的是一個(gè)promise對象,后面使用then
      .then(this.getHomeInfoSucc) // 獲取成功執(zhí)行g(shù)etHomeInfoSucc函數(shù)
  },
  getHomeInfoSucc (res) {
    res = res.data
    if (res.ret && res.data) {
      const data = res.data
      this.city = data.city
      this.swiperList = data.swiperList
      this.iconList = data.iconList
      this.recommendList = data.recommendList
      this.weekendList = data.weekendList
    }
    console.log(res)
  }
},
mounted () {
  this.getHomeInfo() // 頁面掛載好執(zhí)行這個(gè)方法ajax獲取數(shù)據(jù)
}

3. 首頁的開發(fā)

3.1 初始化準(zhǔn)備

  • 配置路由
  • 創(chuàng)建組件

3.2 header開發(fā)

  • 創(chuàng)建組件
  • city.vue導(dǎo)入

3.3 搜索框

  • 創(chuàng)建組件
  • city.vue導(dǎo)入

3.4 城市列表

  • 創(chuàng)建組件
  • city.vue導(dǎo)入

title聊表的邊框不太明顯,可以給其添加樣式

  .border-topbottom
    &:before
      border-color #ccc
    &:after
      border-color #ccc

因?yàn)槲覀儗⒁褂靡粋€(gè)滾動(dòng)插件--Better-scroll來完成此頁面,所以我們應(yīng)該禁止頁面的超出滾動(dòng)

.list
  overflow hidden
  position absolute
  top 1.58rem
  left 0
  right 0
  bottom 0

使用Better-scroll

  • 裝包 npm install better-scroll --save
  • import Bscroll from 'better-scroll'
  • 在vue的mounted時(shí)掛載一個(gè)better-scroll實(shí)例

因?yàn)檫@個(gè)組件需要最外城的wrapper dom元素 我們給最外層標(biāo)簽添加ref="wrapper"屬性

3.5 字母滑動(dòng)選擇器

  • 創(chuàng)建組件
  • city.vue導(dǎo)入

使用flex布局使其居中

3.6 ajax獲取城市數(shù)據(jù)

  • 在city.vue中引入city.json
  • 父子間向子組件傳遞消息

3.7 兄弟組件聯(lián)動(dòng)

Todo1. 點(diǎn)擊右側(cè)字母表 list也跳到對應(yīng)的城市也部分

循環(huán)字母列表時(shí)為每一個(gè)字母綁定點(diǎn)擊事件
alphabet組件傳遞消息給父組件city,city在傳遞消息給list組件,實(shí)現(xiàn)Alphabet和list的兄弟傳值

  • Alphabet.vue
    @click="handleLetterClick"
handleLetterClick (e) {
      this.$emit('change', e.target.innerText)
    },
  • City.vue
    @change="handleLetterChange"
handleLetterChange (letter) {
      this.letter = letter
    }

:letter="letter" 傳遞給list.vue組件

  • List.vue
    props 接收 letter
    通過watch來監(jiān)聽letter的變化
  watch: {
    letter () { // 監(jiān)聽letter改變
      if (this.letter) {
        const element = this.$refs[this.letter][0]
        // refs-->通過為每個(gè)循環(huán)綁定ref ref的值對應(yīng)的是每個(gè)key 也就是每個(gè)字母
        // [0]-->取到的是一個(gè)數(shù)組,具體的元素dom節(jié)點(diǎn)為數(shù)組的第一項(xiàng)
        this.scroll.scrollToElement(element)
        // scroll插件的而一個(gè)方法幫我們調(diào)到制定元素
      }
    }
  }

Todo2. 滑動(dòng)右側(cè)字母表,list跟著滑動(dòng)到對應(yīng)的位置

  • Alphabet.vue
    綁定star move end 三個(gè)觸摸方法
  @touchstart="handleTouchStart"
  @touchmove="handleTouchMove"
  @touchEnd="handleTouchEnd"

把字母表從cities獲取放到計(jì)算屬性letters中

computed: {
    letters () {
      const letters = []
      for (let i in this.cities) {
        letters.push(i)
      }
      return letters
      // ['A','B','C'...]
    }
  },

將計(jì)算出的滑到哪個(gè)字母$emit傳遞給父元素

handleTouchMove (e) {
      if (this.touchStatus) {
        const startY = this.$refs['A'][0].offsetTop // A元素距離頂部的高度
        const touchY = e.touches[0].clientY - 79 // 手指距離header下邊緣的的距離
        const index = Math.floor((touchY - startY) / 22) // 滑動(dòng)了第幾個(gè)字母
        if (index >= 0 && index < this.letters.length) {
          this.$emit('change', this.letters[index])
        }
        // console.log(index)
      }
    },
  • City.vue
    @change="handleLetterChange"接收來自Alphabet的letter
    :letter="letter" 傳遞給list
    同樣的和1一樣使用watch來監(jiān)視

Todo3. 列表組件優(yōu)化

  1. const startY = this.$refs['A'][0].offsetTop
    startY的值是固定的,可以提取出來

放在updated生命周期函數(shù)鉤子中,因?yàn)閯傞_始加載citise是通過json獲取的,剛開始獲取不到的時(shí)候是空,之后有獲取到了ajax的內(nèi)容,頁面更新,就會(huì)執(zhí)行updated鉤子函數(shù)

  1. 函數(shù)節(jié)流
    手指在屏幕上滑動(dòng)的時(shí)候,函數(shù)執(zhí)行的次數(shù)是非常高的,我們可以采用函數(shù)節(jié)流
    通過定義一個(gè)定時(shí)器,來大大提高我們代碼性能
    handleTouchMove (e) {
      if (this.touchStatus) {
        if (this.timer) {
          clearTimeout(this.timer)
        }
        this.timer = setTimeout(() => {
          const touchY = e.touches[0].clientY - 79 // 手指距離header下邊緣的的距離
          const index = Math.floor((touchY - this.startY) / 22) // 滑動(dòng)了第幾個(gè)字母
          if (index >= 0 && index < this.letters.length) {
            this.$emit('change', this.letters[index])
          }
          // console.log(index)
        }, 10)
      }
    }

3.7 完善搜索框--邏輯

  • 在search.vue增加search-content類 用于展示搜索內(nèi)容
    <div class="search-content" ref="search" v-show="keyword">
      <ul>
        <li
          class="search-item border-bottom"
          v-for="item of list"
          :key="item.id"
        >
          {{item.name}}
        </li>
        <li class="search-item border-bottom" v-show="hasNoData">
          沒有找到匹配數(shù)據(jù)
        </li>
      </ul>
    </div>

ref = search 用于在mounted掛載滾動(dòng)插件 v-show="keyword" 沒有輸入內(nèi)容不顯示

  • 在watch中監(jiān)聽keyword的變化,使用循環(huán)遍歷,通過篩選把符合的city追加到list數(shù)組

  • 使用v-for循環(huán)輸出list

  • 中間使用了定時(shí)器來實(shí)現(xiàn)函數(shù)節(jié)流來提高性能

4.使用Vuex來實(shí)現(xiàn)數(shù)據(jù)共享

4.1 實(shí)現(xiàn)city和home組件的數(shù)據(jù)聯(lián)動(dòng)

我們想要城市頁面和首頁實(shí)現(xiàn)數(shù)據(jù)共享
City.vue和Home.vue是沒有一個(gè)父組件可供中轉(zhuǎn),那么想進(jìn)行兩者的通信,該怎么辦呢?

Vuex

  • npm install vuex --save
  • 在src目錄下創(chuàng)建store文件夾并新建index.js文件
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({ // 向外暴露一個(gè)由Actions State Mutations 三個(gè)組成的系統(tǒng)對象
  state: {
    city: 'aaa'
  },
  // actions: {
  //   changeCity (ctx, city) { // 借助這個(gè)ctx上下文來使用commit方法來調(diào)用Mutations完成數(shù)據(jù)的更改
  //     console.log(city)
  //     console.log(ctx)
  //     ctx.commit('MchangeCity', city)
  //   }
  // },
  mutations: {
    MchangeCity (state, city) {
      state.city = city
    }
  }
})

  • 在main.js中引入
    import store from './store' // vuex 這樣我們?nèi)侄寄茉L問到store了
    并在vue實(shí)例中申明store,這樣,我們以后就能使用vuex的數(shù)據(jù)了
    {{this.$store.state.city}}

具體使用

  1. 把要公用的數(shù)據(jù)(例如city)定義到store/index.js的state中,在頁面中把有city的地方換成 {{this.$store.state.city}}
  2. 我們?yōu)檠h(huán)的每一個(gè)城市按鈕綁定一個(gè)方法 @click="handleCityClick(item.name)
    并在methods中定義方法:
  methods: {
    handleCityClick (city) {
      this.$store.commit('MchangeCity', city) // 想要通過actions調(diào)用方法必須使用dispatch 或者 跳過actions直接通過commit來調(diào)用Mutations
      this.$router.push('/') // 選擇后跳轉(zhuǎn)到主頁 實(shí)現(xiàn)聯(lián)動(dòng) 用了vue-router的編程跳轉(zhuǎn)鏈接
    }
  }
  1. 在store中定義Actions函數(shù)和Mutations函數(shù) 來實(shí)現(xiàn)數(shù)據(jù)的修改

總結(jié):

想要通過vuex來管理公用數(shù)據(jù),想要更改數(shù)據(jù) 要經(jīng)過一下步驟

  1. 組件 ---dispatch---> Actions
  methods: {
    handleCityClick (city) {
      this.$store.dispatch('changeCity', city) // 想要通過actions調(diào)用方法必須使用dispatch
  }
  1. Actions ---commit---> Mutations
actions: {
    changeCity (ctx, city) { // 借助這個(gè)ctx上下文來使用commit方法來調(diào)用Mutations完成數(shù)據(jù)的更改
      ctx.commit('MchangeCity', city)
    }
  },
  1. Mutations ------> State
  mutations: {
    MchangeCity (state, city) {
      state.city = city
    }
  }

在不復(fù)雜的環(huán)境下,有的時(shí)候我們更愛數(shù)據(jù)并不一定需要經(jīng)過Actions,組件可以直接通過commit來使Mutations改變State

  1. 組件 ---commit---> Mutations
  methods: {
    handleCityClick (city) {
      this.$store.commit('MchangeCity', city) // 想要通過actions調(diào)用方法必須使用dispatch
  }
  1. Mutations ------> State
  mutations: {
    MchangeCity (state, city) {
      state.city = city
    }
  }

4.2 vuex的高級使用和localStorage

上述我們已經(jīng)完成了vuex 實(shí)現(xiàn)兩個(gè)不先練的組件的數(shù)據(jù)共享,但是我們一旦刷新我們的頁面,我們的頁面數(shù)據(jù)還是默認(rèn)的我們在store中定義的數(shù)據(jù),如何讓程序記錄我們的操作

使用localStorage來完成
在Mutations定義的方法里 加入:
localStorage.city = city 來記錄我們選擇的城市
在state中
city: localStorage.city || '南陽'
這樣 瀏覽器就能記憶我們選擇的城市了

但是此時(shí)存在一個(gè)問題,瀏覽器如果使用了隱身模式或者關(guān)閉了瀏覽器存儲(chǔ),我們的程序就會(huì)直接報(bào)錯(cuò)無法執(zhí)行
我們可以使用try catch來優(yōu)化一下我們的代碼


vuex高級

  1. 慢慢的 我們的store- index中的代碼越來越多,我們可以把狀態(tài)分開到不同的文件中管理

  2. 使用map輔助函數(shù)來進(jìn)行優(yōu)化

4.3 使用keep-alive優(yōu)化網(wǎng)頁性能

路由發(fā)生切換的時(shí)候 ajax都會(huì)被重新發(fā)送,為什么?

因?yàn)槲覀兊捻撁婷恳淮武秩径紩?huì)執(zhí)行mounted鉤子 而我們的ajax請求就是放在mounted中進(jìn)行的

怎么優(yōu)化?

將我們的router-view坑用keep-alive標(biāo)簽包裹起來

<template>
  <div id="app">
    <keep-alive>
      <router-view/>
    </keep-alive>
  </div>
</template>

頁面被keep-alive包裹起來,就會(huì)是頁面的資源加載到內(nèi)存當(dāng)中,不需要重新渲染,也不需要從新執(zhí)行鉤子,來回返回頁面也只會(huì)獲取一次json
此時(shí),我們的vue中多出來一個(gè)生命周期函數(shù)鉤子:activated

4.4 選擇城市后返回頁面 頁面需要被修改

我們之前寫的代碼是固定的,雖然選擇的城市發(fā)生變化,但是我們的我們的home頁面中的內(nèi)容并沒有變化,怎么辦?

我們home首頁的內(nèi)容是有index.json ajax來獲取的 我們只需要在home組件獲得ajax的時(shí)候 使用?傳參的方式,使得每一個(gè)城市對應(yīng)自己的json文件,就可以了
axios.get('/api/index.json?city=' + this.city

但是此時(shí)的json文件被緩存到了內(nèi)存當(dāng)中,存的還是第一次的值,我們怎么改變緩存的數(shù)據(jù)呢

由于此時(shí)的頁面被keep-alive標(biāo)簽包裹,我們的ajax請求只會(huì)在第一次刷新的時(shí)候被獲取,但是此時(shí)我們需要由城市列表選擇的城市來同步我們首頁的json文件以達(dá)到統(tǒng)一刷新的目的

keep-detail 可以加入exclude="不被緩存的組件名字" 這樣就可以指定排除某個(gè)組件不被緩存

此時(shí)我們可以使用activated生命周期鉤子
因?yàn)樵诒话黭eep-alive標(biāo)簽之后,mounted鉤子不會(huì)執(zhí)行,但是activated鉤子只要頁面重新出現(xiàn),就會(huì)執(zhí)行,所以我們可以在activated鉤子函數(shù)中 判斷頁面選擇的城市和之前的城市是否為一個(gè)城市,如果不是一個(gè)城市,則重新發(fā)送ajax請求
我們在data數(shù)據(jù)中新增一個(gè) lastcity 數(shù)據(jù) 配合activated鉤子使用

activated () {
  if (this.lastcity !== this.city) {
    this.lastcity = this.city
    this.getHomeInfo()
  }
}

5.詳情頁面的制作

創(chuàng)建detail.vue Banner.vue 導(dǎo)入detail路由

5.1 banner的制作

  • 字體圖標(biāo)更新后 記得替換字體文件和iconfont.css的一段 base64的代碼、

  • 使用 background-image linear-gradient 達(dá)到漸變效果

5.2 banner畫廊組件

這個(gè)畫廊組件不僅僅這個(gè)組件中要使用,以后可能在別的地方也會(huì)使用

所以我們新建 src/common/gallary/Gallary.vue 編寫畫廊組件為以后復(fù)用

  • 使用swiper插件實(shí)現(xiàn)圖片輪播滾動(dòng)

  • 當(dāng)我們點(diǎn)擊banner的時(shí)候調(diào)到畫廊頁面,會(huì)發(fā)現(xiàn)渲染有問題,怎么辦?
    點(diǎn)擊跳轉(zhuǎn)dom節(jié)點(diǎn),會(huì)使得我們的css屬性計(jì)算出錯(cuò),從而造成錯(cuò)誤,swiper為我們提供了一組配置,我們在配置項(xiàng)里添加 observeParents: trueobserver: true
    observeParents: 將observe應(yīng)用于Swiper的父元素。當(dāng)Swiper的父元素變化時(shí),例如window.resize,Swiper更新。
    observer: 啟動(dòng)動(dòng)態(tài)檢查器(OB/觀眾/觀看者),當(dāng)改變swiper的樣式(例如隱藏/顯示)或者修改swiper的子元素時(shí),自動(dòng)初始化swiper。

5.3 漸隱逐顯的header

  • 頁面有兩個(gè)頭部,一個(gè)是剛進(jìn)去的的定位為abs的返回按鈕,另外一個(gè)是定位是fixed頭部導(dǎo)航

  • 剛開始我們使用v-show = showAbs 和 v-show = !showAbs 來分別控制兩個(gè)頭部,使其只顯示一個(gè)

  • 使用 window.addEventListener('scroll', this.handleScroll) 來監(jiān)聽滾動(dòng)的距離以切換哪個(gè)頭部的展示 這個(gè)方法放在activated鉤子里

  • handleScroll方法使用 document.documentElement.scrollTop 監(jiān)聽滾動(dòng)離頂部的距離

展示效果做好,剩下漸隱漸顯的效果

在 fixed 的頭部標(biāo)簽綁定樣式對象 :style="opacityStyle"

handleScroll () {
      const top = document.documentElement.scrollTop
      if (top > 60) { // 過渡階段
        let opacity = top / 140 // 過渡效果
        opacity = opacity > 1 ? 1 : opacity
        this.opacityStyle = { opacity }
        this.showAbs = false
      } else {
        this.showAbs = true
      }
    }
  }

5.4 事件綁定的相關(guān)問題

我們在5.3中,使用 window.addEventListener('scroll', this.handleScroll) 來監(jiān)聽滾動(dòng)的距離,但是這個(gè)監(jiān)聽方法被綁定在了全局window中,所以我們的其他頁面滾動(dòng)時(shí)也會(huì)執(zhí)行這段代碼

那么 我們怎么樣才能使其只綁定在詳情頁呢?

當(dāng)我們使用keep-alive標(biāo)簽的時(shí)候,activated鉤子函數(shù)產(chǎn)生的同時(shí),也產(chǎn)生了一個(gè)deactivated的函數(shù)鉤子,在activated綁定,在deactivated解綁即可

  activated () {
   window.addEventListener('scroll', this.handleScroll) // 頁面展示綁定
  },
  deactivated() {
    window.removeEventListener('scroll', this.handleScroll)
  }

5.5 遞歸列表組件

組件自生調(diào)用自己

5.6 ajax數(shù)據(jù)替換

我們發(fā)現(xiàn),首頁滑動(dòng)到底部,在點(diǎn)擊詳情頁面,詳情頁面初始狀態(tài)也是在底部,怎么辦?

頁面滑動(dòng) 各個(gè)組件會(huì)相互影響,我們可以在路由的配置選項(xiàng)中添加如下配置:

scrollBehavior: function (to, from, savedPosition) {
  return savedPosition || { x: 0, y: 0 }
}

router進(jìn)階

每個(gè)組件的export defalut的name是干什么用的?

我們目前接觸到的:

  1. 遞歸組件中可以用到它
  2. 對某個(gè)頁面取消緩存的時(shí)候
  3. vue tools中組件的顯示名字

6 Vue項(xiàng)目上線前準(zhǔn)備

6.1 Vue項(xiàng)目的接口聯(lián)調(diào)

我們之前都是自己模擬后端的數(shù)據(jù),實(shí)際項(xiàng)目中,我們是要和后端的數(shù)據(jù),實(shí)現(xiàn)項(xiàng)目聯(lián)調(diào),如何進(jìn)行?

把mock中的數(shù)據(jù)替換成真正的后端服務(wù)器數(shù)據(jù)

把config index.js 中的api制定的路徑改為后端服務(wù)器的地址 一般都是本地80端口,一般是一下的形式

proxyTable: {
  '/api': {
    target: 'http://localhost:80' 
  }
}

6.2 Vue項(xiàng)目的真機(jī)測試

我們的項(xiàng)目是 通過 Webpack dev server 來進(jìn)行的 它默認(rèn)不支持ip地址的訪問方式,要把它的默認(rèn)配置項(xiàng)修改

在package.json下 修改dev配置項(xiàng) webpack-dev-server --host 0,0,0,0
這樣,就可以直接通過手機(jī)用ip地址來訪問我們的項(xiàng)目

在真機(jī)上,我們拖動(dòng)字母表,會(huì)發(fā)現(xiàn)整個(gè)頁面都跟著滾動(dòng),出現(xiàn)了bug,怎么半?

@touchstart.prevent="handleTouchStart" 組織拖動(dòng)的默認(rèn)行為

在低版本的安卓瀏覽器,可能出現(xiàn)白屏現(xiàn)象,怎么辦?

出現(xiàn)白屏現(xiàn)象的原因大部分是因?yàn)槭謾C(jī)瀏覽器不支持promise特性,我們在項(xiàng)目中安裝一個(gè)第三方的包

  • npm install babel-polyfill --save
  • 在main.js引入包 import 'babel-polyfill'

6.3 Vue項(xiàng)目的打包上線

  1. 運(yùn)行命令 npm run build 生成一個(gè)能被瀏覽器運(yùn)行的代碼,打包完成后,項(xiàng)目目錄中多出來一個(gè)dist文件夾,里面就是是上線代碼
  2. dist文件夾里的文件放到服務(wù)器跟目錄中,就能上線了
  3. 如果想把上線文件放到根目錄以外的地方,我們可以更改我們的config/index.js --> build--> assetsPublicPath路徑

End To Do

vue基礎(chǔ)官方文檔熟連掌握

VueRouter 細(xì)節(jié)

Vuex 細(xì)節(jié)

Vue 服務(wù)器端渲染 (難)

Webpack Bable Es6

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容