路由传参

购物车点击”去结算”按钮时跳转到订单结算页面, 此时router-link需传递 shopId 和 shopName 参数
参数可以通过 params 或 query string 传递,且两者都可以传递多个参数

  1. <router-link :to="{name: 'Checkout', params: {id: shopId}, query: {shopName}}">
  2. 去结算
  3. </router-link>

使用 params 传参时别忘了路由定义时需设置变量

  1. {
  2. path: '/checkout/:id',
  3. name: 'Checkout',
  4. component: () => import(/* webpackChunkName: "checkout" */ '@/views/CheckOut.vue'),
  5. },

在组件中获取参数

  1. <script lang="ts">
  2. import { useRoute } from 'vue-router'
  3. export default {
  4. setup(){
  5. const route = useRoute()
  6. const shopId = route.params.id
  7. const shopName = route.query.shopName
  8. return {
  9. shopId,
  10. shopName
  11. }
  12. }
  13. }
  14. </script>

使用 router.push 代替 router-link

  1. const router = useRouter()
  2. const handleCheckoutButtonClick = () => {
  3. if (count.value === 0) {
  4. console.log('cart is empty')
  5. showToast('还没挑选商品哦!')
  6. return
  7. }
  8. router.push({name: 'Checkout', params: {id: shopId}, query: {shopName:'hello'}})
  9. }

注意 useRouter 和 useRoute 都只能用在setup()函数的最外层,如果写在其他函数里面会得到 undefined
参考文档1 参考文档2

背景部分渐变

实现背景部分渐变
image.png

  1. /* 方法一 */
  2. .top {
  3. background-size: 100% 76%;
  4. background-image: linear-gradient(0deg, rgba(0,145,255,0.00) 4%, #0091FF 55%);
  5. background-repeat: no-repeat;
  6. }
  7. /* 方法二 */
  8. .top {
  9. background-image: linear-gradient(0deg, rgba(0,145,255,0.00) 30%, #0091FF 70%);
  10. }

父元素跳过子元素的点击事件

事件处理函数在父元素上,要跳过子元素的点击事件,可通过 event.target.className 来判断点击的元素

  1. const handleCommit = (e) => {
  2. if(e.target.className.includes('nohandle')) return;
  3. showConfirmPanel.value = !showConfirmPanel.value
  4. }

也可以使用 .stop 修饰符

  1. <div class="mask" v-if="showConfirmPanel" @click="toggleShowConfirmPanel">
  2. <div class="confirm-panel" @click.stop>
  3. <h2>确认要离开收银台?</h2>
  4. <p>请尽快完成支付,否则将被取消</p>
  5. <div class="buttons">
  6. <button @click="toggleShowConfirmPanel">取消支付</button>
  7. <button>确认支付</button>
  8. </div>
  9. </div>
  10. </div>

如果只监听父元素的点击事件,不监听子元素的点击事件,可以通过**e.target === e.currentTarget** 来判断

产生订单

在mutation中添加confirmOrder方法

  1. confirmOrder(state, payload) {
  2. const { shopId, shopName } = payload
  3. const orderId = Math.floor(Math.random() * 1000000000)
  4. const { orderList } = state
  5. const products = state.cartList[shopId]
  6. const order: OrderItem = {
  7. shopName,
  8. products: [],
  9. }
  10. const checkedKeys: string[] = []
  11. for (const i in products) {
  12. const product = products[i]
  13. if (product.count > 0 && product.checked) {
  14. checkedKeys.push(i)
  15. }
  16. }
  17. for (const i of checkedKeys) {
  18. order.products.push(products[i])
  19. delete products[i]
  20. }
  21. orderList[orderId] = order
  22. saveOrderListToLocalStorage(state)
  23. },

订单数据处理

  1. import { deepClone } from "@/lib/helper";
  2. import { useStore } from "vuex";
  3. import dayjs from 'dayjs'
  4. const store = useStore()
  5. const orderList = store.state.orderList
  6. const newOrderList = deepClone(orderList).sort((a, b) =>
  7. dayjs(b.createDate).valueOf() - dayjs(a.createDate).valueOf())
  8. newOrderList.forEach(item => {
  9. item.createDate = dayjs(item.createDate).format('YYYY-MM-DD HH:mm:ss')
  10. item.totalCount = item.products.reduce((sum, item) => sum + item.count, 0)
  11. item.totalPrice = item.products.reduce((sum, item) => sum + (item.count * item.price) ,0).toFixed(2)
  12. item.shortProducts = item.products.slice(0, 4)
  13. })

props解构问题

props在setup的根作用域中解构回导致被赋值的变量失去 reactive 特性
参考文档
解决办法: 创建 ref 或 reactive, 初始值传 props, 然后再解构

  1. const props = defineProps({
  2. products: {type: Object, required: true},
  3. })
  4. const checkedProducts = ref(props.products)
  5. const products = ref({})
  6. products.value = checkedProducts.value