从0-1:vue3重构饿了么

目录

静态方法 Reflect.set() 

vue3中父组件调用子组件中的方法

购物车小球

better-scroll

新版本vue-router tag属性废除

关于cookie的存储踩坑


今日小结(2023-03-25)

静态方法 Reflect.set() 

工作方式就像在一个对象上设置一个属性

Reflect.set(target, propertyKey, value[, receiver]) 

vue3中父组件调用子组件中的方法

子组件:

const toggleShow = () => {

  isShow.value = !isShow.value

}

//defineExpose将子组件的方法暴露级父组件

defineExpose({

  toggleShow

})

父组件:

<FoodDetail :food=" food" ref="foodDetail"/>

……

const foodDetail = ref()

……

//调用子组件的方法

foodDetail.value.toggleShow()

3月28日小结

购物车小球

折磨多日的购物车小球终于成功了。参考了c站上多篇帖子,各种方法都试过。最终的解决方案是,通过store进行状态管理,各组件完成各自的功能。

-----------------------------------------------------store part -------------------------------------------------------

state.js

 balls: [{
    show: false
  },
  {
    show: false
  },
  {
    show: false
  },
  {
    show: false
  },
  {
    show: false
  }
  ],
  dropBall: [] // 购物车小球

mutation-types.js

export const BALL_CHANGE_SHOW = 'ball_change_show' // 改變小球的顯示
export const CHANGE_DROP_BALL = 'change_drop_ball'

action.js

 [BALL_CHANGE_SHOW] (state, { index, isShow, el }) {
    state.balls[index].show = isShow
    state.balls[index].el = el
  },
  [CHANGE_DROP_BALL] (state, ball) {
    state.dropBall.push(ball)
  }

mutation.js

 [BALL_CHANGE_SHOW] (state, { index, isShow, el }) {
    state.balls[index].show = isShow
    state.balls[index].el = el
  },
  [CHANGE_DROP_BALL] (state, ball) {
    state.dropBall.push(ball)
  }

----------------------------------------------------component part------------------------------------------------------

shopcart.vue

 <!-- 購物車小球 -->
    <div class="ball-container">
      <transition
        v-for="(ball, index) in useState.balls"
        :key="index"
        name="drop"
        @before-enter="beforeEnter"
        @enter="enter"
        @after-enter="afterEnter"
      >
        <div class="ball" v-show="ball.show">
          <div class="inner inner-hook"></div>
        </div>
      </transition>
    </div>
// 控制小球動畫
const beforeEnter = (el) => {
  let count = useState.value.balls.length
  while (count--) {
    const ball = useState.value.balls[count]
    if (ball.show) {
      // getBoundingClientRect返回值是一个 DOMRect 对象, 此包含了一组用于描述边框的只读属性——left、top、right和bottom,单位为像素。
      // 除了 width 和 height 外的属性都是相对于视口的左上角位置而言的。
      const rect = ball.el.getBoundingClientRect()
      const x = rect.left - 32
      const y = -(window.innerHeight - rect.top - 22)

      // 小球外层控制y轴的运动轨迹,translate3d()可以开启硬件加速
      el.style.display = 'block'
      el.style.transform = `translate3d(0px,${y}px,0)`

      // 内层小球控制x轴运动轨迹,内外层运动方式是不一样的, y轴贝塞尔曲线, x轴匀速.
      const inner = el.getElementsByClassName('inner-hook')[0]
      inner.style.transform = `translate3d(${x}px, 0px,0)`
    }
  }
}
const enter = (el, done) => {
  nextTick(() => {
    el.style.webkitTransform = 'translate3d(0, 0,0)'
    el.style.transform = 'translate3d(0, 0,0)'
    const inner = el.getElementsByClassName('inner-hook')[0]
    inner.style.webkitTransform = 'translate3d(0, 0,0)'
    inner.style.transform = 'translate3d(0, 0,0)'
    el.addEventListener('transitionend', done)
  })
}
const afterEnter = (el) => {
  // 删除数组第一个元素, 并返回第一个元素,因对象都是指向地址,所以操作dropBall数组也就操作了balls数组
  const ball = useState.value.dropBall.shift()
  if (ball) {
    ball.show = false
    el.style.display = 'none'
  }
}
.ball-container {
    .ball {
      position: fixed; //小球掉落点固定在这个位置
      left: 32px;
      bottom: 22px;
      z-index: 200;
      transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
      .inner {
        width: 16px;
        height: 16px;
        border-radius: 50%;
        background: rgb(0, 160, 220);
        transition: all 0.4s linear;
      }
    }
  }

cartcount.vue

const addCart = (event) => {
  for (let i = 0; i < useState.value.balls.length; i++) {
    if (!useState.value.balls[i].show) {
      store.dispatch('changeBallShow', { index: i, isShow: true, el: event.target })
      store.dispatch('changeDropBall', useState.value.balls[i])
      return
    }
  }
}

better-scroll

今天又是better-scroll滚不起来的一天。

better-scroll滚动和css的设置有很大的关系

list-content是scroll的wrapper

.list-content {
      max-height: 10rem;
      overflow: hidden;
}

新版本vue-router tag属性废除

要想将router-link渲染成自己想要的dom元素,写法如下:

<router-link to="/about" custom v-slot="{ navigate }">
     <li @click="navigate" role="link">About Us</li>
</router-link>

关于cookie的存储踩坑

使用js-cookie工具

以存储用户信息为例

1.JSON.stringfy(userInfo) //转换为json字符串

2.Cookie.set('userInfo',JSON.stringfy(userInfo) )

3.JSON.parse(Cookie.get('userInfo'))//解析json

vue3中v-model和ref冲突问题

let orderList = ref[]
 <el-form :model="orderList" label-width="120px" label-position="left" inline>

控制台waring:

[Vue warn]: Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead

原因是:vue3的setup函数中避免用model和ref绑定同一个函数

解决办法:当然只有model绑定另一个对象了

vite 打包发布的问题

打包时碰到如下问题

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.

解决办法:

vite.config.js中添加如下设置

build: {
    outDir: './dist',
    sourcemap: false,
    minify: 'terser',
    chunkSizeWarningLimit: 1500,
    emptyOutDir: true,
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      }
    },
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        },
        chunkFileNames: (chunkInfo) => {
          const facadeModuleId = chunkInfo.facadeModuleId ? chunkInfo.facadeModuleId.split('/') : [];
          const fileName = facadeModuleId[facadeModuleId.length - 2] || '[name]';
          return `js/${fileName}/[name].[hash].js`;
        }
      }
    }
  },

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值