路由传参
购物车点击”去结算”按钮时跳转到订单结算页面, 此时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.idconst shopName = route.query.shopNamereturn {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 } = payloadconst orderId = Math.floor(Math.random() * 1000000000)const { orderList } = stateconst 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] = ordersaveOrderListToLocalStorage(state)},
订单数据处理
import { deepClone } from "@/lib/helper";import { useStore } from "vuex";import dayjs from 'dayjs'const store = useStore()const orderList = store.state.orderListconst 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
