node中間層

/ 思路:給當前的運行環境加上標識 系統環境變量 (內存) // 怎麼設置環境變量在內存 // 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
    複製代碼
  • express.json() 解析前端提交的json格式字符串
  • express.urlencoded({extended: false}) 提交表單的數據post

02-回顧ios

  • node中間層
  • mvc思想
  • 介紹中間件類型
  • 錯誤處理
    • app.use((req,res,next))
    • app.use((err,req,res,next))
    • 設置環境變量
  • 模版抽離

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-首頁-分類數據緩存

  • 分類的數據獲取時間好久
  • 獲取一次後 緩存在node中間層
  • 在內存中存儲 一個變量 存儲分類信息
  • // 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
    複製代碼
  • express.json() 解析前端提交的json格式字符串
  • express.urlencoded({extended: false}) 提交表單的數據post

02-回顧

  • node中間層
  • mvc思想
  • 介紹中間件類型
  • 錯誤處理
    • app.use((req,res,next))
    • app.use((err,req,res,next))
    • 設置環境變量
  • 模版抽離

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-首頁-分類數據緩存

  • 分類的數據獲取時間好久
  • 獲取一次後 緩存在node中間層
  • 在內存中存儲 一個變量 存儲分類信息
  • // 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-商品詳情-渲染-商品簡介

相關文章
相關標籤/搜索