vue3.2 电商前台项目(二)—— 路由组件和非路由组件

文章目录

  • 一、非路由组件和路由组件
    • 1. 非路由组件
    • 2. 路由组件
    • 3. 非路由组件和路由组件的区别
    • 4. 路由的跳转
      • 4.1 声明式导航: router-link
      • 4.2 编程式导航:push、replace
      • 4.3 两者区别
    • 5. 路由元信息
    • 6. 路由传参
      • 6.1 params参数
      • 6.2 query参数
      • 6.3 路由传参的几种写法
        • 6.3.1 字符串形式
        • 6.3.2 模板字符串
        • 6.3.3 对象写法(最常用的)
      • 6.4 路由传参的对象写法中的常见问题
        • 6.4.1 对象写法中 path 和 params 结合使用会报错
        • 6.4.2 如何指定params参数可传可不传
        • 6.4.3 路由组件传递props(三种写法)

一、非路由组件和路由组件

1. 非路由组件

  • 非路由文件存放在 components 文件夹下

  • 非路由组件包含:Header【首页、登录、注册、搜索】、Footer【首页、搜索页】

  • 非路由组件的使用步骤

  1. 创建组件
  2. 引入
  3. 使用
  1. 新建 src / components / Header / index.vue
  2. 新建 src / components / Footer / index.vue
  3. App.vue 中引入和使用
<template>
  
  <Header>Header>
  
  <Footer>Footer>
template>
<script setup>
import Header from '@/components/Header'
import Footer from '@/components/Footer'
script>
<style lang="scss">style>

2. 路由组件

Home首页路由、Search搜索路由、Login登录路由、Refister注册路由

  • 路由组件存放在 src / views 文件夹下

1. 配置路由

  • src / router / index.js
import { createRouter, createWebHashHistory } from 'vue-router'

const routes = [
  // 重定向:运行项目时,立即定位到首页,而不是 /
  {
    path: '/',
    redirect: '/home'
  }, {
    path: '/home',
    component: () => import('@/views/Home')
  }, {
    path: '/search',
    component: () => import('@/views/Search')
  }, {
    path: '/login',
    component: () => import('@/views/Login')
  }, {
    path: '/register',
    component: () => import('@/views/Register')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router


2. 引入和注册

  • vue3 在创建的时候如果选择安装路由,则会在 main.js 自动引入和注册
  • 如果没有在创建项目时安装,则需要手动安装 vue-router,再在 main.js 中引入和注册

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 引入路由
import store from './store'

// 重置样式
import 'normalize.css'
import '@/assets/styles/common.css'
createApp(App).use(store).use(router).mount('#app')

3. App.vue 中设置路由出口

<template>
  
  <Header>Header>
  
  <router-view>router-view>
  
  <Footer>Footer>
template>
<script setup>
import Header from '@/components/Header'
import Footer from '@/components/Footer'
script>
<style lang="scss">style>

3. 非路由组件和路由组件的区别

  1. 路由组件一般存放在views 文件夹,非路由组件一般存放在components 文件夹
  2. 路由组件一般需要在router文件中进行注册(使用的即为组件的名字),非路由组件一般是以标签的形式使用
  3. 路由一旦被注册,不管是路由还是非路由组件都会拥有$ toute、$ router 属性

$router:一般用于在编程式导航进行路由跳转(push/replace)
$route:一般用于获取路由信息,如路径、query、params

4. 路由的跳转

4.1 声明式导航: router-link

  • 必须带有 to 属性,用于指明要跳转的位置
<router-link to="/login">登录</router-link>

4.2 编程式导航:push、replace

import { useRouter } from 'vue-router'
const router = useRouter()
// 搜索按钮的回调函数
const handleSearch = () => {
  router.push('/search')
}

4.3 两者区别

  • 声明式导航能做的,编程式导航都可以做
  • 编程式导航除了路由跳转,还可以处理其他业务逻辑

5. 路由元信息

  • 通过配置 meta 字段
  • 本项目中通过meta来控制 底部的显示与隐藏

  <Footer v-if="$route.meta.showFooter">Footer>
const routes = [
  // 重定向:运行项目时,立即定位到首页,而不是 /
  {
    path: '/',
    redirect: '/home'
  }, {
    path: '/home',
    component: () => import('@/views/Home'),
    meta: {
      showFooter: true
    }
  }, {
    path: '/search',
    component: () => import('@/views/Search'),
    meta: {
      showFooter: true
    }
  }, {
    path: '/login',
    component: () => import('@/views/Login'),
    meta: {
      showFooter: false
    }
  }, {
    path: '/register',
    component: () => import('@/views/Register'),
    meta: {
      showFooter: false
    }
  }
]

6. 路由传参

6.1 params参数

  • 属于路径中的一部分,在配置路由时需要进行占位,如path:'/search/:id'

6.2 query参数

  • 不属于路径中,不用在路由中进行占位,在路径中会自动展示为 ?key=value&key1=value1 的拼接形式

6.3 路由传参的几种写法

6.3.1 字符串形式

```javascript
// 方法一:通过字符串直接传参
      // params形式
       router.push('/search/'+this.searchValue)
      // query形式
       router.push('/search?key='+this.searchValue)
      // params+query
      router.push('/search/'+this.searchValue+'?key='+this.searchValue.toUpperCase())

6.3.2 模板字符串

router.push(`/search/${this.searchValue}?k=${this.searchValue.toUpperCase()}`)

6.3.3 对象写法(最常用的)

特别注意:路由携带params参数时,若使用的对象写法,则不能使用path配置项,必须使用name配置!

// 通过name命名路由
 {
    name: 'search',
    path: '/search/:keyword',
    component: () => import('@/views/Search'),
    meta: {
      showFooter: true
    }
  }
// 方法三:对象的写法(常用的),要对路由命名(name)
  import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
// 搜索框的数据
const keyword = ref('')
// 搜索按钮的回调函数
const handleSearch = () => {
  router.push({
    name: 'search', //name要和路由中配置的name一致
    params: {
      keyword: keyword.value
    },
    query: {
      key: keyword.value.toUpperCase()
    }
  })
}

6.4 路由传参的对象写法中的常见问题

6.4.1 对象写法中 path 和 params 结合使用会报错

  • 对象写法中如果要用params参数,只能通过name指定跳转路由,不能用path
router.push({
    path: '/search',
    params: {
      keyword: keyword.value
    },
    query: {
      key: keyword.value.toUpperCase()
    }
  })
  • 控制台会抛出警告
    在这里插入图片描述
  • URL路径中也没有正确添加params
    在这里插入图片描述

6.4.2 如何指定params参数可传可不传

  • 如果路由中配置了占位,但是不传params,路由不会进行跳转,并且控制台会报错
router.push({
    name: 'search',
    query: {
      key: keyword.value.toUpperCase()
    }
  })

vue3.2 电商前台项目(二)—— 路由组件和非路由组件_第1张图片

  • 可以在占位时将可选的参数后面加上问号?,则表示该params参数可传可不传
 {
    ...
    path: '/search/:keyword?'
    ...
  }

6.4.3 路由组件传递props(三种写法)

1. 布尔值的写法

 {
    name: 'search',
    path: '/search/:keyword',
    component: () => import('@/views/Search'),
    meta: {
      showFooter: true
    },
    props: true // 传递props
  }
  • 这种写法可以将params作为路由组件的属性,组件中可以通过defineProps接收params参数
  • 这种写法只能接收 params参数
// search / index.vue 
import { defineProps } from 'vue'
// 接收路由组件中的props
const props = defineProps({
  keyword: {
    type: String
  }
})
console.log(props.keyword)

2. 对象写法

  • 可以配置额外的参数
  • 组件中可以通过 defineProps 接收路由中配置的props
 {
    name: 'search',
    path: '/search/:keyword',
    component: () => import('@/views/Search'),
    // 对象写法
    props: {
      name: 'dudu',
      age: 18
    }
  }
// search页面
import { defineProps } from 'vue'
// 接收路由组件中的props
const props = defineProps({
  name: {
    type: String
  },
  age: {
    type: Number
  }
})
console.log(props)

3. 函数写法

  • 可以把 paramsquery 参数传递给路由组件
  • 组件中可以通过 defineProps 接收路由中配置的props
{
    name: 'search',
    path: '/search/:keyword',
    component: () => import('@/views/Search'),
    meta: {
      showFooter: true
    },
    props: route => {
      return {
        keyword: route.params.keyword,
        keyy: route.query.key
      }
    }
  }

你可能感兴趣的:(Vue3,vue.js,javascript,前端)