/ 思路:給當前的運行環境加上標識 系統環境變量 (內存) // 怎麼設置環境變量在內存 // windows SET NODE_ENV=production // windows SET NODE_ENV=development // 可以去跨平臺設置環境變量 cross-env 第三方命令行工具 // npm i -g cross-env // cross-env NODE_ENV=production 或者 cross-env NODE_ENV=development // 在設置完成環境變量的同時 啓動項目 // 那麼能夠在項目代碼 獲取當前設置的環境變量 去區分運行環境 // 開發 cross-env NODE_ENV=development nodemon app.js // 生產 cross-env NODE_ENV=production node app.js // package.json scripts 進行配置php
"scripts": { "test": "echo "Error: no test specified" && exit 1", "dev": "cross-env NODE_ENV=development nodemon app.js", "start": "cross-env NODE_ENV=production node app.js" },css
// 獲取 環境變量 判斷環境 req.app.get('env')html
NODE中間層項目-day02前端
01-反饋html5
姓名 意見或建議
*** 1. req.query 不是接受get傳送的數據嗎 它是中間件嗎 2. 老師template第二個參數 必須是對象形式嗎 3.提交表單的數據不是json格式嗎能夠用app.use(express.json())嗎仍是必須用app.use(express.urlencoded({extended: false})) 這句話是對bodypaser的設置嗎 設置完了能夠用req.body來接受post的數據 這幾個中間件有點弄不清楚 *** 剛哥把提取母的文件部分再細細的講一下吶 艾尼喲node
// template('id',數據) 數據能夠爲任何類型 模版內容獲取傳入的數據$data
複製代碼
02-回顧ios
03-抽離公用模版ajax
{{include '../components/header.art'}}
複製代碼
04-維護網站頭部信息express
config.jsnpm
// 1. 網站頭部信息
const site = {
title: '品優購(PYG.COM)-正品低價、品質保障、配送及時、輕鬆購物!',
description: '品優購(PYG.COM)-專業的綜合網上購物商城,爲您提供正品低價的購物選擇、優質便捷的服務體驗。商品來自全球數十萬品牌商家,囊括家電、手機、電腦、服裝、居家、母嬰、美妝、個護、食品、生鮮等豐富品類,知足各類購物需求。',
Keywords:'網上購物,網上商城,家電,手機,電腦,服裝,居家,母嬰,美妝,個護,食品,生鮮,京東'
}
導出模塊:
module.exports = {site}
exports = {site}
相同:導出模塊
區別:module.exports 是最終使用的導出內容,exports爲了語法簡單
結論:當你直接賦值 module.exports 當你是掛載屬性 使用誰同樣的
導入模塊:
require('')
複製代碼
遵循:commonJS 模塊化規範
AMD require.js 提早加上全部模塊 CMD sea.js 按需加載模塊
nodejs 實現同步加載模塊 commonJS
ES6模塊化規範
實現思路: global 污染 ----》 app 沒法在模版內使用 ----》 render 每一個頁面須要這個數據 ----》res.locals 掛載的數據能夠在模版內使用 ----》 在中間件 公用中間件
05-提取路由模塊和控制器
// 定義路由規則 不去實現具體的業務 controller
const express = require('express')
const router = express.Router()
const homeController = require('./controllers/homeController')
const userController = require('./controllers/userController')
router.get('/', homeController.home)
router.get('/login',userController.login)
module.exports = router
複製代碼
06-提取axios模塊
// 返回 已經配置好的 axios 實例
const axios = require('axios')
const instance = axios.create({
baseURL: 'http://localhost:8000/v1/',
auth: {
username: 'newshop-frontend',
password: 'd8667837fce5a0270a35f4a8fa14be479fadc774'
}
})
module.exports = instance
複製代碼
07-首頁-渲染輪播圖
<!--banner輪播-->
<div id="banner" data-ride="carousel" data-interval="4000" class="sui-carousel slide">
<ol class="carousel-indicators">
{{each banner item i}}
<li data-target="#banner" data-slide-to="{{i}}" class="{{i===0?'active':''}}"></li>
{{/each}}
</ol>
<div class="carousel-inner">
{{each banner item i}}
<div class="item {{i===0?'active':''}}"><a href="{{item.link}}"><img src="{{item.image}}" title="{{item.title}}"></a></div>
{{/each}}
</div>
<a href="#banner" data-slide="prev" class="carousel-control left">‹</a>
<a href="#banner" data-slide="next" class="carousel-control right">›</a>
</div>
複製代碼
08-首頁-複習promise
在then函數中直接返回 封裝成一個promise對象 必定是成功的調用
在catch函數中直接返回 封裝成一個promise對象 必定是成功的調用
在catch函數中返回 promise對象 失敗的狀況 Promise.reject(err)
return axios.get('settings/home_slides') .then(res => res.data) .catch(err => Promise.reject(err))
Promise.reject() 錯誤回調
Promise.resolve() 成功回調
Promise.all() 同時執行多個promise對象 全部的promise操做結束後觸發then()
Promise.race() 同時執行多個promise對象 等最快的異步操做結束觸發then()
09-首頁-渲染猜你喜歡
獲取數據:
Promise.all([homeModel.getBanner(), homeModel.getLike()])
.then(results => {
// results 全部的異步操做的返回結果 且順序和你傳入promise對象的順序一致
res.locals.banner = results[0]
res.locals.like = results[1]
res.render('home.art')
}).catch(err=> next(err))
複製代碼
渲染頁面:
{{each like item i}}
<li class="yui3-u-1-6">
<a href="/item/{{item.id}}" class="pic"><img src="{{item.thumbnail}}"></a>
<p>{{item.name}}</p><h3>¥{{item.price}}</h3>
</li>
{{/each}}
複製代碼
10-首頁-定義猜你喜歡接口
exports.like = (req, res, next) => {
homeModel.getLike()
.then(data => {
res.send({
status: 200,
result: data
})
})
.catch(err => {
res.send({
status: 500,
msg: '獲取猜你喜歡數據失敗'
})
})
}
複製代碼
11-首頁-猜你喜歡換一換
// 點擊換一換按鈕 發生ajax請求 成功的時候 更新列表
$('#xxlChg').on('click', function () {
$.get('/like', function (data) {
if (data.status !== 200) return alert(data.msg)
var html = ''
data.result.forEach(function (item) {
html += `
<li class="yui3-u-1-6">
<a href="/item/${item.id}" class="pic"><img src="${item.thumbnail}"></a>
<p>${item.name}</p>
<h3>¥${item.price}</h3>
</li>
`
})
$('#picLBxxl').fadeOut(function () {
$(this).html(html).fadeIn()
})
})
})
複製代碼
12-首頁-獲取分類數據
// 全局的處理
exports.global = (req, res, next) => {
// 1. 設置網站頭部
res.locals.site = site
// 2. 獲取分類數據且設置模版使用
// 2.1 數據獲取時間太長 優化
categoryModel.getCategory().then(data => {
res.locals.category = data
next()
}).catch(err => next(err))
}
複製代碼
13-首頁-渲染分類模塊
{{each category item i}}
<div class="item">
<h3><a href="/list/{{item.id}}">{{item.name}}</a></h3>
<div class="item-list clearfix">
<div class="subitem">
{{each item.children subItem i}}
<dl>
<dt><a href="/list/{{subItem.id}}">{{subItem.name}}</a></dt>
<dd>
{{each subItem.children lastItem i}}
<em><a href="/list/{{lastItem.id}}">{{lastItem.name}}</a></em>
{{/each}}
</dd>
</dl>
{{/each}}
</div>
</div>
</div>
{{/each}}
複製代碼
14-首頁-分類數據緩存
// 2. 獲取分類數據且設置模版使用
// 2.1 數據獲取時間太長 優化
// 2.2 在 app 實例存儲數據 緩存分類
// 2.3 req.locals 每次請求都是新的對象
// 2.4 req.app.locals 掛載數據的對象
// 2.5 判斷是否緩存數據 若是緩存走緩存 若是沒有走接口
if (req.app.locals.category) {
res.locals.category = req.app.locals.category
next()
} else {
categoryModel.getCategory().then(data => {
// 緩存
req.app.locals.category = data
res.locals.category = data
next()
}).catch(err => next(err))
}
複製代碼
15-分類商品列表-路由規則定義
// 商品列表
router.get('/list/:id', productController.list)
複製代碼
16-分類商品列表-獲取路徑傳參
exports.list = (req, res, next) => {
// 獲取路徑傳參 req.params
// 獲取地址?傳參 req.query
// 獲取post傳參 req.body
res.send(req.params.id)
}
複製代碼
17-分類商品列表-獲取列表數據
// 獲取分類下的商品
exports.getProductsPager = (id, page, per_page) =>{
return axios.get(`categories/${id}/products?page=${page}&per_page=${per_page}`)
.then(res => {
// 還須要分頁數據 在響應頭中
// res 響應報文對象 res.headers 獲取響應頭
// console.log(res.headers)
return {
list: res.data,
totalPage: + res.headers['x-total-pages']
}
})
.catch(err => Promise.reject(err))
}
// 獲取post傳參 req.body
const id = req.params.id
// 在?後提交數據 page
const page = req.query.page || 1
// 經過分類ID去獲取商品列表數據且帶分頁
categoryModel.getProductsPager(id, page, 10)
.then(data => {
res.send(data)
}).catch(err => next(err))
複製代碼
18-分類商品列表-渲染列表
<ul class="yui3-g">
{{each list item i}}
<li class="yui3-u-1-5">
<div class="p-img"><a href="/item/{{item.id}}"><img src="{{item.thumbnail}}"></a></div>
<div class="price"><strong><em>¥</em><i>{{item.price}}</i></strong></div>
<div class="attr"><em>{{item.name}}</em></div>
<div class="commit"><i class="command">已有2000人評價</i></div>
<div class="operate">
<a href="/cart/add" class="sui-btn btn-bordered btn-danger">加入購物車</a>
<a href="#" class="sui-btn btn-bordered">對比</a>
<a href="#" class="sui-btn btn-bordered">關注</a>
</div>
</li>
{{/each}}
</ul>
複製代碼
19-分類商品列表-麪包屑渲染
<!--bread-->
<div class="bread">
<ul class="fl sui-breadcrumb">
{{if bread.parent && bread.parent.parent}}
<li><a href="/list/{{bread.parent.parent.id}}">{{bread.parent.parent.name}}</a></li>
{{/if}}
{{if bread.parent}}
<li><a href="/list/{{bread.parent.id}}">{{bread.parent.name}}</a></li>
{{/if}}
<li class="active">{{bread.name}}</li>
</ul>
</div>
複製代碼
數據:
Promise.all([
categoryModel.getProductsPager(id, page, 10),
categoryModel.getCategoryAndParent(id)
]).then(results => {
res.locals.list = results[0].list
res.locals.bread = results[1]
res.render('list.art')
//res.send(res.locals)
}).catch(err => next(err))
複製代碼
20-分類商品列表-排序功能實現
<a href="/list/{{bread.id}}?sort=commend">綜合</a>
複製代碼
獲取請求的地址 不包含域名 不包含?傳參
<ul class="sui-nav">
<li class="{{sort==='commend'?'active':''}}"><a href="{{currUrl}}?sort=commend">綜合</a></li>
<li class="{{sort==='quantity'?'active':''}}"><a href="{{currUrl}}?sort=quantity">銷量</a></li>
<li class="{{sort==='market_time'?'active':''}}"><a href="{{currUrl}}?sort=market_time">新品</a></li>
<li class="{{sort.includes('price')?'active':''}}">
{{if sort==='-price'}}
<a href="{{currUrl}}?sort=price">價格 <span class="sui-icon icon-tb-fold"></span></a>
{{else if sort==='price'}}
<a href="{{currUrl}}?sort=-price">價格 <span class="sui-icon icon-tb-unfold"></span></a>
{{else}}
<a href="{{currUrl}}?sort=-price">價格</a>
{{/if}}
</li>
</ul>
const sort = req.query.sort || 'commend'
// req.url 當前請的地址
// 解析url地址 獲得pathname
const urlObject = url.parse(req.url)
res.locals.currUrl = urlObject.pathname
複製代碼
NODE中間層項目-day02
01-反饋
姓名 意見或建議
*** 1. req.query 不是接受get傳送的數據嗎 它是中間件嗎 2. 老師template第二個參數 必須是對象形式嗎 3.提交表單的數據不是json格式嗎能夠用app.use(express.json())嗎仍是必須用app.use(express.urlencoded({extended: false})) 這句話是對bodypaser的設置嗎 設置完了能夠用req.body來接受post的數據 這幾個中間件有點弄不清楚 *** 剛哥把提取母的文件部分再細細的講一下吶 艾尼喲
// template('id',數據) 數據能夠爲任何類型 模版內容獲取傳入的數據$data
複製代碼
02-回顧
03-抽離公用模版
{{include '../components/header.art'}}
複製代碼
04-維護網站頭部信息
config.js
// 1. 網站頭部信息
const site = {
title: '品優購(PYG.COM)-正品低價、品質保障、配送及時、輕鬆購物!',
description: '品優購(PYG.COM)-專業的綜合網上購物商城,爲您提供正品低價的購物選擇、優質便捷的服務體驗。商品來自全球數十萬品牌商家,囊括家電、手機、電腦、服裝、居家、母嬰、美妝、個護、食品、生鮮等豐富品類,知足各類購物需求。',
Keywords:'網上購物,網上商城,家電,手機,電腦,服裝,居家,母嬰,美妝,個護,食品,生鮮,京東'
}
導出模塊:
module.exports = {site}
exports = {site}
相同:導出模塊
區別:module.exports 是最終使用的導出內容,exports爲了語法簡單
結論:當你直接賦值 module.exports 當你是掛載屬性 使用誰同樣的
導入模塊:
require('')
複製代碼
遵循:commonJS 模塊化規範
AMD require.js 提早加上全部模塊 CMD sea.js 按需加載模塊
nodejs 實現同步加載模塊 commonJS
ES6模塊化規範
實現思路: global 污染 ----》 app 沒法在模版內使用 ----》 render 每一個頁面須要這個數據 ----》res.locals 掛載的數據能夠在模版內使用 ----》 在中間件 公用中間件
05-提取路由模塊和控制器
// 定義路由規則 不去實現具體的業務 controller
const express = require('express')
const router = express.Router()
const homeController = require('./controllers/homeController')
const userController = require('./controllers/userController')
router.get('/', homeController.home)
router.get('/login',userController.login)
module.exports = router
複製代碼
06-提取axios模塊
// 返回 已經配置好的 axios 實例
const axios = require('axios')
const instance = axios.create({
baseURL: 'http://localhost:8000/v1/',
auth: {
username: 'newshop-frontend',
password: 'd8667837fce5a0270a35f4a8fa14be479fadc774'
}
})
module.exports = instance
複製代碼
07-首頁-渲染輪播圖
<!--banner輪播-->
<div id="banner" data-ride="carousel" data-interval="4000" class="sui-carousel slide">
<ol class="carousel-indicators">
{{each banner item i}}
<li data-target="#banner" data-slide-to="{{i}}" class="{{i===0?'active':''}}"></li>
{{/each}}
</ol>
<div class="carousel-inner">
{{each banner item i}}
<div class="item {{i===0?'active':''}}"><a href="{{item.link}}"><img src="{{item.image}}" title="{{item.title}}"></a></div>
{{/each}}
</div>
<a href="#banner" data-slide="prev" class="carousel-control left">‹</a>
<a href="#banner" data-slide="next" class="carousel-control right">›</a>
</div>
複製代碼
08-首頁-複習promise
在then函數中直接返回 封裝成一個promise對象 必定是成功的調用
在catch函數中直接返回 封裝成一個promise對象 必定是成功的調用
在catch函數中返回 promise對象 失敗的狀況 Promise.reject(err)
return axios.get('settings/home_slides') .then(res => res.data) .catch(err => Promise.reject(err))
Promise.reject() 錯誤回調
Promise.resolve() 成功回調
Promise.all() 同時執行多個promise對象 全部的promise操做結束後觸發then()
Promise.race() 同時執行多個promise對象 等最快的異步操做結束觸發then()
09-首頁-渲染猜你喜歡
獲取數據:
Promise.all([homeModel.getBanner(), homeModel.getLike()])
.then(results => {
// results 全部的異步操做的返回結果 且順序和你傳入promise對象的順序一致
res.locals.banner = results[0]
res.locals.like = results[1]
res.render('home.art')
}).catch(err=> next(err))
複製代碼
渲染頁面:
{{each like item i}}
<li class="yui3-u-1-6">
<a href="/item/{{item.id}}" class="pic"><img src="{{item.thumbnail}}"></a>
<p>{{item.name}}</p><h3>¥{{item.price}}</h3>
</li>
{{/each}}
複製代碼
10-首頁-定義猜你喜歡接口
exports.like = (req, res, next) => {
homeModel.getLike()
.then(data => {
res.send({
status: 200,
result: data
})
})
.catch(err => {
res.send({
status: 500,
msg: '獲取猜你喜歡數據失敗'
})
})
}
複製代碼
11-首頁-猜你喜歡換一換
// 點擊換一換按鈕 發生ajax請求 成功的時候 更新列表
$('#xxlChg').on('click', function () {
$.get('/like', function (data) {
if (data.status !== 200) return alert(data.msg)
var html = ''
data.result.forEach(function (item) {
html += `
<li class="yui3-u-1-6">
<a href="/item/${item.id}" class="pic"><img src="${item.thumbnail}"></a>
<p>${item.name}</p>
<h3>¥${item.price}</h3>
</li>
`
})
$('#picLBxxl').fadeOut(function () {
$(this).html(html).fadeIn()
})
})
})
複製代碼
12-首頁-獲取分類數據
// 全局的處理
exports.global = (req, res, next) => {
// 1. 設置網站頭部
res.locals.site = site
// 2. 獲取分類數據且設置模版使用
// 2.1 數據獲取時間太長 優化
categoryModel.getCategory().then(data => {
res.locals.category = data
next()
}).catch(err => next(err))
}
複製代碼
13-首頁-渲染分類模塊
{{each category item i}}
<div class="item">
<h3><a href="/list/{{item.id}}">{{item.name}}</a></h3>
<div class="item-list clearfix">
<div class="subitem">
{{each item.children subItem i}}
<dl>
<dt><a href="/list/{{subItem.id}}">{{subItem.name}}</a></dt>
<dd>
{{each subItem.children lastItem i}}
<em><a href="/list/{{lastItem.id}}">{{lastItem.name}}</a></em>
{{/each}}
</dd>
</dl>
{{/each}}
</div>
</div>
</div>
{{/each}}
複製代碼
14-首頁-分類數據緩存
// 2. 獲取分類數據且設置模版使用
// 2.1 數據獲取時間太長 優化
// 2.2 在 app 實例存儲數據 緩存分類
// 2.3 req.locals 每次請求都是新的對象
// 2.4 req.app.locals 掛載數據的對象
// 2.5 判斷是否緩存數據 若是緩存走緩存 若是沒有走接口
if (req.app.locals.category) {
res.locals.category = req.app.locals.category
next()
} else {
categoryModel.getCategory().then(data => {
// 緩存
req.app.locals.category = data
res.locals.category = data
next()
}).catch(err => next(err))
}
複製代碼
15-分類商品列表-路由規則定義
// 商品列表
router.get('/list/:id', productController.list)
複製代碼
16-分類商品列表-獲取路徑傳參
exports.list = (req, res, next) => {
// 獲取路徑傳參 req.params
// 獲取地址?傳參 req.query
// 獲取post傳參 req.body
res.send(req.params.id)
}
複製代碼
17-分類商品列表-獲取列表數據
// 獲取分類下的商品
exports.getProductsPager = (id, page, per_page) =>{
return axios.get(`categories/${id}/products?page=${page}&per_page=${per_page}`)
.then(res => {
// 還須要分頁數據 在響應頭中
// res 響應報文對象 res.headers 獲取響應頭
// console.log(res.headers)
return {
list: res.data,
totalPage: + res.headers['x-total-pages']
}
})
.catch(err => Promise.reject(err))
}
// 獲取post傳參 req.body
const id = req.params.id
// 在?後提交數據 page
const page = req.query.page || 1
// 經過分類ID去獲取商品列表數據且帶分頁
categoryModel.getProductsPager(id, page, 10)
.then(data => {
res.send(data)
}).catch(err => next(err))
複製代碼
18-分類商品列表-渲染列表
<ul class="yui3-g">
{{each list item i}}
<li class="yui3-u-1-5">
<div class="p-img"><a href="/item/{{item.id}}"><img src="{{item.thumbnail}}"></a></div>
<div class="price"><strong><em>¥</em><i>{{item.price}}</i></strong></div>
<div class="attr"><em>{{item.name}}</em></div>
<div class="commit"><i class="command">已有2000人評價</i></div>
<div class="operate">
<a href="/cart/add" class="sui-btn btn-bordered btn-danger">加入購物車</a>
<a href="#" class="sui-btn btn-bordered">對比</a>
<a href="#" class="sui-btn btn-bordered">關注</a>
</div>
</li>
{{/each}}
</ul>
複製代碼
19-分類商品列表-麪包屑渲染
<!--bread-->
<div class="bread">
<ul class="fl sui-breadcrumb">
{{if bread.parent && bread.parent.parent}}
<li><a href="/list/{{bread.parent.parent.id}}">{{bread.parent.parent.name}}</a></li>
{{/if}}
{{if bread.parent}}
<li><a href="/list/{{bread.parent.id}}">{{bread.parent.name}}</a></li>
{{/if}}
<li class="active">{{bread.name}}</li>
</ul>
</div>
複製代碼
數據:
Promise.all([
categoryModel.getProductsPager(id, page, 10),
categoryModel.getCategoryAndParent(id)
]).then(results => {
res.locals.list = results[0].list
res.locals.bread = results[1]
res.render('list.art')
//res.send(res.locals)
}).catch(err => next(err))
複製代碼
20-分類商品列表-排序功能實現
<a href="/list/{{bread.id}}?sort=commend">綜合</a>
複製代碼
獲取請求的地址 不包含域名 不包含?傳參
<ul class="sui-nav">
<li class="{{sort==='commend'?'active':''}}"><a href="{{currUrl}}?sort=commend">綜合</a></li>
<li class="{{sort==='quantity'?'active':''}}"><a href="{{currUrl}}?sort=quantity">銷量</a></li>
<li class="{{sort==='market_time'?'active':''}}"><a href="{{currUrl}}?sort=market_time">新品</a></li>
<li class="{{sort.includes('price')?'active':''}}">
{{if sort==='-price'}}
<a href="{{currUrl}}?sort=price">價格 <span class="sui-icon icon-tb-fold"></span></a>
{{else if sort==='price'}}
<a href="{{currUrl}}?sort=-price">價格 <span class="sui-icon icon-tb-unfold"></span></a>
{{else}}
<a href="{{currUrl}}?sort=-price">價格</a>
{{/if}}
</li>
</ul>
const sort = req.query.sort || 'commend'
// req.url 當前請的地址
// 解析url地址 獲得pathname
const urlObject = url.parse(req.url)
res.locals.currUrl = urlObject.pathname
複製代碼
07-商品列表-按關鍵字搜索
搜索框 保留搜索的關鍵字
在麪包屑的位置 提示文字 根據'123'的搜索結果:
其餘需求和分類下商品列表一致
// 1. 搜索關鍵字 const q = req.query.q // 2. 排序類型 const sort = req.query.sort || 'commend' // 3. 當前頁碼 每頁顯示條數 const page = req.query.page || 1 const per_page = 5 // 4. 商品列表 根據(搜索關鍵字,排序方式,當前頁碼,每頁顯示條數)去獲取 productModel.getProductsPager(q,page,per_page,sort) .then(data=>{ // 前端頁面須要哪些數據??? res.locals.q = q res.locals.sort = sort res.locals.list = data.list res.locals.pagination = paginationUtil({ currPage: +page, totalPage: data.totalPage, req }) res.render('list.art') }).catch(err => next(err))
注意:php服務器 不支持URL傳中文
// 不能傳中文
// 地址欄編碼 URI
// 中文 轉換 URI 編碼
//encodeURIComponent('電腦')
//"%E7%94%B5%E8%84%91"
//decodeURIComponent('%E7%94%B5%E8%84%91')
//"電腦"
複製代碼
08-商品詳情-路由規則配置
規則 處理函數 模版頁面
// 商品詳情
router.get('/item/:id', productController.detail)
{{extend './layout/common.art'}}
{{block 'styles'}}
<link rel="stylesheet" href="/public/assets/css/page-item.css">
<link rel="stylesheet" href="/public/assets/css/xzoom.css">
{{/block}}
{{block 'scripts'}}
<script src="/public/assets/js/sui.tab.js"></script>
<script src="/public/assets/js/xzoom.min.js"></script>
<script>
$(function () {
$('.xzoom, .xzoom-gallery').xzoom({ tint: '#888', Xoffset: 15 })
})
</script>
{{/block}}
複製代碼
09-商品詳情-頁面需求分析
經過兩個接口:
products/:id?include=introduce,category,pictures
products?type=like&limit=6
exports.detail = (req, res, next) => {
// - 麪包屑
// - 商品圖片
// - 商品基本信息
// - 相關商品
// - 商品介紹
const id = req.params.id
Promise.all([
productModel.getProduct(id),
homeModel.getLike()
]).then(results => {
//res.send(results)
res.locals.bread = results[0].category
res.locals.pictures = results[0].pictures
res.locals.info = {
name: results[0].name,
price: results[0].price
}
res.locals.like = results[1]
res.locals.introduce = results[0].introduce
res.render('item.art')
}).catch(err => next(err))
}
複製代碼
10-商品詳情-渲染-圖片區域
<div class="fl preview-wrap">
<!--放大鏡效果-->
<div class="zoom">
<!--默認第一個預覽-->
<div id="preview" class="spec-preview">
<img class="xzoom" xoriginal="{{pictures[0].large}}" src="{{pictures[0].middle}}" width="100%">
</div>
<!--下方的縮略圖-->
<div class="spec-scroll">
{{each pictures item i}}
<a href="{{item.large}}"><img class="xzoom-gallery" src="{{item.middle}}" width="60"></a>
{{/each}}
</div>
</div>
</div>
複製代碼
11-商品詳情-渲染-商品基本信息
html5 的 輸入類型 email number url tel search
<form action="/cart/add/{{info.id}}">
<div class="controls">
<input autocomplete="off" name="count" type="number" autofocus min="1" max="10" value="1" class="itxt">
</div>
<button class="sui-btn btn-danger addshopcar">加入購物車</button>
</form>
複製代碼
12-商品詳情-渲染-相關商品
{{each like item i}}
<li>
<div class="p-img"><img src="{{item.thumbnail}}"></div>
<div class="attr"><em>{{item.name}}</em></div>
<div class="price"><strong>¥{{item.price}}</strong></div>
<div class="operate"><a href="/cart/add/{{item.id}}?count=1" class="sui-btn btn-bordered">加入購物車</a></div>
</li>
{{/each}}
複製代碼
13-商品詳情-渲染-商品簡介