最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

Vue框架中有關(guān)goods組件開(kāi)發(fā)

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 19:38:43
文檔

Vue框架中有關(guān)goods組件開(kāi)發(fā)

Vue框架中有關(guān)goods組件開(kāi)發(fā):這篇文章主要介紹了Vue框架之goodvs組件開(kāi)發(fā)詳解,現(xiàn)在分享給大家,也給大家做個(gè)參考。一、 布局 FlexFlex 布局,可以簡(jiǎn)便、完整、響應(yīng)式地實(shí)現(xiàn)各種頁(yè)面布局,F(xiàn)lex 是 Flexible Box 的縮寫(xiě),意為"彈性布局",用來(lái)為盒狀模型提供最大的靈活性。
推薦度:
導(dǎo)讀Vue框架中有關(guān)goods組件開(kāi)發(fā):這篇文章主要介紹了Vue框架之goodvs組件開(kāi)發(fā)詳解,現(xiàn)在分享給大家,也給大家做個(gè)參考。一、 布局 FlexFlex 布局,可以簡(jiǎn)便、完整、響應(yīng)式地實(shí)現(xiàn)各種頁(yè)面布局,F(xiàn)lex 是 Flexible Box 的縮寫(xiě),意為"彈性布局",用來(lái)為盒狀模型提供最大的靈活性。

這篇文章主要介紹了Vue框架之goodvs組件開(kāi)發(fā)詳解,現(xiàn)在分享給大家,也給大家做個(gè)參考。

一、 布局 Flex

Flex 布局,可以簡(jiǎn)便、完整、響應(yīng)式地實(shí)現(xiàn)各種頁(yè)面布局,F(xiàn)lex 是 Flexible Box 的縮寫(xiě),意為"彈性布局",用來(lái)為盒狀模型提供最大的靈活性。任何一個(gè)容器都可以指定為 Flex 布局。

// 指定為 Flex 布局
 display: flex;
flex : 等分 內(nèi)容縮放 展位空間;
flex : 0 0 80px

// 主要屬性
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
flex屬性是flex-grow, flex-shrink 和 flex-basis的簡(jiǎn)寫(xiě),默認(rèn)值為0 1 auto。后兩個(gè)屬性可選。
flex-grow屬性定義項(xiàng)目的放大比例,默認(rèn)為0,即如果存在剩余空間,也不放大
flex-shrink屬性定義項(xiàng)目的縮小比例,默認(rèn)為1,即如果空間不足,該項(xiàng)目將縮小,flex-shrink屬性為0,其他項(xiàng)目都為1,則空間不足時(shí),前者不縮小
flex-basis屬性定義了在分配多余空間之前,項(xiàng)目占據(jù)的主軸空間(main size)。瀏覽器根據(jù)這個(gè)屬性,計(jì)算主軸是否有多余空間。它的默認(rèn)值為auto,即項(xiàng)目的本來(lái)大小,設(shè)為跟width或height屬性一樣的值(比如350px),則項(xiàng)目將占據(jù)固定空間

二、圖標(biāo)組件

子組件 iconMap

<template lang="html">
 <span class="iconMap" :class="iconClassMap[iconType]"></span>
</template>
export default {
 props: { // 圖標(biāo)類(lèi)型
 iconType: Number
 },
 created() { // 數(shù)組類(lèi)名
 this.iconClassMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee']
 }
}

父組件 goods

import iconMap from '../iconMap/iconMap' // 注意路徑寫(xiě)法
// 注冊(cè)組件
 components: {
 iconMap
 }
<ul>
 <li v-for='(item,index) in goods' class="menu-item">
 <span class="text"> // json 數(shù)據(jù) 根據(jù) type 判斷 是否有圖標(biāo)
 <iconMap v-show="item.type>0" :iconType="item.type"></iconMap>
 {{item.name}}
 </span>
 </li>
</ul>

三、better-scroll 應(yīng)用

類(lèi)似iscroll 實(shí)現(xiàn)滾動(dòng)效果

安裝

npm install better-scroll

引入

import BScroll from 'better-scroll'

說(shuō)明

(1)原理:父容器wrapper,它具有固定的高度,當(dāng)它的第一個(gè)子元素content 的高度超出了wrapper的高度,我們就可以滾動(dòng)內(nèi)容區(qū)了,若沒(méi)有超出則不能滾動(dòng)了。

(2)better-scroll 的初始化

better-scroll 的初始化時(shí)機(jī)很重要,因?yàn)樗诔跏蓟臅r(shí)候,會(huì)計(jì)算父元素和子元素的高度和寬度,來(lái)決定是否可以縱向和橫向滾動(dòng)。因此,我們?cè)诔跏蓟臅r(shí)候,必須確保父元素和子元素的內(nèi)容已經(jīng)正確渲染了。如果子元素或者父元素 DOM 結(jié)構(gòu)發(fā)生改變的時(shí)候,必須重新調(diào)用 scroll.refresh() 方法重新計(jì)算來(lái)確保滾動(dòng)效果的正常。所以 better-scroll 不能滾動(dòng)的原因多半是初始化 better-scroll 的時(shí)機(jī)不對(duì),或者是當(dāng) DOM 結(jié)構(gòu)發(fā)送變化的時(shí)候并沒(méi)有重新計(jì)算 better-scroll。

(3)better-scroll 結(jié)合 Vue

Vue.js 提供了我們一個(gè)獲取 DOM 對(duì)象的接口—— vm.$refs。在這里,我們通過(guò)了 this.$refs.wrapper 訪問(wèn)到了這個(gè) DOM 對(duì)象,并且我們?cè)?mounted 這個(gè)鉤子函數(shù)里,this.$nextTick 的回調(diào)函數(shù)中初始化 better-scroll 。因?yàn)檫@個(gè)時(shí)候,wrapper 的 DOM 已經(jīng)渲染了,我們可以正確計(jì)算它以及它內(nèi)層 content 的高度,以確保滾動(dòng)正常。

這里的 this.$nextTick 是一個(gè)異步函數(shù),為了確保 DOM 已經(jīng)渲染,底層用到了 MutationObserver 或者是 setTimeout(fn, 0)。其實(shí)我們?cè)谶@里把 this.$nextTick 替換成 setTimeout(fn, 20) 也是可以的(20 ms 是一個(gè)經(jīng)驗(yàn)值,每一個(gè) Tick 約為 17 ms),對(duì)用戶(hù)體驗(yàn)而言都是無(wú)感知的。

(4)異步數(shù)據(jù)的處理

在我們的實(shí)際工作中,列表的數(shù)據(jù)往往都是異步獲取的,因此我們初始化 better-scroll 的時(shí)機(jī)需要在數(shù)據(jù)獲取后,代碼如下:

<template>
 <p class="wrapper" ref="wrapper">
 <ul class="content">
 <li v-for="item in data">{{item}}</li>
 </ul>
 </p>
</template>
<script>
 import BScroll from 'better-scroll'
 export default {
 data() {
 return {
 data: []
 }
 },
 created() {
 requestData().then((res) => {
 this.data = res.data
 this.$nextTick(() => {
 this.scroll = new Bscroll(this.$refs.wrapper, {})
 })
 })
 }
 }
</script>

這里的 requestData 是偽代碼,作用就是發(fā)起一個(gè) http 請(qǐng)求從服務(wù)端獲取數(shù)據(jù),并且這個(gè)函數(shù)返回的是一個(gè) promise(實(shí)際項(xiàng)目中我們可能會(huì)用 axios 或者 vue-resource )。我們獲取到數(shù)據(jù)的后,需要通過(guò)異步的方式再去初始化 better-scroll,因?yàn)?Vue 是數(shù)據(jù)驅(qū)動(dòng)的, Vue 數(shù)據(jù)發(fā)生變化(this.data = res.data)到頁(yè)面重新渲染是一個(gè)異步的過(guò)程,我們的初始化時(shí)機(jī)是要在 DOM 重新渲染后,所以這里用到了 this.$nextTick,當(dāng)然替換成 setTimeout(fn, 20) 也是可以的。

注意:這里為什么是在 created 這個(gè)鉤子函數(shù)里請(qǐng)求數(shù)據(jù)而不是放到 mounted 的鉤子函數(shù)里?因?yàn)?requestData 是發(fā)送一個(gè)網(wǎng)絡(luò)請(qǐng)求,這是一個(gè)異步過(guò)程,當(dāng)拿到響應(yīng)數(shù)據(jù)的時(shí)候,Vue 的 DOM 早就已經(jīng)渲染好了,但是數(shù)據(jù)改變 —> DOM 重新渲染仍然是一個(gè)異步過(guò)程,所以即使在我們拿到數(shù)據(jù)后,也要異步初始化 better-scroll。

使用

初始化需要滾動(dòng)的dom結(jié)構(gòu)

借助ref屬性用來(lái)綁定某個(gè)dom元素,或者來(lái)說(shuō)來(lái)綁定某個(gè)組件,然后在函數(shù)內(nèi)用this.$refs.menuwrapper獲取到dom。

說(shuō)明:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素; 如果用在子組件上,引用就指向組件實(shí)例:

<p class="menu-wrapper" ref='menuWrapper'> </p>
<p class="foods-wrapper" ref="foodsWrapper"></p>

在ajax內(nèi)執(zhí)行_initScroll() 函數(shù)

在此之前我們要做一些準(zhǔn)備和 注意事項(xiàng)

(1) dom結(jié)構(gòu)完全加載完再調(diào)用_initScroll()方法才會(huì)生效

(2) 因?yàn)橐O(jiān)聽(tīng)內(nèi)容區(qū)域的高度,所以初始化應(yīng)在created過(guò)程中去監(jiān)聽(tīng)dom結(jié)構(gòu)是否完全加載,這里是在$nextTick對(duì)象中進(jìn)行觸發(fā)檢測(cè)

ES6語(yǔ)法格式: this.$nextTick(() => {})

created (){ // 在實(shí)例創(chuàng)建完成后被立即調(diào)用 $el 屬性目前不可見(jiàn)。
 axios.get('static/data.json').then((result) => {
 this.goods=result.data.goods
 //dom結(jié)構(gòu)加載結(jié)束
 this.$nextTick(() => {
 this._initScroll(); // 初始化scroll
 })
 })
}

(3) 在methods方法里面定義一個(gè)_initScroll的函數(shù),主要用來(lái)對(duì)左右兩側(cè)dom結(jié)構(gòu)進(jìn)行初始化

methods:{
 // 用來(lái)對(duì)左右兩側(cè)dom結(jié)構(gòu)進(jìn)行初始化
 _initScroll (){
 // 實(shí)例化 better-scroll 插件,傳入要滾動(dòng)的DOM 對(duì)象 
 this.meunScroll=new BScroll(this.$refs.menuWrapper,{
 click:true 
 });
 this.foodScroll=new BScroll(this.$refs.foodsWrapper,{
 click:true
 });
 
 }
 }

說(shuō)明:vue中更改數(shù)據(jù),DOM會(huì)跟著做映射,但vue更新DOM是異步的,用 $nextTick ()來(lái)確保Dom變化后能調(diào)用到_initScroll()方法。調(diào)用_initScroll()方法能計(jì)算內(nèi)層ul的高度,當(dāng)內(nèi)層ul的高度大于外層wrapper的高度時(shí),可以實(shí)現(xiàn)滾動(dòng)。

此時(shí)倆側(cè)可以分別滾動(dòng)了!

(4) 實(shí)現(xiàn)左右聯(lián)動(dòng)

原理:我們計(jì)算出右側(cè)實(shí)時(shí)變化的y值,落到哪一個(gè)區(qū)間,我們就顯示那一個(gè)區(qū)間。首先我們要計(jì)算整體區(qū)間的一個(gè)高度,然后分別計(jì)算第一個(gè)區(qū)間的高度,第二個(gè)區(qū)間的高度,以此類(lèi)推。然后將區(qū)間數(shù)存入一個(gè)定義好的數(shù)組。當(dāng)我們?cè)跐L動(dòng)的時(shí)候?qū)崟r(shí)拿到y(tǒng)軸的高度,然后對(duì)比在哪一個(gè)區(qū)間,這樣我們就會(huì)得到一個(gè)區(qū)間的索引值去對(duì)應(yīng)左側(cè)的菜品類(lèi)別,最后我們用一個(gè)vue的class去綁定高亮文本。

1.定義一個(gè)方法在 _initScroll 下面,作為計(jì)算高度的方法叫做_calculateHeight () ,再定義一個(gè)listHeight:[]數(shù)組,存放獲取到的每一塊foods類(lèi)的高度。然后通過(guò)給每個(gè)li 定義類(lèi)名來(lái)供js 選擇 從而計(jì)算出高度存放到listHeight數(shù)組里。

// 通過(guò) 方法 計(jì)算foods內(nèi)部每一個(gè)塊的高度,組成一個(gè)數(shù)組listHeight。
 // 每個(gè)li 定義一個(gè)類(lèi)food-list-hook 通過(guò)獲取該類(lèi) 來(lái)計(jì)算 每一塊的高度 存到數(shù)組listHeight里
 _calculateHeight (){
 // 獲取 li 通過(guò)food-list-hook
 let foodList=this.$refs.foodsWrapper.querySelectorAll(".food-list-hook");
 let height=0;// 初始化高度
 this.listHeight.push(height) // 把第一個(gè)高度存入數(shù)組
 //通過(guò)循環(huán)foodList下的dom結(jié)構(gòu),將每一個(gè)li的高度依次送入數(shù)組
 for(let i = 0 ,l = foodList.length ; i < l ; i++){
 let item=foodList[i]; //每一個(gè)item都是剛才獲取的food的每一個(gè)dom
 height += item.clientHeight; //獲取每一個(gè)foods內(nèi)部塊的高度
 this.listHeight.push(height) // 將獲取的值存放到數(shù)組里
 }
 
 }

2.我們獲取到區(qū)間高度數(shù)組后,我們要實(shí)時(shí)獲取到右側(cè)的y值,和左側(cè)的索引值做一個(gè)對(duì)比,定義一個(gè)scrollY變量用來(lái)存放實(shí)時(shí)獲取的y值。bs插件為我們提供了一個(gè)實(shí)時(shí)獲取y值的方法,我們?cè)诔跏蓟痶his.foodScroll的時(shí)候加一個(gè)·屬性probeType: 3,其作用就是實(shí)時(shí)獲取y值,相當(dāng)于探針的作用。

goods: [],// goods json 數(shù)組
listHeight: [],// 存放 foods 內(nèi)部的每一塊的高度
scrollY:0
this.foodScroll=new BScroll(this.$refs.foodsWrapper,{
 click:true,
 //探針作用,實(shí)時(shí)監(jiān)測(cè)滾動(dòng)位置
 probeType: 3
 });

3.我們?cè)偬砑右粋€(gè)方法this.foodScroll.on('scroll',(pos) => {}),作用是實(shí)時(shí)滾動(dòng)的時(shí)候把獲取到的位置給暴露出來(lái)。代碼如下。

//結(jié)合BScroll的接口使用,監(jiān)聽(tīng)scroll事件(實(shí)時(shí)派發(fā)的),并獲取鼠標(biāo)坐標(biāo),當(dāng)滾動(dòng)時(shí)能實(shí)時(shí)暴露出scroll
 this.foodScroll.on("scroll",(pos) =>{ // 回調(diào)函數(shù)
 //scrollY接收變量 
 this.scrollY=Math.abs(Math.round(pos.y)) //滾動(dòng)坐標(biāo)會(huì)出現(xiàn)負(fù)的,并且是小數(shù),所以需要處理一下,實(shí)時(shí)取得scrollY
 // console.log(pos.y)
 })

4.定義一個(gè)計(jì)算屬性computed,獲取到food滾動(dòng)區(qū)域?qū)?yīng)的menu區(qū)域的子塊的索引i值,從而定位到左側(cè)邊欄的位置。

computed:{
 currentIndex (){ //計(jì)算到達(dá)哪個(gè)區(qū)域的區(qū)間的時(shí)候的對(duì)應(yīng)的索引值
 // 利用 listHeight 存放 每一塊 對(duì)應(yīng)的高度
 for (let i=0,l=this.listHeight.length; i<l ; i++){
 let menuHeight_fir = this.listHeight[i] // 當(dāng)前menu 子塊區(qū)域的 高度
 let menuHeight_sec = this.listHeight[i + 1] // 下一個(gè)menu 子塊區(qū)域的 高度
 // 當(dāng)滑到底部時(shí),menuHeight_sec 為 underfined,
 // 需要確定滑到倆個(gè)高度區(qū)間 
 if( !menuHeight_sec || (this.scrollY > menuHeight_fir && this.scrollY < menuHeight_sec) ){
 return i;
 }
 }
 },
 
 }

獲取到i后,,然后通過(guò)設(shè)置一個(gè)class來(lái)做樣式切換變化 :class="{'current':currentIndex === index}" ,當(dāng)currentIndex和menu-item對(duì)應(yīng)的index相等時(shí),設(shè)置current的樣式。這樣就可以實(shí)現(xiàn)左右聯(lián)動(dòng)了。

<li v-for='(item,index) in goods' class="menu-item" :class="index === currentIndex?'menu-item-selected':'menu-item'">
...

在樣式里提前設(shè)好 選中和正常的樣式

5.最后實(shí)現(xiàn)左側(cè)點(diǎn)擊的功能。在左側(cè)的li下綁定一個(gè)selectMenu的點(diǎn)擊事件,并傳入索引值,這樣我們就可以知道點(diǎn)擊的是哪一個(gè)li

<li v-for='(item,index) in goods' class="menu-item" @click="selectMenu(index,$event)" :class="index === currentIndex?'menu-item-selected':'menu-item'">
...
selectMenu (index, event){ // 點(diǎn)擊左側(cè) ,右側(cè)響應(yīng)
 this.foodScroll.scrollTo(0, -this.listHeight[index], 300)
 }
scrollTo(x, y, time, easing)
//滾動(dòng)到某個(gè)位置,x,y 代表坐標(biāo),time 表示動(dòng)畫(huà)時(shí)間,easing 表示緩動(dòng)函數(shù)
scroll.scrollTo(0, 500)

參考: vue使用 better-scroll的參數(shù)和方法

6.關(guān)于在selectMenu中點(diǎn)擊事件

在selectMenu中點(diǎn)擊,在pc界面會(huì)出現(xiàn)兩次事件,在移動(dòng)端就只出現(xiàn)一次事件的問(wèn)題

原因 : better-scroll 會(huì)監(jiān)聽(tīng)事件(例如touchmove,click之類(lèi)),并且阻止默認(rèn)事件(prevent stop),并且他只會(huì)監(jiān)聽(tīng)移動(dòng)端的,pc端的沒(méi)有監(jiān)聽(tīng)

在pc頁(yè)面上 better-scroll 也派發(fā)了一次click事件,原生也派發(fā)了一次click事件

// better-scroll 的事件,有_constructed: true
MouseEvent {isTrusted: false, _constructed: true, screenX: 0, screenY: 0, clientX: 0…}
//pc的事件
MouseEvent {isTrusted: true, screenX: -1867, screenY: 520, clientX: 53, clientY: 400…}

解決 : 針對(duì)better-scroll 的事件,有_constructed: true,所以做處理,return掉非better-scroll 的事件

selectMenu(index, event){
 if (!event._constructed) { //去掉自帶的click事件點(diǎn)擊,即pc端直接返回
 return;
 }
 let foodList=this.$refs.foodsWrapper.querySelectorAll(".food-list-hook"); // 獲得監(jiān)聽(tīng)元素
 let el = foodList[index]; // 獲得 當(dāng)前 監(jiān)聽(tīng)元素的高度 
 this.foodScroll.scrollToElement(el, 300); //類(lèi)似jump to的功能,通過(guò)這個(gè)方法,跳轉(zhuǎn)到指定的dom
 }

goods 組件到此差不多了!

上面是我整理給大家的,希望今后會(huì)對(duì)大家有幫助。

相關(guān)文章:

使用原生JavaScript實(shí)現(xiàn)放大鏡效果

在nodejs中通過(guò)redis作為緩存實(shí)現(xiàn)的封裝緩存類(lèi)

Vue Socket.io源碼詳細(xì)分析

vue中調(diào)用methods的方法

Vue組件通信(詳細(xì)教程)

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

Vue框架中有關(guān)goods組件開(kāi)發(fā)

Vue框架中有關(guān)goods組件開(kāi)發(fā):這篇文章主要介紹了Vue框架之goodvs組件開(kāi)發(fā)詳解,現(xiàn)在分享給大家,也給大家做個(gè)參考。一、 布局 FlexFlex 布局,可以簡(jiǎn)便、完整、響應(yīng)式地實(shí)現(xiàn)各種頁(yè)面布局,F(xiàn)lex 是 Flexible Box 的縮寫(xiě),意為"彈性布局",用來(lái)為盒狀模型提供最大的靈活性。
推薦度:
標(biāo)簽: VUE 開(kāi)發(fā) 組件
  • 熱門(mén)焦點(diǎn)

最新推薦

猜你喜歡

熱門(mén)推薦

專(zhuān)題
Top