目录
今日小结(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`;
}
}
}
},