国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > JS > 正文

利用vue重構(gòu)有贊商城的思路以及總結(jié)整理

2024-05-06 16:48:23
字體:
供稿:網(wǎng)友

這個是我的第一個vue項目,歷時了兩個多星期完成吧,通過這個項目了解了vue框架的基本語法以及生命周期等特性,并且了解了vue-loader、vue-cli、vue-router、vuex的基本使用方法,以及使用到axios,swiper,mint-ui,Volecity庫收獲頗深,因此想在此簡單地敘述一下重構(gòu)有贊商城的基本思路以及當(dāng)中的一些重要操作,另外當(dāng)作對自己項目的回顧以及相關(guān)vue知識的總結(jié)。

以下是本次項目的代碼鏈接和預(yù)覽鏈接:

代碼鏈接:https://github.com/Leonardo-zyh/Vue-youzanStore
預(yù)覽鏈接:https://leonardo-zyh.github.io/Vue-youzanStore/dist1/  

首先這次重構(gòu)有贊商城使用的是一個多頁面應(yīng)用的重構(gòu)思路,因此在進(jìn)行重構(gòu)之前要對項目文件進(jìn)行一些配置和調(diào)整,具體的操作的話可以點(diǎn)擊以下這個鏈接進(jìn)行查看:基于vue-cli搭建一個多頁面應(yīng)用

在完成了多頁面應(yīng)用的基礎(chǔ)結(jié)構(gòu)的搭建之后,會出現(xiàn)項目根目錄下有一個src文件夾,src文件里有components、modules、pages三個文件夾的情況,而components文件夾是用來放置一些共用的vue組件的,而modules文件夾里是放置一些共用的css、js模塊,至于最后的pages文件夾則是用來放置有贊商城的不同頁面的文件,每個頁面都會在pages內(nèi)呈一個單獨(dú)的文件夾,里面會放置關(guān)于這個頁面的獨(dú)有的所有文件。

在這里先說明一下,重構(gòu)過程中所有獲取到的數(shù)據(jù),都是通過使用在easymock上編寫對應(yīng)的接口(原在數(shù)據(jù)在rap2上,但是接口數(shù)據(jù)不穩(wěn)定且無法搭建在github上),然后通過axios發(fā)送異步請求來獲取到的模擬的數(shù)據(jù),這是模仿真實的開發(fā)環(huán)境下的操作,具體的實現(xiàn)過程的話可以參考easymock以及我在github上面的源碼文件。

以下是重構(gòu)有贊商城的所需的頁面列表,一共有六個頁面,分別為:

1.首頁
2.目錄分類頁
3.商品搜索列表頁
4.商品詳情頁
5.購物車頁面
6.個人中心地址管理頁面
接下來我們會逐個頁面來說說他們的重構(gòu)思路

然后我們會用到的一些第三方插件,分別為:

  • axios
  • swiper
  • mint-ui
  • Volecity
  • qs庫

一、首頁

vue,重構(gòu),有贊商城

首頁的整體結(jié)構(gòu)是,頂部一個無縫輪播組件,中間是三個推薦的商店鏈接,然后再下面是一個“最熱商品推薦”的商品列表,然后最底下是一個底部導(dǎo)航欄組件一共四部分,對于中間三個推薦商店鏈接我這邊暫不做處理,原因是關(guān)于并沒有重構(gòu)商店頁面的計劃。

1、無縫輪播組件

那我們首先來說一下輪播組件,首先我們需要在src目錄下的compnents文件夾里新建一個輪播組件文件,輪播的話我們會直接選擇使用swiper插件提供的輪播組件庫,我們只需把它封裝到一個組件文件中即可,具體的操作在這里我就不詳細(xì)說明了,這里只強(qiáng)調(diào)兩個需要注意的問題:

1.應(yīng)不應(yīng)該在輪播組件放入圖片數(shù)據(jù)呢?

回答:不應(yīng)該,原因是為了使得輪播組件獨(dú)立出來,在不同的組件中得以復(fù)用,并且使其可以適應(yīng)不同規(guī)格不同數(shù)量的圖片,因此我們的輪播組件只負(fù)責(zé)展示數(shù)據(jù),不負(fù)責(zé)拿數(shù)據(jù),數(shù)據(jù)應(yīng)該通過props從父組件中獲取。

<Swipe :lists="bannerLists" name="swpie.vue" v-if="bannerLists"></Swipe>
new Swiper('.swiper-container',{   loop:true,   pagination: '.swiper-pagination',   autoplay: 2000  })  getBanner(){//獲取輪播數(shù)據(jù)   this.$http.get(url.banner).then(res=>{    this.bannerLists = res.data.lists       })

2.關(guān)于swiper的配置應(yīng)將其寫在輪播組件的生命周期的哪一部分呢?

回答:首先我們需要了解的是swiper是對DOM節(jié)點(diǎn)進(jìn)行操作的,所以swiper的配置應(yīng)該寫在組件的mounted生命周期鉤子里,因為在這個階段已經(jīng)在頁面上生成了該組件對應(yīng)的DOM節(jié)點(diǎn);另一方面,swiper組件里的數(shù)據(jù)是swiper的父組件異步獲取后傳遞給swiper的,因此應(yīng)該等swiper拿到了傳遞的數(shù)據(jù)之后再對這個組件進(jìn)行渲染,因此需要給這個組件添加一個v-if="bannerLists"的判斷,判斷swiper組件是否獲取到數(shù)據(jù),只有獲取到了數(shù)據(jù)才生成這個DOM節(jié)點(diǎn)。

2、“最熱商品推薦”的商品列表

關(guān)于這個“最熱商品推薦”的商品列表的重構(gòu)也非常簡單,只需通過axios發(fā)送你想獲取的商品列表的頁數(shù)和每頁的展示商品的個數(shù)的請求到對應(yīng)的接口中,就可以獲取到對應(yīng)的商品列表的數(shù)據(jù),然后再通過v-for把每個商品的圖片、名稱和價格渲染到頁面中即可。

同樣的,這里有兩個值得注意的問題:

1.獲取到的價格的格式并不統(tǒng)一,如何來使得這些價格的格式統(tǒng)一起來?

回答:這里需要用到vue實例里的一個自帶屬性filters來對數(shù)據(jù)進(jìn)行過濾,在vue1.0的時候,filters里面會有自帶的過濾器,不過在vue2.0時被移除了,因此需要我們來自己寫所需的過濾器的過濾方式:

filters:{  currency(num){    num=num+''    let arr=num.split('.')    if (arr.length===1){      return num+'.00'    } else {      if (arr[1].length===1){        return num+'0'      } else return num    }  }}

只有在渲染頁面時,只要對你想進(jìn)行的數(shù)據(jù)后加上該過濾器即可:

<div class="price">¥{{list.price | currency}}</div>

2.如何做到下來商品列表就發(fā)送對應(yīng)的請求來更新一頁新的商品列表?

回答:這里我們使用到了mint-ui,一個移動端分頁效果庫,然后我們使用它文檔上面對應(yīng)的infinite scroll的api來達(dá)到我們想要的效果,具體代碼如下:

<ul class="js-list js-lazy" data-src=""v-infinite-scroll="getList"infinite-scroll-disabled="loading"infinite-scroll-distance="50">  <li v-for="list in lists" :key="list.id">   <div class="goods-item">    <a :href="'/goods.html?id='+list.id" rel="external nofollow" >     <div class="thumb img-box">      <img class="fadeIn" v-bind:src="list.img">     </div>     <div class="detail">      <div class="title">{{list.name}}</div>      <div class="price">¥{{list.price | currency}}</div>     </div>    </a>   </div>  </li></ul>

上述代碼中,v-infinite-scroll="getList"表示每當(dāng)下拉到一定距離時就觸發(fā)methods里面的getList方法;getList方法的具體代碼如下所示:

getList(){  if (this.allLoad) return  this.loading=true  axios.post(url.hostLists,{    pageNum:this.pageNum,    pageSize:this.pageSize  }).then((response)=>{    let currentList=response.data.lists    if (currentList.length<this.pageSize) this.allLoad=true    if (this.lists) {      this.lists=this.lists.concat(currentList)    } else {      this.lists=currentList    }    this.pageNum +=1    this.loading=false  })}

infinite-scroll-disabled="loading"表示效果觸發(fā)的條件,若loading為false則表示可以觸發(fā),若loading為true則表示不能觸發(fā),因此當(dāng)loading為true時我們可以給底部添加一個加載效果,當(dāng)數(shù)據(jù)獲取完畢,loading變?yōu)閒alse時,我們可以通過v-show="loading"來讓加載效果消失;infinite-scroll-distance="50"表示下拉的觸發(fā)距離,設(shè)置的數(shù)值越大,表示滾動條離底部的觸發(fā)距離越大,越容易觸發(fā)。

3.底部導(dǎo)航欄組件

底部導(dǎo)航欄和輪播組件一樣,由于可以在其他地方進(jìn)行復(fù)用,因此會把該組件放于components文件夾中,這里值得一提的是,底部導(dǎo)航欄組件由于點(diǎn)擊不同的圖標(biāo),它會跳轉(zhuǎn)到不同的頁面,因此會導(dǎo)致導(dǎo)航欄狀態(tài)的重新加載,因此,若想要在不同的頁面讓導(dǎo)航欄呈現(xiàn)不同的狀態(tài),我們需要在跳轉(zhuǎn)的時候傳入對應(yīng)的查詢參數(shù),然后在跳轉(zhuǎn)到不同的頁面時讀取這個參數(shù)來呈現(xiàn)對應(yīng)的不同的狀態(tài),具體的代碼片段如下:

let {index}=qs.parse(window.location.search.substring(1))export default { data(){  return {   navConfig,   curIndex:parseInt(index,10) || 0  } }, methods:{  changeNav(index,list){   location.href=`${list.href}?index=${index}`  } }}

值得一提的是,在這里我們使用到了一個qs庫,這個庫可以方便我們提取出當(dāng)前url后面的查詢參數(shù)。

最后,由于在其他頁面中,filters屬性和底部導(dǎo)航欄組件都可以進(jìn)行復(fù)用,所以這里我們利用mixins屬性,來對filters屬性和底部導(dǎo)航欄組件的注入進(jìn)行打包,打包在一個js文件夾下的mixin.js文件中:

import Footnav from 'components/FootNav.vue'let mixin={  filters:{    currency(num){      num=num+''      let arr=num.split('.')      if (arr.length===1){        return num+'.00'      } else {        if (arr[1].length===1){          return num+'0'        } else return num      }    }  },  components:{    Footnav  }}export default mixin

當(dāng)你的頁面需要使用到該過濾器,或者底部導(dǎo)航欄時,只要對這個模塊進(jìn)行引入,并在mixins屬性中添加它即可:

new Vue({  ...  mixins:[mixin]})

二、目錄分類頁

vue,重構(gòu),有贊商城

目錄分類頁并無新的操作,和首頁的部分操作類似,就是利用axios從接口中獲取數(shù)據(jù)并渲染到頁面中,并對頁面中的一些焦點(diǎn)狀態(tài)進(jìn)行v-show的處理,以及一些類名和焦點(diǎn)的處理,我們可以從目錄分類頁中通過點(diǎn)擊熱銷商品進(jìn)入商品詳情頁,通過點(diǎn)擊熱門品牌進(jìn)入商品搜索列表頁,在進(jìn)行這些頁面的跳轉(zhuǎn)時,把一些關(guān)鍵的數(shù)據(jù)傳入查詢參數(shù)中以便跳轉(zhuǎn)頁面獲取即可。

let { index } = qs.parse(location.search.substr(1));changeNav(list, index) {   //this.curIndex = index;   location.href = `${list.href}?index=${index}`;   //頁面跳轉(zhuǎn)   event.preventDefault();     }

三、商品搜索列表頁

vue,重構(gòu),有贊商城

商品搜索列表頁同樣的基本操作與首頁和目錄分類頁類似,這里唯一不同的是,商品搜索列表頁在用戶下拉一定距離后,會出現(xiàn)一個回到頂部的圖標(biāo),點(diǎn)擊圖標(biāo),用戶就可以直接回到頂部,在這里,我們使用了一個叫作Velocity.js的動畫庫,它是把css中的一些動畫效果進(jìn)行封裝,進(jìn)而可以通過一些api輕松實現(xiàn)一些簡單的動畫效果,例如上面所說的回到頂部,在項目中的代碼片段如下所示:

//引入Velocityimport Velocity from 'velocity-animate/velocity.js'//在methods中加入對應(yīng)方法methods:{  scrollMove(){    if (window.scrollY>=290){      this.isShow=true    } else {      this.isShow=false    }  },  goToTop(){    Velocity(document.body, 'scroll', { duration: 500, easing: "easeOutQuart" });    this.isShow=false //回到頂部圖標(biāo)消失  }}

四、商品詳情頁

vue,重構(gòu),有贊商城

在商品詳情頁中,除了有對數(shù)據(jù)的獲取和頁面的渲染外,這里主要涉及到了三個新的操作:

  • sku算法的應(yīng)用
  • 頁面的載入和消失的動畫效果
  • 頁面展示時的穿透滾動問題的解決  

      vue,重構(gòu),有贊商城

首先是sku算法,由于此次商品詳情頁的選擇并不需要使用到它,因為商品的可選屬性只有一個,但是在實際情況下,由于很多商品的可選屬性不止一個,因此是需要使用到sku算法的。SKU=Stock Keeping Unit(庫存量單位),同一型號的產(chǎn)品,或者說是同一個產(chǎn)品項目(產(chǎn)品條形碼是針對企業(yè)的產(chǎn)品)。

然后如何制作sku頁面載入和消失時的動畫效果呢?這里我們使用到了vue提供的自帶transition的封裝組件,可以通過這個組件來給任何元素和組件添加進(jìn)入或者離開時的過渡。這個組件提供了八個JavaScript鉤子函數(shù)以及六個過渡類名的切換,利用這些鉤子函數(shù)以及類名的切換就可以完成組件的過渡動畫了,這里列舉一個vue文檔上的典型例子給大家參考一下吧:

transition過渡:

<div id="demo"> <button v-on:click="show = !show">  Toggle </button> <transition name="fade">  <p v-if="show">hello</p> </transition></div>
new Vue({ el: '#demo', data: {  show: true }})
.fade-enter-active, .fade-leave-active { transition: opacity .5s;}.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { opacity: 0;}

最后在遮罩層和彈出層出現(xiàn)之后(即sku頁面),對頁面進(jìn)行上下拖動時,背后的內(nèi)容層也會跟著一起拖動,這是典型的滾動穿透問題,在這里我的解決辦法是監(jiān)聽遮罩層和彈出層的出現(xiàn),當(dāng)它們出現(xiàn)之后,我們更改內(nèi)容層的樣式,使其樣式變?yōu)椋?code style="margin: 3px auto 0px; padding: 2px 4px; outline: none; font-style: inherit; font-weight: inherit; background: rgb(249, 242, 244); width: 640px; line-height: 1.5; clear: both; font-size: 12px; border: 1px solid rgb(204, 204, 204); color: rgb(199, 37, 78); border-radius: 0px; font-family: Menlo, Monaco, Consolas, "Courier New", monospace;">position:fixed;width:100%;這樣內(nèi)容層就不會再滾動了,之后我們再通過設(shè)置:

scrollTop = document.scrollingElement.scrollTopdocument.body.style.top = -scrollTop + 'px'

使得內(nèi)容層的滾動高度與遮罩層和彈出層出現(xiàn)前相同,并且,調(diào)整html元素的樣式:height:100%;overflow:hidden;,在關(guān)閉遮罩層和彈出層后,還原這些修改樣式,即可使得滾動穿透的問題得以解決。需要注意的是,還原這些樣式之后,原本內(nèi)容層滾動的高度就會丟失,因此我們要通過之前記錄下來內(nèi)容層滾動的高度,在還原樣式時將滾動高度也一并還原。

document.scrollingElement.scrollTop = scrollTop

這樣滾動穿透的問題就算是徹底解決了,下面是全部的這部分的全部代碼片段:

chooseSku(type) {//顯示購買菜單   this.skuType = type   this.showModal = true  },  changeSku(num) {//增減數(shù)量   if (num < 0 && this.skuNum === 1) return   this.skuNum += num  },  addCart() {//加入購物車   $.ajax($.url.cartAdd, {    id,    skuNum: this.skuNum   }).then((data) => {    if (data.status === 200) {     this.showModal = false     this.showAddMsg = true //添加成功的信息     this.isAddedCart = true //顯示購物車圖標(biāo)     setTimeout(() => this.showAddMsg = false, 1200)    }   })  } },
watch:{  showSku(val,oldVal){    if (val){      scrollTop = document.scrollingElement.scrollTop      document.body.style.top = -scrollTop + 'px'    }    document.body.style.position=val?'fixed':'static'    // document.body.style.margin=val?`0 0 ${window.scrollY}px 0`:'0px'    document.querySelector('html').style.overflow=val?'hidden':'auto'    document.body.style.width=val?'100%':'auto'    document.querySelector('html').style.height=val?'100%':'auto'    if (!val){      document.scrollingElement.scrollTop = scrollTop    }  }}

WeUI上面的層級規(guī)范用于規(guī)范WeUI頁面元素所屬層級、層級順序及組合規(guī)范。

vue,重構(gòu),有贊商城

五、購物車頁面

vue,重構(gòu),有贊商城

購物車頁面里面比較多的邏輯關(guān)系,在此就不一一枚舉了,大概說一下它的重構(gòu)思路:

商品的獲取渲染以及增加是否被選中屬性

獲取后臺數(shù)據(jù)加載處理或動態(tài)響應(yīng)式處理

商品選中店鋪選中全選,影響價格三級聯(lián)動。

編輯狀態(tài),其余不可切換。對數(shù)量操作,加減更改。刪除,單商品刪除,選中(多個)刪除,商品刪除店鋪刪除。

原生事件,滑動刪除頁面,Volecity。

刪除多個商品進(jìn)行過濾處理

fetch層封裝,

同一個場景下思維層封裝

問題呈現(xiàn),左滑刪除樣式繼承。[0].style.left='0px' this.$refs[`goods-${shopIndex}-${goodIndex}`][0].style.left='0px'

ref 是非響應(yīng)式的,不建議在模板中進(jìn)行數(shù)據(jù)綁定,即使用唯一標(biāo)識綁定

v-for 模式使用“就地復(fù)用”策略,簡單理解就是會復(fù)用原有的dom結(jié)構(gòu),盡量減少dom重排來提高性能 ( 解決方案:還原dom樣式 )

key 為每個節(jié)點(diǎn)提供身份標(biāo)識,數(shù)據(jù)改變時會重排,最好綁定唯一標(biāo)識,如果用index標(biāo)識可能得不到想要的效果(綁定唯一識別key)

網(wǎng)頁性能管理詳解

首先獲取數(shù)據(jù),渲染到頁面這些是基本的操作

獲取到數(shù)據(jù)之后,由于有一些屬性數(shù)據(jù)中沒有,并且我們想要它在頁面中是呈響應(yīng)式存在的,因此從接口獲取到數(shù)據(jù)之后不應(yīng)該直接賦值給data里,而是應(yīng)該先給數(shù)據(jù)增添屬性,再把增添后的數(shù)據(jù)賦值到data處,具體代碼如下:

getLists(){  cart.getCartLists().then((response)=>{    let list=response.data.cartList    list.forEach(shop=>{      shop.checked=true      shop.editingStatus=false      shop.editingMsg='編輯'      shop.removeChecked=false      shop.goodsList.forEach(good=>{        good.checked=true        good.removeChecked=false        good.touchDelete=false      })    })    this.cartLists=list  })}

每次選擇了商店下的商品時,都利用數(shù)組的every方法來遍歷數(shù)組看是否全部商品都被選中了,若選中則商店也被選中,同理,若選擇了商店,則遍歷商店下的商品,把商店下的商品全部選中。取消選中亦是同理。

全選與否則利用計算屬性來處理,利用計算屬性的getter來獲取此時購物車的狀態(tài)來判斷是否被全選,利用計算屬性的setter來處理點(diǎn)擊全選時商店及商店下商品的狀態(tài)的改變。

同樣的,利用計算屬性來計算正常狀態(tài)下選中商品的總價,并返回選中商品的列表。同理,利用計算屬性來計算編輯狀態(tài)下的選中的商品的列表,并以數(shù)組的形式返回。

在編輯狀態(tài)下,我利用了計算屬性來對商品的數(shù)量的數(shù)據(jù)進(jìn)行了監(jiān)測,若判斷出數(shù)量中存在非數(shù)字或者負(fù)數(shù)的情況,則會自動把數(shù)量的數(shù)據(jù)變成1。

利用touchstarttouchend兩個事件來實現(xiàn)商品左拉刪除的功能,這兩個事件分別綁定startend的方法,方法的具體代碼如下所示:

start(e,good){  good.startX=e.changedTouches[0].clientX},end(e,good,goodIndex,shopIndex,shop){  let endX=e.changedTouches[0].clientX  let left='0px'  if (good.startX-endX>100){    good.touchDelete=true    left='-60px'    Velocity(this.$refs[`goods-${shopIndex}-${goodIndex}`],{left})    shop.goodsList.forEach((otherGood,index)=>{      if (otherGood.touchDelete && index!==goodIndex) {        otherGood.touchDelete=false        Velocity(this.$refs[`goods-${shopIndex}-${index}`],{left:'0px'})      }    })  } else if (endX-good.startX>100) {    good.touchDelete=false    left='0px'    Velocity(this.$refs[`goods-${shopIndex}-${goodIndex}`],{left})  }}

當(dāng)添加了左拉刪除的功能之后,頁面會出現(xiàn)一個BUG,就是左拉之后,點(diǎn)擊該商品對應(yīng)的商店下的編輯按鈕,刪除的按鈕會繼續(xù)被左拉,呈現(xiàn)一個比其他刪除按鈕長的BUG狀態(tài)。        

vue,重構(gòu),有贊商城

處理辦法:通過給每個商品的一個具有唯一識別性的ref,然后在點(diǎn)擊編輯時,找到已左拉的商品的對應(yīng)的具有唯一識別性的ref,把它的左拉狀態(tài)還原即可,具體代碼如下所示:

shop.editingStatus=!shop.editingStatusif (shop.editingStatus){    shop.goodsList.forEach((good,index)=>{    if (good.touchDelete){      good.touchDelete=false      this.$refs[`goods-${shopIndex}-${index}`][0].style.left='0px'    }  })}

六、個人中心地址管理頁面

最后是個人中心地址管理頁面,在這個頁面中,我們會封裝addressService層和fetch層,addressService層主要是負(fù)責(zé)頁面中前后端交互的方法,如添加地址、刪除地址、編輯地址和獲取地址等,然后fetch層主要是負(fù)責(zé)從RAP接口中獲取數(shù)據(jù)并返回一個promise對象到service層中,具體的封裝方式和使用方式請自行查看源碼。

另外在這個頁面中,我們使用到了vue-router和vuex,接下來我將會簡要介紹它們在個人中心地址管理頁面中的使用方式。

首先是vue-router,他是用于構(gòu)建單頁面應(yīng)用的,是基于路由和組件,路由用于訪問特定的路徑,然后特定的路徑與特定的組件相聯(lián)系相映射,傳統(tǒng)頁面中,是通過超鏈接來實現(xiàn)頁面的跳轉(zhuǎn)和切換的,但在vue-router中,則是路由的切換,即組件的切換。

我們先來看看是如何配置一個routes、創(chuàng)建一個router實例并把它注入到vue實例中去的:

import Vue from 'vue'import Router from 'vue-router'Vue.use(Router)//構(gòu)造配置let routes=[{  path:'/',  components: require('../components/member.vue')},{  path:'/address',  components:require('../components/address.vue'),  children:[{    path:'',    redirect: 'all'  },{    path:'all',    components:require('../components/all.vue')  },{    path:'form',    name:'form',    components:require('../components/form.vue')  }]}]//創(chuàng)建router實例let router=new Router({  routes})export default routerimport Vue from 'vue'import router from './router'import store from './vuex'//根組件注入let view=new Vue({  el:'#app',  router,  store})//router-view標(biāo)簽作為配置路由后組件的容器<div id="app"> <router-view></router-view></div>

通過這樣路由的配置和注入,我們就可以實現(xiàn)單頁面下多組件的切換和嵌套了,如果上述有不懂的地方,請到vue-router的官網(wǎng)處查看文檔和說明。

接著我們來講一下vuex,vuex是對SPA即單頁面應(yīng)用進(jìn)行數(shù)據(jù)的狀態(tài)管理,如果想了解具體vuex是什么還有它的用途,請點(diǎn)擊這篇文章:Vuex新手入門指南

vuex其實也是組件間通信的一種方式,說起組件間的通信,我們不如來一一列舉一下他們的方式有哪些:

1.引用類型數(shù)據(jù)

用法:如果父組件有一個數(shù)據(jù)類型是引用類型的數(shù)據(jù),當(dāng)這個數(shù)據(jù)直接傳遞給子組件以后,在子組件對這個數(shù)據(jù)源進(jìn)行修改的時候,父組件中該數(shù)據(jù)也會同步修改。

2.自定義事件

即子組件內(nèi)部定義了一個自定義事件,可以用父組件在子組件上進(jìn)行監(jiān)聽:

//子組件this.$emit('change',18)//父組件<foo :obj="obj" @change="changeAge"></foo>//父組件methods:{  changeAge(age){    this.obj.age=age  }}

3.全局事件(global bus)

//bus.jsimport Vue from 'vue'const bus=new Vue()export default bus//觸發(fā)組件import bus from 'js/bus.js'bus.$emit('change',18)//訂閱組件import bus from 'js/bus.js'bus.$on('change',(age)=>{  this.obj.age=age})

4.vuex狀態(tài)管理

vuex的使用與vue-router有一點(diǎn)相似,具體代碼如下:

import Vue from 'vue'//使用vuex插件import Vuex from 'vuex'Vue.use(Vuex)import address from 'js/addressService.js'//創(chuàng)建Store實例const store=new Vuex.Store({  state:{    lists:null  },  mutations: {    init(state,lists){      state.lists=lists    }  },  actions: {    getLists({commit}){      address.getList().then(response=>{        commit('init',response.data.lists)      })    }  }})export default store

之后同樣的在跟組件對store實例進(jìn)行注入即可,在上述實例中,state屬性表示的是實例的狀態(tài),類似vue實例里的data,需要高度注意的是,不允許直接修改state里面的值,只允許定義一系列的類似事件的mutations來觸發(fā)進(jìn)行state的管理。而mutations屬性里面存放的是同步事件,因此是對數(shù)據(jù)進(jìn)行同步管理,要進(jìn)行異步操作的話必須使用actions屬性;actions屬性里面存放一些異步的操作,在異步的操作進(jìn)行完成之后再觸發(fā)mutations里面的同步事件來對state里面的數(shù)據(jù)的狀態(tài)進(jìn)行同步的操作。

在組件中,我們一般通過dispatch來觸發(fā)actions里面的異步事件進(jìn)行異步操作,一般使用計算屬性來獲取state中的數(shù)據(jù),之所以使用計算屬性,是因為狀態(tài)管理里的數(shù)據(jù)可能是變化的,因此我們希望它在頁面中是響應(yīng)式的,因此我們選擇使用計算屬性來對數(shù)據(jù)進(jìn)行依賴的綁定。

具體代碼如下:

computed:{  list(){    if(this.$store.state.lists){      return this.$store.state.lists    }    return false  }},created(){  if (!this.list){ //防止在新增地址或修改地址后多次觸發(fā)mutations中的init    this.$store.dispatch('getList')  }}

總之,vuex中狀態(tài)管理的過程可總結(jié)為以下流程:
(1).通過dispatch(actionFnName)分發(fā)來觸發(fā)actions中的異步操作=>
(2).待異步操作結(jié)束之后通過commit(mutationsFnName,data)來觸發(fā)mutations中的同步事件來進(jìn)行同步操作=>
(3).通過同步操作改變state中的數(shù)據(jù)的狀態(tài)=>
(4).狀態(tài)改變后,組件中的計算屬性因為綁定了該數(shù)據(jù)作為依賴,因此數(shù)據(jù)的改變會響應(yīng)式地展示在頁面中,即頁面展示的數(shù)據(jù)也會得到同步的改變

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 申扎县| 娄底市| 皮山县| 白朗县| 织金县| 扎赉特旗| 左贡县| 凤阳县| 屏东县| 和硕县| 南汇区| 团风县| 通榆县| 肥城市| 高密市| 离岛区| 绵竹市| 青州市| 石屏县| 永康市| 吉隆县| 沽源县| 南昌市| 涪陵区| 镇远县| 潞西市| 台江县| 南澳县| 开平市| 长沙市| 西充县| 始兴县| 莱阳市| 太保市| 南岸区| 玛沁县| 边坝县| 雅江县| 绥中县| 闽清县| 海宁市|