• vue_eHungry 饿了么


    eHungry 仿饿了么

    • git 操作

    git checkout -b dev        // 创建新分支 dev

    git push origin dev        // 代码推送到 dev

    ------------------------------- 代码合并到主分支 ------------------------------

    git checkout master

    git merge dev

    • 安装 stylus 依赖包

    npm install stylus stylus-loader --save-dev

    common/stylus/mixins.styl -------- 复用样式代码

    • $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 --save

    • 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:{

    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}

     

    --------小尾巴 ________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...
  • 相关阅读:
    myeclipse的debug模式启动不了,但run模式可以启动
    修改tomcat的端口号
    mybatis报错:Caused by: java.lang.IllegalArgumentException: Caches collection already contains value for com.crm.dao.PaperUserMapper
    mysql报错:java.sql.SQLException: Incorrect string value: 'xE4xB8x80xE6xACxA1...' for column 'excelName' at row 1
    修改tomcat命令黑窗口的名字
    myeclipse无法部署项目的解决
    我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?
    14个Java并发容器,你用过几个?
    6 种微服务 RPC 框架,你知道几个?
    Java中Set与Set<?>到底区别在哪?
  • 原文地址:https://www.cnblogs.com/tianxiaxuange/p/10418315.html
Copyright © 2020-2023  润新知