Vue组件与路由精通指南:深入解析组件化开发与路由管理

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Vue组件和路由详解:组件是应用的基石,用于封装可重用代码,可扩展HTML元素。动态组件根据需求切换。父子组件间通过props单向数据流通信,子组件使用`emitVueRouterrouter.push.replace.goroute`对象包含`path`、`params`、`query`等信息。路由钩子如`beforeEach`允许在导航发生时执行逻辑。

@TOC


前言

    本文将深入探讨 Vue 组件的精髓,从组件的定义、动态组件的使用、父子组件的交互与传参等方面展开,帮助读者深入理解 Vue 组件化的设计理念与实现方法。此外,我们还将详细介绍 Vue 路由的常见操作,包括 router.pushrouter.replacerouter.go 等方法的使用,以及路由对象属性 $route.path$route.params$route.query$route.fullPath的含义与应用。


一、Vue组件

1. 组件的定义

组件系统Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树 :
在这里插入图片描述

功能组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。

  • 在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能
  • 在有些情况下,组件也可以表现为用 is 特性进行了扩展的原生 HTML 元素
  • 所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子

2. 动态组件的使用

组件名应该始终是多个单词的,根组件 App 除外
    这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的单文件组件的文件名应该要么始终是单词大写开头 (PascalCase),要么始终是 (kebab-case)混用文件命名方式,有的时候会导致大小写不敏感的文件系统的问题,这也是横线连接命名同样完全可取的原因。

使用 kebab-case:
当使用 kebab-case (短横线分隔命名)定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

Vue.component('my-component-name', {
    
     /* ... */ })
AI 代码解读

使用 PascalCase:
当使用 PascalCase (驼峰式命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的.

Vue.component('MyComponentName', {
    
     /* ... */ })
AI 代码解读

组件注册:

//在要展示的页面 导入组件,并注册
     <script>
        import my_comp from './my-comp'

        export default {
    
    
            data(){
    
    
                return{
    
    
                }
            },
            components:{
    
    
                'Mycomp': my_comp
            }
        }
      </script>

      // 在要展示的地方加入下面这行代码
         <Mycopm></Mycopm>
AI 代码解读

3. 父子组件

父子组件使用

    在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同。最常见的就是父组件为控制组件,子组件为视图组件。父组件传递数据给子组件使用,遇到业务逻辑操作时子组件触发父组件的自定义事件

父组件到子组件通讯
   父组件到子组件的通讯主要为:子组件接受使用父组件的数据,这里的数据包括属性和方法(String, Number, Boolean, Object, Array, Function)。vue提倡单项数据流,因此在通常情况下都是==父组件传递数据给子组件使用,子组件触发父组件的事件,并传递给父组件所需要的参数==

父子组件传参

通过 [props]传递数据 (推荐)

    父子通讯中最常见的数据传递方式 就是通过props传递数据,就像方法的传参一样,父组件调用子组件并传入数据,子组件接受到父组件传递的数据进行验证,使用props (可以是数组或对象)用于接收来自父组件的数据。
ps:props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值

<!-- 父组件 -->
<template>
    <div>
        <my-child :parentMessage="parentMessage"></my-child>
    </div>
</template>

<script>
    import MyChild from '@components/common/MyChild'

    export default {
    
    
        components: {
    
    
            MyChild
        },
        data() {
    
    
            return {
    
    
                parentMessage: "我是来自父组件的消息"
            }
        }
    }
</script>
AI 代码解读
<!-- 子组件 -->
<template>
    <div>
        <span>{
  
  { parentMessage }}</span>
    </div>
</template>

<script>
    export default {
    
    
        props: {
    
    
            parentMessage: {
    
    
                type: String,
                default: '默认显示的信息'
                // require: true // 必填
            }
        }
    }
</script>
AI 代码解读

子父组件传参
    通过 $emit 传递父组件数据 与父组件到子组件通讯中的$on配套使用,可以向父组件中触发的方法传递参数供父组件使用。

<!-- 父组件:一旦触发子组件时,事件child-event就调用parentEvent打印data -->
<template>
  <div>
    <!-- 子组件传递数据给父组件 -->
    <my-child @child-event="parentEvent"></my-child>
  </div>
</template>

<script>
import myChild from "./MyChild.vue";

export default {
    
    
  name: "ParentEl",
  data() {
    
    
    return {
    
    
      msg: "我是父元素的组件",
    };
  },
  components: {
    
    
    myChild,
  },
  methods: {
    
    
    // 父组件方法, data是子组件传递的数据
    parentEvent(data) {
    
    
      console.log(data);
    },
  },
};
</script>
<style lang="scss" scoped></style>
AI 代码解读
<!-- 子组件:一旦点击按钮,就调用toParent函数,toParent函数发送事件child-event并传递数据"我是子组件传递给父组件的"给父组件 -->
<template>
  <div>
    <!---触发事件给父组件传值 -->
    <button @click="toParent">点击实现传值给父组件</button>
  </div>
</template>

<script>
export default {
   
   
  name: "myChild",
  methods: {
   
   
    toParent() {
   
   
      // 使用$emit传值,this.$emit(事件, 数据)
      // 子组件通过$emit发送一个事件给父组件 (click,change)
      // $emit(参数1, 参数2); 参数1:发送的事件名  参数2:发送的数据
      this.$emit("child-event", "我是子组件传递给父组件的"); 
    },
  },
};
</script>
<style lang="scss" scoped></style>
AI 代码解读

二、Vue路由

1. 常见路由操作

<router-link>组件支持用户在具有路由功能的应用中单击导航。

  • 通过to属性可以指定目标地址,默认渲染成带有正确链接的<a>标签,通过配置tag属性可以生成别的标签。
  • 另外,当目标路由成功激活时,链接元素会自动设置一个表示激活的css类名。
 <!-- 直接给to指定属性值, 不提倡使用,尽量使用属性绑定 -->
 <router-link to='/goods'>商品</router-link>

 <!-- 使用v-bind 绑定 JS表达式-->
 <router-link :to="'/goods'">商品</router-link>

 <!-- 绑定data中的变量path -->
 <router-link :to='path'>商品</router-link>

 <!-- 绑定对象,自定义网址,携带查询参数 ==> /goods?id=1 -->
 <router-link :to="{
    
    'path':'/goods', query:{
    
    'id':1}}">商品</router-link>

 <!-- 绑定 对象,命名路由,携带params参数 ==> /goods/1 -->
 <router-link :to="{name:'goods', params:{
    
    'id':1}}">商品</router-link>
AI 代码解读

router.push

routerVueRouter的一个对象,通过Vue.use(VueRouter)VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由,包含了许多关键的对象和属性。

router.push(location): 要导航到不同的URL,则使用router.push方法。该方法会向history栈添加一个新的记录,当用户单击浏览器的后退按钮时,回到之前的URL。
```js
router.push('/goods') // 字符串
router.push({path: '/goods'}) // 对象

// 自定义网址,携带查询参数
router.push({ path: "/goods", query: { id: 1 } }) // -> /goods?id=1

// 命名路由,携带params参数(废弃,详情查看官网)
router.push({ name: "goods", params: { id: 1 } }) // -> /goods/1


### router.replace
>`router.replace(location)`: ***`router.replace`与`router.push`很像,唯一的不同是它不会向`history`栈添加新记录,而是跟它的方法名一样只替换掉当前的history 记录。***`router.replace(...)`等价于`<router-link :to="..." replace>`。
```js
  router.replace('/goods') // 字符串
  router.replace({path: '/goods'}) // 对象

  // 自定义网址,携带查询参数
  router.replace({ path: "/goods", query: { id: 1 } }) // -> /goods?id=1

  // 命名路由,携带params参数(废弃)
  router.replace({ name: "goods", params: { id: 1 } }) // -> /goods/1
AI 代码解读

router.go

router.go(n): 参数是一个整数,表示在history记录中向前进多少步或向后退多少步

  // 在浏览器记录中前进一步,等同于history.forward()
  router.go(1)
  // 后退一步,等同于history.back()
  router.go(-1)
  // 前进三步
  router.go(3)
  // 如果history记录不够,就会失败
  router.go(-100)
  router.go(100)
AI 代码解读

2. 路由对象属性

route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query

$route.path

$route.path: 字符串,对应当前路由的路径,总是解析为绝对路径,如"/goods"

var current_url = this.$route.path
console.log(current_url)
AI 代码解读

$route.params

$route.params: 一个key/value对象, 包含了动态片段和全匹配片段,如果没有路由参数,就为空对象。

var params = this.$route.params
console.log(params)
AI 代码解读

$route.query

$route.query: 一个key/value对象, 表示URL查询参数。
例如: 对于路径/goods?cate_id=1,则有$route.query.cate_id == 1;如果没有查询参数,则为空对象

var query = this.$route.query
console.log(query)
AI 代码解读

$route.fullPath

$route.ful1Path: 完成解析后的URL,包含查询参数和hash的完整路径。

var ful1Path = this.$route.ful1Path
console.log(ful1Path)
AI 代码解读

3. 路由钩子

路由钩子的介绍和案例讲解

全局路由钩子:router.beforeEach 注册一个全局前置守卫

我们可以直接在路由配置文件(/src/main.js)中写钩子函数,但是在路由文件中我们只能写一个。

router.beforeEach((to, from, next) => {
   
   
    //会在任意路由跳转前执行,next一定要记着执行,不然路由不能跳转了
  console.log('beforeEach')
  console.log(to,from)
  //
  next()
})
//
router.afterEach((to, from) => {
   
   
    //会在任意路由跳转后执行
  console.log('afterEach')
})
AI 代码解读

上述代码中的三个参数:

  • to:路由将要跳转的路径信息,信息是包含在对像里边的。
  • from:路径跳转前的路径信息,也是一个对象的形式。
  • next:路由的控制参数,常用的有next(true)next(false)

写在模板中的钩子函数

在配置文件中的钩子函数,只有一个钩子-beforeEnter,如果我们写在模板中就可以有两个钩子函数可以使用:

  • beforeRouteEnter:在路由进入前的钩子函数。
  • beforeRouteLeave:在路由离开前的钩子函数。
<script>
export default {
   
   
  name: 'params',
  data () {
   
   
    return {
   
   
      msg: 'params page'
    }
  },
  beforeRouteEnter:(to,from,next)=>{
   
   
    console.log("准备进入路由模板");
    next();
  },
  beforeRouteLeave: (to, from, next) => {
   
   
    console.log("准备离开路由模板");
    next();
  }
}
</script>
AI 代码解读

    这是我们写在params.vue模板里的路由钩子函数。它可以监控到路由的进入和路由的离开,也可以轻易的读出to和from的值。


目录
打赏
0
2
2
1
38
分享
相关文章
React 步骤条组件 Stepper 深入解析与常见问题
步骤条组件是构建多步骤表单或流程时的有力工具,帮助用户了解进度并导航。本文介绍了在React中实现简单步骤条的方法,包括基本结构、状态管理、样式处理及常见问题解决策略,如状态管理库的使用、自定义Hook的提取和CSS Modules的应用,以确保组件的健壮性和可维护性。
71 17
提升开发效率:看板方法的全面解析
随着软件开发复杂度提升,并行开发模式下面临资源分配不均、信息传递延迟及缺乏全局视图等瓶颈问题。看板工具通过任务状态实时可视化、流量效率监控和任务依赖管理,帮助团队直观展示和解决这些瓶颈。未来,结合AI预测和自动化优化,看板工具将更高效地支持并行开发,成为驱动协作与创新的核心支柱。
淘宝APP分类API接口:开发、运用与收益全解析
淘宝APP作为国内领先的购物平台,拥有丰富的商品资源和庞大的用户群体。分类API接口是实现商品分类管理、查询及个性化推荐的关键工具。通过开发和使用该接口,商家可以构建分类树、进行商品查询与搜索、提供个性化推荐,从而提高销售额、增加商品曝光、提升用户体验并降低运营成本。此外,它还能帮助拓展业务范围,满足用户的多样化需求,推动电商业务的发展和创新。
44 5
React 文本区域组件 Textarea:深入解析与优化
本文介绍了 React 中 Textarea 组件的基础用法、常见问题及优化方法,包括状态绑定、初始值设置、样式自定义、性能优化和跨浏览器兼容性处理,并提供了代码案例。
73 8
探索移动应用与系统:从开发到操作系统的深度解析
在数字化时代的浪潮中,移动应用和操作系统成为了我们日常生活的重要组成部分。本文将深入探讨移动应用的开发流程、关键技术和最佳实践,同时分析移动操作系统的核心功能、架构和安全性。通过实际案例和代码示例,我们将揭示如何构建高效、安全且用户友好的移动应用,并理解不同操作系统之间的差异及其对应用开发的影响。无论你是开发者还是对移动技术感兴趣的读者,这篇文章都将为你提供宝贵的见解和知识。
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
在数字化时代,利用DNS实现地理位置路由成为提升用户体验的有效策略
在数字化时代,利用DNS实现地理位置路由成为提升用户体验的有效策略。通过解析用户请求的来源IP地址,DNS服务器可判断其地理位置,并返回最近或最合适的服务器IP,从而优化网络路由,减少延迟,提高访问速度。示例代码展示了如何基于IP地址判断地理位置并分配相应服务器IP,实际应用中需结合专业地理数据库和动态调整机制,以应对复杂网络环境带来的挑战。
45 6
如何开发一个网站:全面解析与实战指南
在数字化时代,网站是企业和个人展示形象、传播信息的关键平台。本文提供从规划、设计、开发、上线到后期维护的全方位网站开发指南,涵盖明确目标、分析用户、设定功能需求、设计风格、技术选型、测试部署及优化升级等内容,帮助你打造既美观又实用的网站。
128 4
移动应用与系统:从开发到优化的全面解析####
本文深入探讨了移动应用开发的全过程,从最初的构思到最终的发布,并详细阐述了移动操作系统对应用性能和用户体验的影响。通过分析当前主流移动操作系统的特性及差异,本文旨在为开发者提供一套全面的开发与优化指南,确保应用在不同平台上均能实现最佳表现。 ####
44 0

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等