Authored by zhangwenxue

商品详情: 使用列表数据初始化商品详情信息

... ... @@ -41,6 +41,14 @@ export default {
name: 'ProductDetail',
params: {
productId: product.id,
/**
* 传递可用的初始化数据,避免白屏
*/
productInfo: {
...product,
price: product[this.priceKey], // 统一接收端使用的价格key
},
}
});
},
... ...
... ... @@ -7,7 +7,8 @@
<cube-slide ref="slide" :data="imageList">
<cube-slide-item v-for="(item, index) in imageList" :key="index">
<a click="javascript:void 0" class="square-img-container">
<square-img :src="item.image_url" :width="300" :height="300" />
<square-img v-if="!item.initial" :src="item.image_url" :width="600" :height="600" />
<square-img v-else :src="item.image_url" :width="274" :height="274" /> <!-- 利用缓存, productList使用的size -->
</a>
</cube-slide-item>
<template slot="dots" slot-scope="props">
... ... @@ -26,8 +27,8 @@
</div>
<div class="info-name"><div>{{productDetail.product_name}}</div></div>
</div>
<a class="banner" v-if="resource" @click.prevent="gotoNewPage(resource.url)">
<img-size ref="resourceImg" :src="sizeImg(resource.src)"/>
<a class="banner" @click.prevent="gotoNewPage">
<img-size v-if="resource" ref="resourceImg" :src="sizeImg(resource.src)"/>
</a>
<div class="info">
<transition-group name="info-list" tag="div" class="info-list">
... ... @@ -202,6 +203,15 @@ export default {
throw new Error('无效的商品ID');
}
/**
* 接收初始化数据
*/
const initialProductInfo = router.params.productInfo;
if (initialProductInfo) {
store.dispatch('product/setupInitialProductInfo', initialProductInfo);
}
return store.dispatch('product/fetchProductInfo', {productId});
},
activated() {
... ... @@ -252,7 +262,8 @@ export default {
next();
},
methods: {
...mapActions(['fetchProductInfo', 'fetchBrandTop', 'fetchFav', 'toggleFav', 'updateTradeInfo', 'getSelectedTradeProduct', 'payment', 'resetSelectedSize']),
...mapActions(['fetchProductInfo', 'fetchBrandTop', 'fetchFav', 'setupInitialProductInfo',
'toggleFav', 'updateTradeInfo', 'getSelectedTradeProduct', 'payment', 'resetSelectedSize']),
historyBackGuard() {
for (let key of Object.keys(this.actionSheetCloseMap)) {
if (this[key]) {
... ... @@ -347,6 +358,7 @@ export default {
name: this.$route.name,
params: {
productId: product.id,
productInfo: product,
},
});
},
... ... @@ -507,7 +519,13 @@ export default {
},
// 资源位
gotoNewPage(url) {
gotoNewPage() {
if (!this.resource || !this.resource.url) {
return;
}
const url = this.resource.url;
/**
* 商品详情页中的资源位点击
* XY_UFO_GDS_DT_BANNER_C
... ... @@ -600,10 +618,12 @@ export default {
.banner {
display: block;
height: 132px;
img {
display: block;
width: 100%;
height: 132px;
height: 100%;
}
}
... ...
... ... @@ -3,8 +3,9 @@ import { get } from 'lodash';
import Vue from 'vue';
export default {
ensureProduct({ commit }, { productId }) {
ensureProduct({ commit, state }, { productId }) {
commit(Types.ENSURE_PRODUCT_DETAIL, { productId });
return state.products[productId];
},
async fetchProductInfo({ commit, state }, { productId }) {
const queryTasks = ['', '/resource', '/activity', '/recommend'].map(path => {
... ... @@ -71,6 +72,18 @@ export default {
commit(Types.UPDATE_BRAND_PRODUCT_TOP_LIST, { productId, topList: productList});
}
},
async setupInitialProductInfo({ commit, state, dispatch }, payload) {
const { id: productId } = payload;
if (!productId) {
return;
}
const productInfo = await dispatch('ensureProduct', {productId});
if (productInfo.product_name === null) {
commit(Types.SETUP_INITIAL_PRODUCT_INFO, payload);
}
},
async toggleFav({ commit }, { productId, isFav }) {
const result = await this.$api.post(`/api/ufo/product/favorite/${isFav ? 'add' : 'cancel'}`, { productId });
... ...
import * as Types from './types';
import { find } from 'lodash';
import { find, set } from 'lodash';
import { defaultProduct, defaultSelectedSize } from './index';
... ... @@ -58,4 +58,21 @@ export default {
[Types.RESET_SELECTED_PRODUCT_SIZE](state) {
Object.assign(state.selectedProductInfo, defaultSelectedSize());
},
[Types.SETUP_INITIAL_PRODUCT_INFO](state, payload) {
const { id: productId } = payload;
const productInfo = state.products[productId];
// 规格化数据
[['id', 'product_id'], ['price', 'least_price'], ['product_name'], ['default_images', 'goods_list[0].image_list[0].image_url']].forEach((keyMap) => {
const val = payload[keyMap[0]];
if (val !== null) {
set(productInfo, keyMap[1] || keyMap[0], val);
if (keyMap[0] === 'default_images') {
set(productInfo, 'goods_list[0].image_list[0].initial', true); // 区分初始化数据,方便使用缓存
}
}
});
}
};
... ...
export const UPDATE_PRODUCT_DETAIL = 'UPDATE_PRODUCT_DETAIL';
export const SETUP_INITIAL_PRODUCT_INFO = 'SETUP_INITIAL_PRODUCT_INFO';
export const ENSURE_PRODUCT_DETAIL = 'ENSURE_PRODUCT_DETAIL';
export const UPDATE_PRODUCT_FAV = 'UPDATE_PRODUCT_FAV';
export const UPDATE_SELECTED_PRODUCT_SIZE = 'UPDATE_SELECTED_PRODUCT_SIZE';
... ...