...
|
...
|
@@ -30,8 +30,8 @@ |
|
|
</div>
|
|
|
<div class="info-name"><div>{{productDetail.product_name}}</div></div>
|
|
|
</div>
|
|
|
<a class="banner" v-if="resource.src" @click.prevent="gotoNewPage">
|
|
|
<img-size ref="resourceImg" :src="sizeImg(resource.src)"/>
|
|
|
<a class="banner" ref="resourceImg" v-if="resource.src" @click.prevent="gotoNewPage">
|
|
|
<img-size :src="sizeImg(resource.src)"/>
|
|
|
</a>
|
|
|
<div class="info">
|
|
|
<transition-group name="info-list" tag="div" class="info-list">
|
...
|
...
|
@@ -96,12 +96,13 @@ import BuySheet from './components/buy-sheet'; |
|
|
import TopList from './components/top-list';
|
|
|
import SquareImg from './components/square-img';
|
|
|
import stateShortCutsMixins from './mixins';
|
|
|
import trackingMixins from './tracking-mixins';
|
|
|
|
|
|
const { mapActions, mapState } = createNamespacedHelpers('product');
|
|
|
|
|
|
export default {
|
|
|
name: 'ProductDetail',
|
|
|
mixins: [stateShortCutsMixins],
|
|
|
mixins: [stateShortCutsMixins, trackingMixins],
|
|
|
components: {
|
|
|
SizeSelectSheet,
|
|
|
ActivityListSheet,
|
...
|
...
|
@@ -173,11 +174,11 @@ export default { |
|
|
}, {
|
|
|
text: '发售时间',
|
|
|
value: this.productDetail.sale_time
|
|
|
},
|
|
|
},
|
|
|
// {
|
|
|
// text: '发售价格',
|
|
|
// value: this.productDetail.offer_price
|
|
|
// },
|
|
|
// },
|
|
|
{
|
|
|
text: '货号',
|
|
|
value: this.productDetail.product_code
|
...
|
...
|
@@ -201,6 +202,24 @@ export default { |
|
|
showSizeSelectSheet: 'onSizeSelectSheetHide',
|
|
|
showSizeRequestSheet: 'onSizeRequestHide',
|
|
|
};
|
|
|
|
|
|
// create watcher for list data
|
|
|
this.watchList = [];
|
|
|
['resource.url', 'topList', 'recommend'].forEach(key => {
|
|
|
this.watchList.push(this.$watch(key, val => {
|
|
|
if (val) {
|
|
|
this.listDataDirty = true;
|
|
|
}
|
|
|
}));
|
|
|
});
|
|
|
},
|
|
|
beforeDestroy() {
|
|
|
if (this.watchList) {
|
|
|
this.watchList.forEach(item => {
|
|
|
item && item();
|
|
|
});
|
|
|
this.watchList = null;
|
|
|
}
|
|
|
},
|
|
|
asyncData({store, router}) {
|
|
|
const productId = parseInt(router.params.productId, 10);
|
...
|
...
|
@@ -233,17 +252,15 @@ export default { |
|
|
}
|
|
|
|
|
|
if (this.resource && this.resource.url) {
|
|
|
this.yasResourceVisible();
|
|
|
this.yasResourceAvailable();
|
|
|
} else {
|
|
|
this._resourceImgWatcher = this.$watch(() => {
|
|
|
return this.resource && this.resource.url;
|
|
|
}, (url) => {
|
|
|
if (url) {
|
|
|
this._resourceImgWatcher && this._resourceImgWatcher();
|
|
|
this.yasResourceVisible();
|
|
|
this.yasResourceAvailable();
|
|
|
}
|
|
|
}, {
|
|
|
immediate: true,
|
|
|
});
|
|
|
}
|
|
|
|
...
|
...
|
@@ -318,96 +335,80 @@ export default { |
|
|
refresh() {
|
|
|
this.$refs.slide && this.$refs.slide.refresh && this.$refs.slide.refresh();
|
|
|
},
|
|
|
scrollEndHandler({y}) {
|
|
|
const scrollTop = Math.abs(y);
|
|
|
const pageScrollHeight = this.$refs.pageScroll.$el.offsetHeight;
|
|
|
|
|
|
// 相关商品
|
|
|
if (!this._topListYas && this.$refs.topList) {
|
|
|
if (this._topListTop === undefined) {
|
|
|
this._topListTop = this.$refs.topList.$el.offsetTop;
|
|
|
}
|
|
|
|
|
|
if (scrollTop < this._topListTop && (scrollTop + pageScrollHeight) > this._topListTop) {
|
|
|
const DATA = this.topList.slice(0, 3).map((value, i) => {
|
|
|
return {...this.recommendYasParams, I_INDEX: i + 1, PRD_SKN: value.id, POS_ID: 1};
|
|
|
});
|
|
|
|
|
|
/**
|
|
|
*
|
|
|
* 1.P_NAME:页面名称,XY_UFOProductDetail;
|
|
|
* 2.P_PARAM:页面参数;
|
|
|
* 3.I_INDEX:曝光顺序;
|
|
|
* 4.PRD_SKN:商品id
|
|
|
* 5.POS_ID: 1:相关商品,2: 推荐推荐,3: 相关商品列表页面
|
|
|
*/
|
|
|
this.$store.dispatch('reportYas', {
|
|
|
params: {
|
|
|
param: {DATA},
|
|
|
appop: 'XY_UFO_SHOW_EVENT'
|
|
|
}
|
|
|
});
|
|
|
this._topListYas = true;
|
|
|
}
|
|
|
collectTrackingInfo(viewInfo, force) {
|
|
|
if (!this.yasTargets) {
|
|
|
this.yasTargets = {};
|
|
|
}
|
|
|
|
|
|
// 推荐商品
|
|
|
if (this._productItemHeight === undefined) {
|
|
|
let item = document.querySelector('.product-list-item');
|
|
|
|
|
|
if (item) {
|
|
|
this._productItemHeight = item.offsetHeight;
|
|
|
this._productListOffsetTop = item.offsetTop;
|
|
|
}
|
|
|
// banner
|
|
|
if (this.$refs.resourceImg && this.resource.url && (!this.yasTargets.banner || force)) {
|
|
|
/**
|
|
|
* 商品详情页中的资源位曝光
|
|
|
* XY_UFO_SHOW_EVENT
|
|
|
* 1.P_NAME:当前页面名称,XY_UFOProductDetail;
|
|
|
* 2.P_PARAM:当前页面资源位code;
|
|
|
* 3.PRD_ID:商品ID;
|
|
|
* 4.ACTION_URL:资源位跳转URL;
|
|
|
*/
|
|
|
this.yasTargets.banner = {
|
|
|
el: {
|
|
|
offsetTop: this.$refs.resourceImg.offsetTop,
|
|
|
offsetHeight: this.$refs.resourceImg.offsetHeight,
|
|
|
},
|
|
|
yasParams: {
|
|
|
P_NAME: 'XY_UFOProductDetail',
|
|
|
P_PARAM: this.resourceContentCode,
|
|
|
PRD_ID: this.productId,
|
|
|
ACTION_URL: this.resource.url,
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
|
|
|
if (this.$refs.recommendList && this._productItemHeight) {
|
|
|
const productListVisibleHeight = scrollTop + pageScrollHeight - this._productListOffsetTop;
|
|
|
|
|
|
if (productListVisibleHeight > 0) {
|
|
|
const maxRow = Math.floor(productListVisibleHeight / this._productItemHeight);
|
|
|
|
|
|
const listScrollTop = Math.max(0, scrollTop - this._productListOffsetTop);
|
|
|
const row = Math.floor(listScrollTop / this._productItemHeight);
|
|
|
|
|
|
const list = this.recommend.slice(row * 2, (row + maxRow) * 2).filter(item => !item.yas);
|
|
|
|
|
|
if (list.length > 0) {
|
|
|
const DATA = list.map(item => {
|
|
|
item.yas = true;
|
|
|
return {...this.recommendYasParams, I_INDEX: ++this.recommendYasIndex, PRD_SKN: item.id};
|
|
|
});
|
|
|
// 相关商品
|
|
|
if (this.$refs.topList && this.topList && (!this.yasTargets.topList0 || force)) {
|
|
|
const elInfo = {
|
|
|
offsetTop: this.$refs.topList.$el.offsetTop,
|
|
|
offsetHeight: this.$refs.topList.$el.offsetHeight,
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 1.P_NAME:页面名称,XY_UFOProductDetail;
|
|
|
* 2.P_PARAM:页面参数;
|
|
|
* 3.I_INDEX:曝光顺序;
|
|
|
* 4.PRD_SKN:商品id
|
|
|
* 5.POS_ID: 1:相关商品,2: 推荐推荐,3: 相关商品列表页面
|
|
|
*/
|
|
|
this.topList.slice(0, 3).forEach((value, i) => {
|
|
|
this.yasTargets[`topList${i}`] = {
|
|
|
el: elInfo,
|
|
|
yasParams: {...this.recommendYasParams, I_INDEX: i + 1, PRD_SKN: value.id, POS_ID: 1},
|
|
|
};
|
|
|
});
|
|
|
}
|
|
|
|
|
|
this.$store.dispatch('reportYas', {
|
|
|
params: {
|
|
|
param: {DATA},
|
|
|
appop: 'XY_UFO_SHOW_EVENT'
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
// 推荐商品
|
|
|
if (this.$refs.recommendList && this.recommend && this.recommend.length > 0 && (!this.yasTargets.productItem0 || force)) {
|
|
|
let productElList = document.querySelectorAll('.product-list-item');
|
|
|
|
|
|
if (productElList && productElList.length > 0) {
|
|
|
this.recommend.forEach((item, i) => {
|
|
|
if (productElList[i] && item) {
|
|
|
const id = `productItem${i}`;
|
|
|
|
|
|
this.yasTargets[id] = {
|
|
|
el: {
|
|
|
offsetTop: productElList[i].offsetTop,
|
|
|
offsetHeight: productElList[i].offsetHeight,
|
|
|
},
|
|
|
yasParams: {...this.recommendYasParams, I_INDEX: i + 1, PRD_SKN: item.id},
|
|
|
};
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
yasResourceVisible() {
|
|
|
/**
|
|
|
* 商品详情页中的资源位曝光
|
|
|
* XY_UFO_SHOW_EVENT
|
|
|
* 1.P_NAME:当前页面名称,XY_UFOProductDetail;
|
|
|
* 2.P_PARAM:当前页面资源位code;
|
|
|
* 3.PRD_ID:商品ID;
|
|
|
* 4.ACTION_URL:资源位跳转URL;
|
|
|
*/
|
|
|
this.$store.dispatch('reportYas', {
|
|
|
params: {
|
|
|
appop: 'XY_UFO_SHOW_EVENT',
|
|
|
param: {
|
|
|
P_NAME: 'XY_UFOProductDetail',
|
|
|
P_PARAM: this.resourceContentCode,
|
|
|
PRD_ID: this.productId,
|
|
|
ACTION_URL: this.resource.url,
|
|
|
},
|
|
|
}
|
|
|
});
|
|
|
yasResourceAvailable() {
|
|
|
this.scrollEndHandler();
|
|
|
if (this._resourceImgWatcher) {
|
|
|
this._resourceImgWatcher();
|
|
|
this._resourceImgWatcher = null;
|
...
|
...
|
@@ -421,8 +422,8 @@ export default { |
|
|
|
|
|
// 加载商品详情数据
|
|
|
loadData(productId = this.productId) {
|
|
|
this.fetchBrandTop({productId});
|
|
|
this.fetchFav({productId});
|
|
|
this.fetchBrandTop({ productId });
|
|
|
this.fetchFav({ productId });
|
|
|
},
|
|
|
|
|
|
/**
|
...
|
...
|
|