vue-cli构建项目常用知识点

安装

> npm i -g vue-cli
> mkdir my-project && cd my-project
> vue init webpack
> npm i && npm i element-ui

引入组件

/*  test comp */
import test from '@/views/test/menu'
import validate from '@/views/test/validate'
import trans from '@/views/test/transition'
import user from '@/views/user/user'

按需加载(懒加载)

let login = (resolve) => {
  return require.ensure([], () => {
    resolve(require('@/views/login/login'))
  })
}
let nofound = (resolve) => {
  return require.ensure([], () => {
    resolve(require('@/components/404'))
  })
}

let welcome = (resolve) => {
  return require.ensure([], () => {
    resolve(require('@/views/welcome/welcome'))
  })
}
let product = (resolve) => {
  return require.ensure([], () => {
    resolve(require('@/views/product/product'))
  })
}
let buy = (resolve) => {
  return require.ensure([], () => {
    resolve(require('@/views/product/buy'))
  })
}

let router = new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'index',
      component: login,
      meta: {
        title: '登录页面'
      }
    },
    {
      path: '/login',
      name: 'login',
      component: login,
      meta: {
        title: '登录页面'
      }
    },
    {
      path: '*',
      name: 'nofound',
      component: nofound,
      meta: {
        title: '404,你访问的页面不存在'
      }
    },
    {
      path: '/management',
      component: layout,
      children: [
        {
          path: '/welcome',
          component: welcome
        },
        {
          path: '/product',
          name: 'product',
          component: product,
          meta: {
            login: true,
            title: '产品列表'
          }
        },
        {
          path: '/buy/:id?',
          name: 'buy',
          component: buy,
          meta: {
            login: true,
            title: '购买产品'
          }
        },
      ]
    },
  ]
})

====全局路由钩子函数===

router.beforeEach((to, from, next) => {
  // console.log('to', to.matched)
  if (to.matched.some((item) => item.meta.login)) {
    // 访问需要登录
    // console.log('router.app', router)
    var info = router.app.$local.fetch('miaov')
    if (info.login) {
      next()
    } else {
      router.push({
        path: '/login',
        query: {
          redirect: to.path.slice(1)
        }
      })
    }
  } else {
    next()
  }
})
router.afterEach((to, from) => {
  // console.log('beforeEach')
  if (to.meta.title) {
    window.document.title = to.meta.title
  }
})

插件写法(格式)

/**
 * vue插件,用来获取和设置localStoraged存储
 * @type {{save: local.save, fetch: local.fetch}}
 */
let local = {
  save (key, value) {
    localStorage.setItem(key, JSON.stringify(value))
  },
  fetch (key) {
    return JSON.parse(localStorage.getItem(key)) || {}
  },
  checkPhone (phone) {
    // 手机号正则
    var pattern = /^1[34578]\d{9}$/
    if (!(pattern.test(phone))) {
      return false
    }
    return true
  },
  checkPass (pass) {
    // 输入8-20位字母和数字组成的密码
    var ptn = /^[0-9a-zA-Z]{8,20}$/
    var ptnd = /^[0-9]+$/
    var ptnw = /^[a-zA-z]+$/

    if (ptnd.test(pass)) {
      // 排除纯数字
      return false
    }
    if (ptnw.test(pass)) {
      // 排除纯字符
      return false
    }
    if (!ptn.test(pass)) {
      return false
    }
    return true
  },
  GMTToStr (time) {
    // 对GMT时间转换
    let date = new Date(time)
    let Str = date.getFullYear() + '-' +
      ((date.getMonth() + 1) < 10 ? ('0' + (date.getMonth() + 1)) : (date.getMonth() + 1)) + '-' +
      (date.getDate() < 10 ? '0' + date.getDate() : date.getDate())
    return Str
  }
}
export default {
  install: function (vm) {
    vm.prototype.$local = local
  }
}

axios 封装

import axios from 'axios'
import queryString from 'queryString'

var HTTP = axios.create({
  baseURL: 'https://www.easy-mock.com/mock/5a4b2bce6b46dc1957864742/ocr',
  // baseURL: '/api',
  timeout: 5000,
  // transformRequest: [function (data) {
  //   return queryString.stringify(data)
  // }],
})

vuex 必要时加入

State  单一状态树
Getter state 中派生出一些状态
Mutation 更改 Vuex 的 store 中的状态
Action 类似于 mutation 异步操作变更状态
Module  store 如store对象变得相当臃肿,可将store 分割成模块(module)
举例:
const store = new Vuex.Store({
  state: {
    carPanelData: [], // 购物车商品列表
    provisionalOrder: [], // 最终选择的商品列表
    orderData: [], // 订单列表
    maxOff: false,
    carShow: false,
    ball: {
      show: false, // 显示状态
      el: null, // 被点击的按钮
      img: '' // 图片路径
    }
  },
  getters:{
      totleCount (state) {
      // 购物车商品总数量
      let count = 0
      state.carPanelData.forEach((goods) => {
        count += goods.count
      })
      return count
    },
    totlePrice (state) {
      // 购物车商品总价钱
      let total = 0
      state.carPanelData.forEach((goods) => {
        total += goods.price * goods.count
      })
      return total
    },
  },
  mutations: {
    addCarPanelData (state, data) {
      // 加入购物车
      let bOff = true
      state.carPanelData.forEach((goods) => {
        if (goods.sku_id === data[0].sku_id) {
          goods.count += data[1]
          if (goods.count > goods.limit_num) {
            goods.count -= data[1]
            state.maxOff = true
            bOff = false
            return
          }
          state.ball.el = event.path[0]
          state.ball.show = true
          state.ball.img = data[0].ali_image
          bOff = false
          state.carShow = true
        }
      })
      if (bOff) {
        let goodsData = data[0]
        Vue.set(goodsData, 'count', data[1])
        Vue.set(goodsData, 'checked', true)
        state.carPanelData.push(goodsData)
        state.carShow = true
        state.ball.el = event.path[0]
        state.ball.show = true
        state.ball.img = data[0].ali_image
      }
    },
    delCarPanelData (state, id) {
      // 删除商品
      state.carPanelData.forEach((goods, index) => {
        if (goods.sku_id === id) {
          state.carPanelData.splice(index, 1)
          return false
        }
      })
    },
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

购物车小球

<transition
      name="ball"
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-bind:css="true"
>
  <div class="addcart-mask" v-show="ball.show">
    <img class="mask-item"></img>
  </div>
  </transition>
methods: {
     beforeEnter (el) {
        // 小球动效
        let ball = document.getElementsByClassName('mask-item')[0] // 小球
        let rect = this.ball.el.getBoundingClientRect() // 按钮
        let rectEl = document.getElementsByClassName('ball-rect')[0].getBoundingClientRect() // 购物车图标
        let x = (rectEl.left + 16) - (rect.left + rect.width / 2)
        let y = rect.top + rect.height / 2 - rectEl.top + 5 - 16
        console.log('Top', rect.top + rect.height / 2)
        // el:容器
        el.style.transform = 'translate3d(0,' + y + 'px,0)'
        // 小球
        ball.style.transform = 'translate3d(-' + x + 'px,0,0)'
        ball.src = this.ball.img
        console.log('el', el)
        console.log('ball', ball)
      },
      enter (el) {
        let a = el.offsetHeight
        el.a = a
        this.$nextTick(() => {
          // el:容器
          el.style.transform = 'translate3d(0,0,0)'
          // 小球
          document.getElementsByClassName('mask-item')[0].style.transform = 'translate3d(0,0,0)'
        })
      },
      afterEnter (el) {
        this.ball.show = false
      }
    }
<style type="text/css">
    .ball-enter-active{
    transition: .5s cubic-bezier(.15,.69,.6,1.29);
  }
  .ball-enter-active .mask-item{
    transition: .5s cubic-bezier(0,0,1,1);
  }
</style>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335