美文网首页
vue-cli构建项目常用知识点

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

作者: 卡西法_冯文新 | 来源:发表于2018-01-16 18:08 被阅读0次

    安装

    > 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>
    

    相关文章

      网友评论

          本文标题:vue-cli构建项目常用知识点

          本文链接:https://www.haomeiwen.com/subject/spfeoxtx.html