eHungry 仿餓了麼html
git checkout -b dev // 建立新分支 devvue
git push origin dev // 代碼推送到 devios
------------------------------- 代碼合併到主分支 ------------------------------git
git checkout mastergithub
git merge devweb
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
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) })
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"} ] })
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": ""
}
}
}
}
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
})
}
import ajax from "./ajax"
// BASE = "http://localhost:5000"
const BASE = "/api" // proxTable 代理 /api 開頭的請求
export function requestAddress(longitude, latitude){
// 根據 緯度,經度 獲取店鋪位置
return ajax(`/position/${longitude},${latitude}`);
}
export const requestCategory = ()=>ajax("/index_category"); // 獲取商品分類
export const requestShops = (longitude, latitude)=>ajax("/shops", {latitude, longitude}); // 獲取店
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"}, ] })
<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 進行連用
-------------------------------------------------------------------------------------
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
管理的狀態
{home:???, user:???, shop:???}
/vuex/store/modules/
home.js
/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() } }) }
模塊化 時,不管寫在模塊內仍是公共 getter,都是同樣的,
只是在編寫 getter 時,注意不能重名,和 state 的指向
某種類型的實例對象只存在一個
在輪播圖 邏輯的元素,在控制外層元素時,只能用 v-show 而不能用 v-if
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)
})
1. 使用 import 函數: 被引入的模塊單獨打包 (生成有一個單獨的一個 js 文件)
2. 配置的 component 是「返回 import() 獲得的模塊的函數」, 只有當請求對應的 path 纔會執行函數,獲得組件
---- 內部會指定一個指令 lazy
1. 無 # 哈希路由 ---- 配置 404 頁面, 將 404 頁面指向 目標頁面 index.html ---- 單頁面應用
在頁面刷新,就會向後臺請求路由,而路由是前臺路由
將服務器進行 中間件攔截 - 將前臺路由請求 返回 public 頁面
2. 使用 /#/ 哈希路由 ---- 始終會被當成前臺路由處理,而不會當成後臺路由處理
是 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
}
/src/router/index.js
在數組最後,配置{path: "/*", NotFound}