vue 仿二手交易app_Vue項目開發-仿蘑菇街電商APP

最近快畢業了嗚嗚嗚,準備找工作,但是缺乏項目經驗,于是就在B站找相關的課程,學完之后便根據老師穩定的教導,以及自己穩定的心態,做了一個類似于蘑菇街的電商APP。(后端數據接口由老師提供,老師叫coderwhy,前端講得真的很不錯)。

蘑菇街作為中國最大女性購物社區,其APP的設計水平也毋庸置疑的

(1)準備工作

在閱讀大神的博客時有人問里面使用的美工素材怎么得到的,其實很簡單,下載一個APP,把APK格式修改成rar后解壓,你會在目錄下看到所有的素材。

(2)開始工作 項目目錄:

由于是自己的練手之作,所以,莫得啟動頁面

下面是首頁:

詳情頁

分類頁

個人頁面:

一. FeatureView獨立組件封裝FeatureViewdiv>a>img

二. TabControl獨立組件的封裝props -> titles

div>根據titles v-for遍歷 div -> span{{title}}

css相關

選中哪一個tab, 哪一個tab的文字顏色變色, 下面border-bottomcurrentIndex

:key="(item,index)" class="tab-control-item"

:class="{active: index===currentIndex}"

@click="itemClick(index)">

{{item}}

?

export default {

name: 'TabControl',

props:{

titles:{

type:Array,

default(){

return [];

}

}

},

data() {

return {

currentIndex:0,

}

},

methods:{

itemClick(index){

this.currentIndex = index;

this.$emit('tabClick', index);

}

}

}

?

.tab-control{

display: flex;

text-align: center;

font-size: 15px;

height: 40px;

line-height: 40px;

background-color: #fff;

}

.tab-control-item{

flex: 1;

?

}

.tab-control-item span{

padding: 5px;

}

.active{

color: #ff5777;

}

.active span{

border-bottom: 3px solid var(--color-tint);

}

?

三. 首頁商品數據的請求

3.1. 設計數據結構, 用于保存數據

goods: {

pop: page/list

new: page/list

sell: page/list

}

3.2. 發送數據請求在home.js中封裝getHomeGoods(type, page)

在Home.vue中, 又在methods中getHomeGoods(type)

調用getHomeGoods('pop')/getHomeGoods('new')/getHomeGoods('sell')page: 動態的獲取對應的page

獲取到數據: resthis.goods[type].list.push(...res.data.list)

this.goods[type].page += 1

goods: {

pop: page1:/list[30]

new: page1/list[30]

sell: page1/list[30]

}

四. 對商品數據進行展示

4.1. 封裝GoodsList.vue組件props: goods -> list[30]

v-for goods -> GoodsListItem[30]

GoodListItem(組件) -> GoodsItem(數據)

4.2. 封裝GoodsListItem.vue組件props: goodsItem

goodsItem 取出數據, 并且使用正確的div/span/img基本標簽進行展示

五. 對滾動進行重構: Better-Scroll

5.1. 在index.html中使用Better-Scrollconst bscroll = new BScroll(el, { })

注意: wrapper -> content -> 很多內容

1.監聽滾動probeType: 0/1/2(手指滾動)/3(只要是滾動)

bscroll .on('scroll', (position) => {})

2.上拉加載pullUpLoad: true

bscroll .on('pullingUp', () => {})

3.click: falsebutton可以監聽點擊

div不可以

5.2. 在Vue項目中使用Better-Scroll在Profile.vue中簡單的演示

對Better-Scroll進行封裝: Scroll.vue

Home.vue和Scroll.vue之間進行通信Home.vue將probeType設置為3

Scroll.vue需要通過$emit, 實時將事件發送到Home.vue

六. 回到頂部BackTop

6.1. 對BackTop.vue組件的封裝

6.2. 如何監聽組件的點擊直接監聽back-top的點擊, 但是可以直接監聽?不可以, 必須添加修飾.native

回到頂部scroll對象, scroll.scrollTo(x, y, time)

this.$refs.scroll.scrollTo(0, 0, 500)

6.3. BackTop組件的顯示和隱藏isShowBackTop: false

監聽滾動, 拿到滾動的位置:-position.y > 1000 -> isShowBackTop: true

isShowBackTop = -position.y > 1000

七. 解決首頁中可滾動區域的問題Better-Scroll在決定有多少區域可以滾動時, 是根據scrollerHeight屬性決定scrollerHeight屬性是根據放Better-Scroll的content中的子組件的高度

但是我們的首頁中, 剛開始在計算scrollerHeight屬性時, 是沒有將圖片計算在內的

所以, 計算出來的告訴是錯誤的(1300+)

后來圖片加載進來之后有了新的高度, 但是scrollerHeight屬性并沒有進行更新.

所以滾動出現了問題

如何解決這個問題了?監聽每一張圖片是否加載完成, 只要有一張圖片加載完成了, 執行一次refresh()

如何監聽圖片加載完成了?原生的js監聽圖片: img.onload = function() {}

Vue中監聽: @load='方法'

調用scroll的refresh()

如何將GoodsListItem.vue中的事件傳入到Home.vue中因為涉及到非父子組件的通信, 所以這里我們選擇了事件總線bus ->總線

Vue.prototype.$bus = new Vue()

this.bus.emit('事件名稱', 參數)

this.bus.on('事件名稱', 回調函數(參數))

問題一: refresh找不到的問題第一: 在Scroll.vue中, 調用this.scroll的方法之前, 判斷this.scroll對象是否有值

第二: 在mounted生命周期函數中使用 this.$refs.scroll而不是created中

問題二: 對于refresh非常頻繁的問題, 進行防抖操作防抖debounce/節流throttle(課下研究一下)

防抖函數起作用的過程:如果我們直接執行refresh, 那么refresh函數會被執行30次.

可以將refresh函數傳入到debounce函數中, 生成一個新的函數.

之后在調用非常頻繁的時候, 就使用新生成的函數.

而新生成的函數, 并不會非常頻繁的調用, 如果下一次執行來的非常快, 那么會將上一次取消掉

debounce(func, delay) {

let timer = null

return function (...args) {

if (timer) clearTimeout(timer)

timer = setTimeout(() => {

func.apply(this, args)

}, delay)

}

},

八. 上拉加載更多的功能

loadMore(){

this.getHomeGoods(this.currentType);

this.$refs.scroll.refresh();

}

九. tabControl的吸頂效果

9.1. 獲取到tabControl的offsetTop必須知道滾動到多少時, 開始有吸頂效果, 這個時候就需要獲取tabControl的offsetTop

但是, 如果直接在mounted中獲取tabControl的offsetTop, 那么值是不正確.

如何獲取正確的值了?監聽HomeSwiper中img的加載完成.

加載完成后, 發出事件, 在Home.vue中, 獲取正確的值.

補充:為了不讓HomeSwiper多次發出事件,

可以使用isLoad的變量進行狀態的記錄.

注意: 這里不進行多次調用和debounce的區別

9.2. 監聽滾動, 動態的改變tabControl的樣式問題:動態的改變tabControl的樣式時, 會出現兩個問題:問題一: 下面的商品內容, 會突然上移

問題二: tabControl雖然設置了fixed, 但是也隨著Better-Scroll一起滾出去了.

其他方案來解決停留問題.在最上面, 多復制了一份PlaceHolderTabControl組件對象, 利用它來實現停留效果.

當用戶滾動到一定位置時, PlaceHolderTabControl顯示出來.

當用戶滾動沒有達到一定位置時, PlaceHolderTabControl隱藏起來.

十. 讓Home保持原來的狀態

10.1. 讓Home不要隨意銷毀掉keep-alive

10.2. 讓Home中的內容保持原來的位置離開時, 保存一個位置信息saveY.

進來時, 將位置設置為原來保存的位置saveY信息即可.注意: 最好回來時, 進行一次refresh()

非父子組件通信:

我們在用Vue進行前端開發的時候,往往會遇到有很多個組件內,他們都有類似的data,類似的方法。這些大量重復的代碼,如果正常編寫出來,代碼既不美觀也不優雅,而且看起來也相當復雜。所以vue官方提供了一個極其好用的方式來解決這個問題

那就是mixin

先來看看官方的介紹混入 (mixin) 提供了一種非常靈活的方式,來分發 Vue 組件中的可復用功能。一個混入對象可以包含任意組件選項。當組件使用混入對象時,所有混入對象的選項將被“混合”進入該組件本身的選項。

在Java開發中 如果我們遇到兩個類有大量相似代碼的時候,我們通常會定義一個父類,來講這些重復代碼寫在一起,然后再讓這兩個類來繼承父類的代碼和方法。

class Animal{

run(){}

}

class Person extends Animal{

//run(){}

}

class Dog extends Animal{

//run(){}

}

而在Vue中,每個組件export出來的是對象,所以不能像類那樣繼承,于是Vue提供了類似于類的繼承的方法 mixin

使用方法,在這里貼上自己項目的部分代碼。

定義一個mixin.js 文件

import {debounce} from './utils';

?

export const itemListenerMixin = {

data(){

return {

itemImgListener: null,

}

},

methods:{

?

},

mounted(){

let newRefresh = debounce(this.$refs.scroll.refresh, 100)

?

this.itemImgListener = () => {

newRefresh()

}

?

this.$bus.$on('itemImgLoad', this.itemImgListener)

console.log("我是混入的東西")

}

}

mixin 里就跟一個正常的Vue的組件沒有任何的區別,可以定義data,methods,生命周期函數等等。跟Java里面的父類和子類完全一樣。只是調用的方法不一樣而已。

兩個調用mixin.js的組件

Detail.vue

import {itemListenerMixin} from "common/mixin";

?

mixins: [itemListenerMixin],

//其余代碼均省略

Home.vue

import {itemListenerMixin} from "common/mixin";

?

mixins: [itemListenerMixin],

//其余代碼均省略

只需要這樣一小段代碼,就可以調用到mixin.js 內定義的組件了。

而且在兩個組件內,作用完全一樣

當我們在組件上應用Mixin的時候,有可能組件與Mixin中都定義了相同的生命周期鉤子,這時候鉤子的執行順序的問題凸顯了出來。默認Mixin上會首先被注冊,組件上的接著注冊,這樣我們就可以在組件中按需要重寫Mixin中的語句。組件擁有最終發言權。當發生沖突并且這個組件就不得不“決定”哪個勝出的時候,這一點就顯得特別重要,否則,所有的東西都被放在一個數組當中執行,Mixin將要被先推入數組,其次才是組件。

const myMixin = {

mounted() {

console.log('mixin!')

}

}

?

new Vue({

el: '#app',

mixins: [myMixin],

mounted() {

console.log('Vue instance!')

}

});

?

//Output in console

> mixin!

> Vue instance!

//mixin

const myMixin = {

methods: {

sayHello: function() {

console.log('mixin!')

}

},

mounted() {

this.sayHello()

}

}

?

//vue instance or component

new Vue({

el: '#app',

mixins: [myMixin],

methods: {

sayHello: function() {

console.log('Vue instance!')

}

},

mounted() {

this.sayHello()

}

})

?

// Output in console

> Vue instance!

> Vue instance!

我們可以看到,當他們之間沒有發生同名沖突的時候,兩個都正常打印了。而當他們發生沖突之后。你可以看到這里打印了兩個Vue instance。這是因為第一個函數被調用之后,并沒有被銷毀,而是被重寫了。然后被調用了兩次

當組件和混入對象含有同名選項時,這些選項將以恰當的方式混合。

選項合并數據對象(data)在內部會進行遞歸合并,在和組件的數據發生沖突時以組件數據優先。

同名鉤子函數(created,mounted...)將混合為一個數組,因此都將被調用。另外,混入對象的鉤子將在組件自身鉤子之前調用。

值為對象的選項(methods, components 和 directives)將被混合為同一個對象。兩個對象鍵名沖突時,取組件對象的鍵值對。

需要注意的是謹慎使用全局混入對象,因為會影響到每個單獨創建的 Vue 實例 (包括第三方模板)。大多數情況下,只應當應用于自定義選項。也可以將其用作 Plugins 以避免產生重復應用

所以Vue對mixin 設定了 自定義選項合并策略自定義選項將使用默認策略,即簡單地覆蓋已有值。如果想讓自定義選項以自定義邏輯合并,可以向 Vue.config.optionMergeStrategies 添加一個函數:

Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {

// 返回合并后的值

}

對于多數值為對象的選項,可以使用與 methods 相同的合并策略:

var strategies = Vue.config.optionMergeStrategies

strategies.myOption = strategies.methods

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/533496.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/533496.shtml
英文地址,請注明出處:http://en.pswp.cn/news/533496.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HDL的綜合和c語言的編譯區別,C語言與verilog?的區別及相互轉化

1,面對C語言比verilogHDL更加成熟,而且更加可靠,因為verilog的編譯,查錯工具大都是商業軟件,因此沒有像C語言一樣得到廣泛的應用,各種缺陷也較C來說 較多。基于這樣的原因,在設計算法的硬件電路塊時&#x…

linux幾秒鐘同步一次,Linux時間同步配置方法

由于是在做mongoDB的實驗中再一次的遇到了mongos路由節點同步時由于ntp時間的問題導致同步非常的慢。故寫了個時間同步的語句>while :; do rdate -s 192.168.109.129; sleep 2s; done > /dev/null 2>&1 &rdate: couldnt connect to host 192.168.109.129: Con…

c語言 socket 報文解析,C語言實現Socket簡單通信

環境是linux,不過應該沒什么影響,因為只用到了socket的基本用法,沒有涉及pthread等。分為服務器端和客戶端,服務器端監聽端口發來的請求,收到后向客戶端發送一個Hello World,客戶機負責發送消息并打印收到的Hello Worl…

字典排序什么意思_字典排序問題

2018-01-03望京排序,立即想到用Python的內置函數sorted()Python 2.x 中sorted(...)sorted(iterable, cmpNone, keyNone, reverseFalse) --> new sorted listPython 3.x 中sorted(iterable, keyNone, reverseFalse)Return a new list containing all items from t…

bind() c語言,c/c++ 標準庫 bind 函數詳解

bind函數定義在頭文件 functional 中。可以將 bind 函數看作一個通用的函數適配器,它接受一個可調用對象,生成一個新的可調用對象來“適應”原對象的參數列表。bind函數:接收一個函數名作為參數,生成一個新的函數。auto newCallab…

單片機c語言編程要點,第1章單片機的C語言編程_2015要點.ppt

第1章單片機的C語言編程_2015要點1-* 第 1 章 結束!謝 謝! * * 1-* 三、對存儲器和外接I/O口的絕對地址訪問 例: #include #define com XBYTE[0x07ff] 那么后面程序com變量出現的地方,就是對地址為07ffH的外部RAM或I/O口進行訪問。…

c 語言 timestamp,c中的時間戳,精度為毫秒

我對C編程比較陌生,而且我正在開展一個需要非常準確的項目;因此我嘗試寫一些東西來創建一個毫秒精度的時間戳.它似乎有效但我的問題是這種方式是否正確,還是有更簡單的方法?這是我的代碼:#include#includevoid wait(int milliseconds){clock_t start cl…

antd 左右滑動_如何使用reactjs創建可滑動的側邊欄

我正在嘗試使用reactjs創建可滑動的側邊欄。但由于某些原因,這不會發生。我寫的代碼如下所示;如何使用reactjs創建可滑動的側邊欄Sidebar.jsimport React, { Component } from react;class Sidebar extends Component {render() {return (Start BootstrapDashboardS…

不思議迷宮c語言基礎,不思議迷宮神龍收藏品一覽

不思議迷宮神龍收藏品一覽是9K9K小編柚子人為大家帶來的,七龍珠召喚神龍作為游戲最為迷人的彩蛋之一,召喚神龍拿鉆石作為眾多玩家的首選目標,但神龍的收藏品你知道多少呢,下面不妨詳細了解一下吧。神龍收藏品一覽:無限…

shell181網格劃分_復合材料SHELL181單元完全攻略

前言ANSYS程序中的SHELL181單元是用于復合材料層合板結構分析比較好的單元之一。原文在ANSYS程序的在線幫助中,這篇文章是它的譯文,是我們從專業角度對原文的翻譯。目的在于幫助那些英語水平不高,而且從事復合材料結構計算分析的技術人員能夠…

c語言如何判斷是否是子序列,leetcode392(判斷子序列)--C語言實現

求&#xff1a;給定字符串 s 和 t &#xff0c;判斷 s 是否為 t 的子序列。你可以認為 s 和 t 中僅包含英文小寫字母。字符串 t 可能會很長(長度 ~ 500,000)&#xff0c;而 s 是個短字符串(長度 <100)。字符串的一個子序列是原始字符串刪除一些(也可以不刪除)字符而不改變剩…

leetcode數組匯總_LeetCode刷題:前言

LeetCode刷題&#xff1a;前言前言作為一個對編程超級不通的小白&#xff0c;在2020年11月開始打算正式的刷LeetCode。&#xff08;PS&#xff1a;前面有刷過&#xff0c;但是都是隨機&#xff0c;看心情亂刷的&#xff0c;刷完后也沒有什么感覺&#xff0c;該不會的還是不會&a…

淮海工學院大一c語言期中試題,《C語言程序設計》期中考試試卷

《《C語言程序設計》期中考試試卷》由會員分享&#xff0c;可在線閱讀&#xff0c;更多相關《《C語言程序設計》期中考試試卷(5頁珍藏版)》請在人人文庫網上搜索。1、淮 海 工 學 院10 11 學年 第 2 學期 C語言程序設計 期中考試試卷題號一二三四五總分得分單項選擇題答題表123…

通信基站c語言,[轉]2015年數學建模C題–基于無線通信基站的室內三維定位問題...

之前做的一題跟大家分享一下&#xff0c;實際該題數據出的有點問題(個人看法不喜勿噴)。這題主要是做基站定位的&#xff0c;方法主要是用的基于幾何的方法。該題總共四題&#xff0c;由于只有測試case可以驗證性能&#xff0c;非測試case的結果我就不放了在本題中&#xff0c;…

c語言fopen_s的用法,fopen和fopen_s用法的比較

參考&#xff1a;在定義FILE * fp 之后&#xff0c;fopen的用法是: fp fopen(filename,"w")。而對于fopen_s來說&#xff0c;還得定義另外一個變量errno_t err&#xff0c;然后err fopen_s(&fp,filename,"w")。返回值的話&#xff0c;對于fopen來說&…

php redis 投票_高可用Redis服務架構分析與搭建

HorstXuhttps://www.cnblogs.com/xuning/p/8464625.html基于內存的Redis應該是目前各種web開發業務中最為常用的key-value數據庫了&#xff0c;我們經常在業務中用其存儲用戶登陸態&#xff08;Session存儲&#xff09;&#xff0c;加速一些熱數據的查詢&#xff08;相比較mysq…

android studio 啟動畫面,Android Studio 利用Splash制作APP啟動界面的方法

public class SplashActivity extends Activity {// private final int SPLASH_DISPLAY_LENGHT 2000; // 兩秒后進入系統Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getWindow().addFlags(WindowManager.LayoutParams.…

android驅動測試,Android: 通過 cucumber 驅動 monkey 做穩定性測試

主要內容穩定性測試是什么Monkey 介紹自動化 Monkey穩定性測試是什么通過隨機點擊屏幕一段時間&#xff0c;看看 app 會不會奔潰&#xff0c;能不能維持正常運行。Monkey 介紹Monkey 是一個命令行工具&#xff0c;它可以運行在我們的模擬器或者設備當中。它可以發送一些偽隨機(…

gradle 查看依賴類庫版本_Android studio中查看依賴的第三方庫的歷史版本和最新版本...

在日常開發過程中&#xff0c;我們通過會依賴很多的第三方庫項目。類似這樣&#xff1a;dependencies {compile com.android.support:support-v4:24.2.1compile com.google.code.gson:gson:2.4compile com.lzy.net:okhttputils:1.7.0compile com.github.ybq:Android-SpinKit:1.…

set和map去重調用什么方法_【ES6】Set、Map

SetSet 是 ES6 提供給我們的構造函數&#xff0c;能夠造出一種新的存儲數據的結構特點&#xff1a;只有屬性值沒有屬性名&#xff0c;成員值唯一用途&#xff1a;可以轉成數組&#xff0c;其本身具備去重(自動去重)&#xff0c;交集&#xff0c;并集&#xff0c;差集的作用等參…