vue_eHungry 餓了麼

eHungry 仿餓了麼html

  • git 操做

git checkout -b dev        // 建立新分支 devvue

git push origin dev        // 代碼推送到 devios

------------------------------- 代碼合併到主分支 ------------------------------git

git checkout mastergithub

git merge devweb

  • 安裝 stylus 依賴包

npm install stylus stylus-loader --save-devajax

common/stylus/mixins.styl -------- 複用樣式代碼vue-router

  • $green = #02a774; $yellow = #F5A100; $bc = #e4e4e4; // 一像素下邊框 bottom-border-1px($color) position relative border none &:after content '' position absolute left 0 bottom 0 width 100% height 1px background-color $color transform scaleY(0.5) // 一像素上邊框 top-border-1px($color) position relative &::before content '' position absolute z-index 200 left 0 top 0 width 100% height 1px background-color $color //根據像素比縮放1px像素邊框 @media only screen and (-webkit-device-pixel-ratio: 2 ) .border-1px &::before transform scaleY(.5) @media only screen and (-webkit-device-pixel-ratio: 3 ) .border-1px &::before transform scaleY(.333333) //根據像素比來使用 2x圖 3x圖 bg-image($url) background-image: url($url + "@2x.png") @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) background-image: url($url + "@3x.png") //清除浮動 clearFix() *zoom 1 &::after content '' display block clear both
  • 入口文件配置 main.js
  • import Vue from "vue"
    import App from "./App.vue" new Vue({ el: "#app", /* components: {App}, template: "<App/>" */ /* 或者 render: function (createElement){createElement(App)} */ render: h=>h(App) })
  • 路由器 router 配置 ---- 記得在 main.js 中加入 router 

npm install vue-router --savevuex

  • import Vue from "vue" import App from "./App.vue" import Home from "../pages/Home" import Search from "../pages/Search" import Order from "../pages/Order" import Personal from "../pages/Personal" Vue.use(VueRouter) new VueRouter({ mode: "history",    // 去掉 #
     routes: [ {path: "/home", component: Home}, {path: "/search", component: Search}, {path: "/order", component: Order}, {path: "/personal", component: Personal}, {path: "/", redirect: "/home"} ] })
  • 代理 /config/index.js ---- 改完配置要重啓

dev:{npm

proxyTable: {    // 更強大的代理

"api" :{    // 代理 /api 開頭的請求

target: "http://localhost:5000",    // 代理目標的基礎路徑

changeOrigin: true,    // 支持跨域

pathRewrite: {    // 重寫路徑: 去掉開頭的 /api

"^/api": ""

}

},

"reqBaidu" :{    // 代理 /baidu 開頭的請求

target: "http://localhost:5000",    // 代理目標的基礎路徑

changeOrigin: true,    // 支持跨域

pathRewrite: {    // 重寫路徑: 去掉開頭的 /baidu

"^/baidu": ""

}

}

 

}

}

  • /src/api/ajax.js

import axios from "ajax"

export default function ajax(url, data={}, method="GET"){

return new Promise((resolve, reject)=>{

let promise = null

if(method==="GET"){

// params 指的是 query 請求字符串

promise = axios.get(url, {params: data})

}else if(method==="POST"){

promise = axios.post(url, data)

}

// promise.then(response=>resolve(response.data)).catch(err=>reject(err))

promise.then(response=>resolve(response.data)).catch(err=>alert(err))    // 外部無需多個 try catch 處理 reject

})

}

  • /src/api/request.js -------- 參考接口文檔,請求後臺數據

import ajax from "./ajax"

// BASE = "http://localhost:5000"

const BASE = "/api"    // proxTable 代理 /api 開頭的請求

export function requestAddress(longitudelatitude){

// 根據 緯度,經度 獲取店鋪位置

return ajax(`/position/${longitude},${latitude}`);

}

export const requestCategory = ()=>ajax("/index_category");    // 獲取商品分類

export const requestShops = (longitude, latitude)=>ajax("/shops", {latitude, longitude});    // 獲取店

  • Vuex.Store

npm install vuex --save

/src/vuex/store/index.js

  • import Vue from "vue"; import Vuex from "vuex"; import state from "./state" import mutations from "./mutations" import actions from "./actions" import getters from "./getters" Vue.use(Vuex); export default new Vuex.Store({ state, mutations, actions, getters })

/src/vuex/store/state.js

  • export default { isLoginRegister: false, longitude: "116.36867", latitude: "40.10038", position: {}, categorysArr: [], shops: [] }

/src/vuex/store/actions.js

  • import { TOLOGINREGISTER, SAVE_POSITION, SAVE_CATEGORY, SAVE_SHOPS } from "./mutation-type" import {requestPosition, requestCategory, requestShops} from "../../api" export default { toLoginRegister({commit}, to){ commit(TOLOGINREGISTER, to); }, async getPosition({commit, state}){ const {longitude, latitude} = state const result = await requestPosition(longitude, latitude) if(result.code === 0){ commit(SAVE_POSITION, result.data) } }, async getCategorys({commit}){ const result = await requestCategory() if(result.code === 0){ commit(SAVE_CATEGORY, result.data) } }, async getShops({commit, state}){ const {longitude, latitude} = state const result = await requestShops(longitude, latitude) if(result.code === 0){ commit(SAVE_SHOPS, result.data) } } }

/src/vuex/store/mutations.js

  • import { TOLOGINREGISTER, SAVE_POSITION, SAVE_CATEGORY, SAVE_SHOPS } from "./mutation-type" export default { [TOLOGINREGISTER] (state, to) { state.isLoginRegister = to }, [SAVE_POSITION] (state, position) { state.position = position }, [SAVE_CATEGORY] (state, categorysArr) { state.categorysArr = categorysArr }, [SAVE_SHOPS] (state, shops) { state.shops = shops } }

/src/vuex/store/mutations-type.js

  • export const TOLOGINREGISTER = "toLoginRegister" export const SAVE_POSITION = "save_position" export const SAVE_CATEGORY = "save_category" export const SAVE_SHOPS = "save_shops"

/src/vuex/store/getter.js

  • 路由元信息 - 狀態數據共享

/src/router/router.js

  • import Vue from "vue"; import VueRouter from "vue-router"; import Home from "../pages/Home/Home" import Search from "../pages/Search/Search" import Order from "../pages/Order/Order" import Personal from "../pages/Personal/Personal" import LoginRegister from "../pages/LoginRegister/LoginRegister" Vue.use(VueRouter); export default new VueRouter({ mode: "history", routes: [ {path:"/home", component: Home, meta:{showFooter: true}}, {path:"/search", component: Search, meta:{showFooter: true}}, {path:"/order", component: Order, meta:{showFooter: true}}, {path:"/personal", component: Personal, meta:{showFooter: true}}, {path:"/login_register", component: LoginRegister}, {path:"/", redirect: "/home"}, ] })
  • /src/App.vue
  • <template>
      <div>
        <router-view></router-view>
        <FooterNav v-show="$route.meta.showFooter"></FooterNav>
      </div>
    </template>
    ...
  •  watch: { categorysArr () { // 在下次 DOM 更新後,再執行回調
            this.$nextTick(()=>{ const mySwiper = new Swiper('.swiper-container', { loop: true,    // 循環模式選項
                pagination: {    // 若是須要分頁器
                  el: '.swiper-pagination', }, }) }) } },

圖片驗證碼點擊,從新請求

改變 img 的 src,每次都必須賦新的值

this.$refs.captcha.src = "http://localhost:5000/captcha?curTime="+Data.now

容聯-雲通信

Account SID

Auth Token

Rest URL 都同樣

測試號碼必須填

SMS 普通短信 sms_utilt.js 配置

MMS 彩信

-----------------------------------------------------------------------------------------

 

cookie 分兩類

會話 cookie - 保存在瀏覽器運行時內存中,關閉瀏覽器後,數據清除 - 會話的標識

持久化 cookie - 保存在瀏覽器管理的文件中,關閉瀏覽器後,數據還在

session 會話 - 保存在服務器端,用於存儲數據的容器 ---------- session 依賴於 cookie,瀏覽器能夠禁用 cookie

會話: 瀏覽器的打開到關閉,整個過程是一個會話

session 對象保存在服務器存儲數據的容器

一旦產生這個對象,服務器會自動向瀏覽器返回一個響應 cookie,用來保存 sessioin 的ID - connect.sid = sessionID

在服務器經過 request.session 獲取到 session

session 若是有: 找到對應的 session 對象

session 若是不存在: 建立新的 session 對象

第一次登陸,會將 user_id 存入 session

刷新瀏覽器, user_id 仍是能夠從 瀏覽器獲取的

可是 session 一般與 cookie 進行連用

  • 會話 cookie ---- 關閉瀏覽器,則數據清空
  • 持久化 cookie ---- 關閉瀏覽器,數據還在

 

-------------------------------------------------------------------------------------

  • mini-ui

npm install --save mint-ui

npm install --save-dev babel-     // 實現按需打包

/src/mock/data.json

處理後臺接口還不可以使用的狀況,攔截 ajax ,返回 模擬數據

/src/mock/mockServer.js -------- 使用 mockjs 來 mock 模擬數據接口

import Mock from "mockjs"

import data from "./data.json" -------- 內部會自動解析 JSON 對象 成 js 對象

// mock 三個接口,開始監視改變, 特別的是這個代碼不會向外暴露什麼

Mock.mock("/goods", {code: 0, data: data.goods})

Mock.mock("/ratings", {code: 0, data: data.ratings})

Mock.mock("/info", {code: 0, data: data.info})

/src/main.js

import "./mock/mockServer"        // 保證 mockjs 被打包執行,從而組件可使用

4

4

  • Vuex.Store 模塊化

管理的狀態 

{home:???, user:???, shop:???}

/vuex/store/modules/

home.js

  • 1

/src/vuex/store/index.js

import home from "./modules/home"

import user from "./modules/user"

import shop from "./modules/shop"

export default new Vuex.Store({

modules: {

home,

user,

shop

}

})

npm install --save better-scroll

new BScroll(".wrapper", {})

  •     mounted () {
          this.$nextTick(()=>{
            if(!this.bScroll){
              this.bScroll = new BScroll(".header_nav", {
                click: true,
                scrollX: true
              })
            }else{
              this.bScroll.refresh()
            }
          })
        }
  • ...mapGetter(["xxx"])

模塊化 時,不管寫在模塊內仍是公共 getter,都是同樣的,

只是在編寫 getter 時,注意不能重名,和 state 的指向

  • 單例對象

某種類型的實例對象只存在一個

在輪播圖 邏輯的元素,在控制外層元素時,只能用 v-show 而不能用 v-if

  • moment 自定義過濾器 - 日期處理 /src/filters/index.js

import Vue from 'vue'

import moment from "moment"

Vue.filter('data-format', funtion(vue, formatStr="YYYY-MM-DD HH:mm:ss"){

return moment().format(formatStr)

})

  • 優化 router ---- 路由懶加載效果

1. 使用 import 函數: 被引入的模塊單獨打包 (生成有一個單獨的一個 js 文件)

2. 配置的 component 是「返回 import() 獲得的模塊的函數」, 只有當請求對應的 path 纔會執行函數,獲得組件

  • 圖片懶加載 vue-lazyload ---- 其實 mint-ui 內置了這個庫
  • main.js

---- 內部會指定一個指令 lazy

  • 在組件中 <img v-lazy="food.image"/>
  • 構建打包app

1. 無 # 哈希路由 ---- 配置 404 頁面, 將 404 頁面指向 目標頁面 index.html ---- 單頁面應用

在頁面刷新,就會向後臺請求路由,而路由是前臺路由

將服務器進行 中間件攔截 - 將前臺路由請求 返回 public 頁面

2. 使用 /#/ 哈希路由 ---- 始終會被當成前臺路由處理,而不會當成後臺路由處理

  • 將 store 保存到 Vue 上 ---- 很實用
  • 導航守衛

是 vue-router 提供的 下面 2 個方面的功能

  • 監視路由跳轉
  • 控制路由跳轉

應用

在跳轉到界面以前,對用戶進行檢查限制

在界面離開以前進行收尾工做

分類

全局守衛 ---- 針對任意路由跳轉

/src/router/index.js

  • import Vue from "vue";
    import VueRouter from "vue-router";
    
    // import Home from "../pages/Home/Home"
    import Shop from "../pages/Shop/Shop"
    import Goods from "../pages/Shop/Goods/Goods"
    import Ratings from "../pages/Shop/Ratings/Ratings"
    import Info from "../pages/Shop/Info/Info"
    
    // import Search from "../pages/Search/Search"
    // import Order from "../pages/Order/Order"
    // import Personal from "../pages/Personal/Personal"
    import LoginRegister from "../pages/LoginRegister/LoginRegister"
    
    const Home = ()=>import("../pages/Home/Home")
    const Search = ()=>import("../pages/Search/Search")
    const Order = ()=>import("../pages/Order/Order")
    const Personal = ()=>import("../pages/Personal/Personal")
    
    
    Vue.use(VueRouter);
    const router = new VueRouter({
      mode: "history",
      routes: [
        {path:"/home", component: Home, meta:{showFooter: true}},
        {
          path:"/shop",
          component: Shop,
          children: [
            {path:"/shop/goods", component: Goods},
            {path:"/shop/ratings", component: Ratings},
            {path:"/shop/info", component: Info},
            {path:"/shop", redirect: "/shop/goods"},
          ]
        },
        
        {path:"/search", component: Search, meta:{showFooter: true}},
        {path:"/order", component: Order, meta:{showFooter: true}},
        {path:"/personal", component: Personal, meta:{showFooter: true}},
        
        {path:"/login_register", component: LoginRegister},
        
        {path:"/", redirect: "/home"},
      ]
    })
    
    /*************************************************/ const paths = ["/login_register"] router.beforeEach((to, from, next)=>{ // 設置全局守衛 const path = to.path if(paths.indexOf(path)>=0){ if(Vue.store.state.user.userInfo._id){ // 在 main.js 中保存 store return next("/personal") } } next() // 其餘路由請求,放行 }) /*************************************************/
    
    export default router

     


  • 全局前置守衛: 在準備跳轉到某個路由組件以前 (在開發中用的較多)

router.beforeEach((to, from, next)=>{

})

to ---- 目標路由

from ---- 當前路由

next ---- 函數

next() ---- 執行下一個守衛回調,若是沒有,就跳轉到目標路由

next(false) ---- 不繼續執行,跳轉流程在此處中斷,不會跳轉到目標路由組件

next(path) ---- 跳轉到指定的另外一個路由

next() ---- 傳入的回調函數會在組件對象建立後對象,即延後執行回調 - 且將組件對象傳入回調函數 即 this 

  • 全局後置守衛: 在跳轉到某個路由組件以後

router.afterEach((to, from)=>{

})

組件守衛 ---- 

beforeRouteEner(){        // 在跳轉到當前組件以前,沒法訪問這個組件的組件對象  this

}

beforeRouteUpdate(){        // 在當前組件顯示更新前調用,能夠訪問 this

 

}

beforeRouteLeave(){        // 在當前組件離開前調用,能夠訪問 this

}

  • 構建打包

  • 配置前臺路由 - 404 頁面

/src/router/index.js

在數組最後,配置{path: "/*", NotFound}

相關文章
相關標籤/搜索