路由传参
购物车点击”去结算”按钮时跳转到订单结算页面, 此时router-link需传递 shopId 和 shopName 参数
参数可以通过 params 或 query string 传递,且两者都可以传递多个参数
<router-link :to="{name: 'Checkout', params: {id: shopId}, query: {shopName}}">
去结算
</router-link>
使用 params 传参时别忘了路由定义时需设置变量
{
path: '/checkout/:id',
name: 'Checkout',
component: () => import(/* webpackChunkName: "checkout" */ '@/views/CheckOut.vue'),
},
在组件中获取参数
<script lang="ts">
import { useRoute } from 'vue-router'
export default {
setup(){
const route = useRoute()
const shopId = route.params.id
const shopName = route.query.shopName
return {
shopId,
shopName
}
}
}
</script>
使用 router.push 代替 router-link
const router = useRouter()
const handleCheckoutButtonClick = () => {
if (count.value === 0) {
console.log('cart is empty')
showToast('还没挑选商品哦!')
return
}
router.push({name: 'Checkout', params: {id: shopId}, query: {shopName:'hello'}})
}
注意 useRouter 和 useRoute 都只能用在setup()函数的最外层,如果写在其他函数里面会得到 undefined
参考文档1 参考文档2
背景部分渐变
实现背景部分渐变
/* 方法一 */
.top {
background-size: 100% 76%;
background-image: linear-gradient(0deg, rgba(0,145,255,0.00) 4%, #0091FF 55%);
background-repeat: no-repeat;
}
/* 方法二 */
.top {
background-image: linear-gradient(0deg, rgba(0,145,255,0.00) 30%, #0091FF 70%);
}
父元素跳过子元素的点击事件
事件处理函数在父元素上,要跳过子元素的点击事件,可通过 event.target.className 来判断点击的元素
const handleCommit = (e) => {
if(e.target.className.includes('nohandle')) return;
showConfirmPanel.value = !showConfirmPanel.value
}
也可以使用 .stop 修饰符
<div class="mask" v-if="showConfirmPanel" @click="toggleShowConfirmPanel">
<div class="confirm-panel" @click.stop>
<h2>确认要离开收银台?</h2>
<p>请尽快完成支付,否则将被取消</p>
<div class="buttons">
<button @click="toggleShowConfirmPanel">取消支付</button>
<button>确认支付</button>
</div>
</div>
</div>
如果只监听父元素的点击事件,不监听子元素的点击事件,可以通过**e.target === e.currentTarget**
来判断
产生订单
在mutation中添加confirmOrder方法
confirmOrder(state, payload) {
const { shopId, shopName } = payload
const orderId = Math.floor(Math.random() * 1000000000)
const { orderList } = state
const products = state.cartList[shopId]
const order: OrderItem = {
shopName,
products: [],
}
const checkedKeys: string[] = []
for (const i in products) {
const product = products[i]
if (product.count > 0 && product.checked) {
checkedKeys.push(i)
}
}
for (const i of checkedKeys) {
order.products.push(products[i])
delete products[i]
}
orderList[orderId] = order
saveOrderListToLocalStorage(state)
},
订单数据处理
import { deepClone } from "@/lib/helper";
import { useStore } from "vuex";
import dayjs from 'dayjs'
const store = useStore()
const orderList = store.state.orderList
const newOrderList = deepClone(orderList).sort((a, b) =>
dayjs(b.createDate).valueOf() - dayjs(a.createDate).valueOf())
newOrderList.forEach(item => {
item.createDate = dayjs(item.createDate).format('YYYY-MM-DD HH:mm:ss')
item.totalCount = item.products.reduce((sum, item) => sum + item.count, 0)
item.totalPrice = item.products.reduce((sum, item) => sum + (item.count * item.price) ,0).toFixed(2)
item.shortProducts = item.products.slice(0, 4)
})
props解构问题
props在setup的根作用域中解构回导致被赋值的变量失去 reactive 特性
参考文档
解决办法: 创建 ref 或 reactive, 初始值传 props, 然后再解构
const props = defineProps({
products: {type: Object, required: true},
})
const checkedProducts = ref(props.products)
const products = ref({})
products.value = checkedProducts.value