IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 生命周期、钩子函数、路由 -> 正文阅读

[JavaScript知识库]生命周期、钩子函数、路由

生命周期、钩子函数、路由

提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

提示:以下是本篇文章正文内容,下面案例可供参考

一、生命周期

1、生命周期的基本定义

  • 生命周期的含义

生命周期: Vue是一个构造函数,当执行执行这个函数时,相当于初始化vue实例;
在创建实例过程中,需要设置数据监听,编译模板,将实例挂载到DOM上,数据更新能够让DOM也更新,在这个初始化,又会不同阶段默认调用一些函数执行,这些函数就是生命周期的钩子函数;

2、钩子函数

钩子函数简单介绍
beforeCreate在内存开始创建组件之前,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
created在内存把组件创建完后,在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来
beforeMount在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已,在数据渲染到页面之前
Mounted数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的插件
beforeUpdate表示页面还没有被更新,数据已经被更改了,页面显示的数据还是旧的,没有被改变,而data中的数据是更改后的数据,所以数据不一致。
Update数据变化后,事件执行的时候,页面和data数据已经保持一致了,都是最新的
beforeDestroy实例(组件)被销毁之前调用
Destroyed当执行到destroyed函数的时候,组件已经被完全销毁了,此时,组件中的所有数据,方法、指令过滤器都已经不可用了。

注意

  • 发送Ajax请求时,应在create执行期间发送
  • 操作DOM元素,应在Mounted函数期间操作元素

代码示例

<template>
<div>
 <p>首页</p>
 <span>{{username}}</span>
</div>
</template>

<script>
export default {
name:'Main',
data(){
  return {
    username:'Hello',
  }
},
//该函数被调用在页面数据data还未创建之前,无法打印出页面中的数据
beforeCreate(){
console.log(this.username);
},
//该函数调用,在数据创建好后,此时发送Ajax请求,刚还还未进行数据的渲染
created(){
    console.log(this.username);
  },
//该函数调用,在创建好的数据进行渲染在页面之前,视为初始化数据,不会调用Updated函数
beforeMount(){
  // this.username='你好';
   console.log('初始页面被渲染了')
},
//页面被渲染好后调用该函数,在此之后数据变化,就会调用beforeUpdate函数
mounted(){
  this.username='你好';
  console.log(this.username);
  },
//页面数据改变,但还未渲染,只进行数据的更新
beforeUpdate(){
  console.log('页面数据更新了');
  },
//更新的数据被渲染好后
  updated(){
  console.log('更新的页面数据被渲染了');
  }
}
</script>

<style>

</style>

在这里插入图片描述


二、路由

1.路由的基本概念

  1. 路由的定义?

路由本质上来说就是一种对应关系,比如说我们在浏览器中输入不同的 url 地址,我们就能访问不同的资源,那么这 url 地址与资源之间的对应关系,就是路由。

  1. 路由的分类
  • 后端路由:指请方式、请求地址、与函数function处理函数之间的对应关系
  • 前端路由:前端路由是通过页面 hash 值(锚链接) 的变化实现的不同页面之间的相互切换,本质上是用户事件与事件处理函数之间的对应关系

? 前端路由的核心就是监听事件并分发执行事件处理函数,所以需要依靠 window.onhashchange 事件来监听 hash 值的变化,以及 location.hash 获取目前页面的 hash 值。

  1. SPA
    ? SPA(Single Page Application)单页面应用程序,整个页面只有一个页面,内容的变化通过 ajax 局部更新实现,同时支持浏览器地址栏的前进与后退操作,又称单页面多视图。其实现原理是基于 url 地址的hash变化,hash变化会导致浏览器访问记录的变化,但不会触发新的url请求。SPA最核心的技术点就是前端路由。

代码示例:

<template>
  <div id="app">
    <a href="#/main">首页</a> 
    <br>
    <a href="#/movie">电影</a>
    <component :is="comName"></component>
  </div>
</template>

<script>
import Main from './components/main.vue'
import Movie from './components/movie.vue'
export default {
  name: 'App',
  components: {
    Main,Movie,
  },
  data(){
    return {
      comName:'',
    }
  },
  created(){
    window.onhashchange=()=>{
      switch(location.hash){
        case'#/main':
          this.comName='Main';
          break;
        case'#/movie':
           this.comName='Movie';
           break;
      }
    }
  }
}
</script>

<style>
</style>

2、vue-router

1、vue-router的基本使用

  1. vue-router的含义
    vue-router是vue.js官方给出的路由解决方案,他只能结合vue项目进行使用,能够轻松管理SPA项目中的组件切换
  2. vue-router的使用

点击此链接查看安装步骤
代码示例:
index.js
在这里插入图片描述
main.js
在这里插入图片描述
App.vue
在这里插入图片描述

2、路由重定向

在用户访问某个地址A时,强制用户跳转到地址 B,并展示相关内容。想要实现重定向,需要使用路由规则的 redirect 属性。我们一般通过路由重定向为页面设置默认展示的组件。

<script>
const router  = new VueRouter({
    routes:[
        {path:'/',redirect:'/page1'},
        {path:'/page1',component:Main},
        {path:'/movie',component:Movie}
    ],
})
</script>

在这里插入图片描述

3、嵌套路由

? 路由嵌套是指:当我们点击父级路由链接,在路由占位符显示的组件内容中有子级路由链接,点击子级路由链接时,在子级路由占位符显示子级组件内容。子级路由规则,由父级路由的 children 属性来配置。

  1. 首先在嵌套组件中的负组件中声明子路由链接和子路由占位符
<template>
  <div>
    <p>欢迎大家的到来</p>
    <span class="bottom">
    <router-link to='/page1/1'>电视剧</router-link>
    <router-link to='/page1/2'>电影</router-link>
    <router-view></router-view>
    </span>
    
  </div>
</template>

<script>
export default {
name:'Main'
}
</script>

<style>
.bottom{
    width: 300px;
    height: 100px;
    display: block;
    background-color: rgb(198, 236, 185);
}
</style>
  1. 然后通过children属性声明子路由规则(数组的形式),并在index.js的文件中导入所需要的子组件,并用children声明规则
import Vue from 'vue'
import VueRouter  from 'vue-router'

import Main from '../components/page1.vue'
import Movie from '../components/movie.vue'
import Paper1 from '../components/paper1.vue'
import Paper2 from '../components/paper2.vue'

Vue.use(VueRouter)

const router  = new VueRouter({
    routes:[
        {path:'/',redirect:'/page1'},
        {path:'/page1',component:Main,children:[
            {path:'/page1',component:Paper1},
            {path:'/page1/1',component:Paper1},
            {path:'/page1/2',component:Paper2}
        ]},
        {path:'/movie',component:Movie}
    ],
})
export default  router

在这里插入图片描述
补充:

在嵌套路由中,子路由和父路由之间如何传值?

①、虽然是通过路由嵌套的方式展示的页面,当其形式还是相当于父子组件的的关系,所以我们可以通过父子组件传值的方式来传值,只不过是将router-view视为子组件在父组件中的载体,
使用this.$emit来传参

②、父路由也可以给子路由传递数据,用props

互相调用参数

①、子路调用父路中的参数,用this. $emit ,或直接使用this. $parent来进行调用

②、父路调用子路可直接使用this.$ref来进行调用

4、动态路由匹配参数(路由传参)

  1. this.route.$params.参数
    设置路由规则时,在路径path里,通过 /:参数 的形式,设置参数。然后在组件中通过 {{ $route.params.参数 }} 的形式,获取参数。该方法耦合度高,不够灵活,很少使用。
<template>
  <div>
    <p>电影</p>
    <p>{{$route.params.id}}</p>
  </div>
</template>
const router  = new VueRouter({
    routes:[
        {path:'/',redirect:'/page1'},
        {path:'/page1',component:Main,children:[
            {path:'/page1',component:Paper1},
            {path:'/page1/:id',component:Movie},
            {path:'/page1/:id',component:Movie}
        ]},
        {path:'/movie',component:Movie}
    ],
})
  1. 使用props
  • props 的值为 true
    在路由规则中,将props的值设置为 true,使 $route.params 成为组件属性。在路径path里,通过 /:参数 的形式,设置参数,然后在组件中,使用 props 接收参数即可。
// 使用 props['参数'] 来接收参数
const User = {
	props: ['id'],
	template: '<h1>User 组件 -- 用户id为: {{id}}</h1>'
}
// 创建路由实例对象
const router = new VueRouter({
	// 所有的路由规则
	routes: [
          { path: '/', redirect: '/user'},
          { path: '/user/:id', component: User, props: true },
        ]
      })
  • props的值为对象
    ? 我们将props 的值设置为一个对象,就相当于将对象中的所有属性传递给组件,组件使用 props[‘属性名1’,‘属性名2’] ,即可接收数据
const User = {
    // 接收对象中的数据,但id接收不到,因为传递的对象中没有这个属性
	props: ['id', 'uname', 'age'],
	template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}
// 创建路由实例对象
const router = new VueRouter({
	// 所有的路由规则
	routes: [
          { path: '/', redirect: '/user'},
         // 传递的是静态对象
          { path: '/user/:id', component: User, props: { uname: 'lisi', age: 20 } }
        ]
      })

在这里插入图片描述

  • props的值为函数
    ? 如果既想获取路径传递的参数值,又想获取传递的对象数据,那么props应该设置为函数形式。
// 组件
const User = {
	props: ['id', 'uname', 'age'],
	template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}
     // 创建路由实例对象
      const router = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user' },
          {
            // 路径传递的参数
            path: '/user/:id',
            component: User,
            // 以函数的形式 传递数据到组件
            props: route => ({ uname: 'zs', age: 20, id: route.params.id })
          },
          { path: '/register', component: Register }
        ]
      })

在这里插入图片描述

5、命名路由(?嵌套的路由中能否使用命名路由)

? 为了更加方便的表示路由的路径,我们可以给路由规则起一个别名,即为命名路由。

<!-- to属性动态绑定一个对象  name属性 表示要绑定的路由规则  params 表示要传递的参数 参数名必须与路由规则定义的相同 -->
<router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
<!-- <router-link to="/user/3">User3</router-link> -->
<script>
    // 声明组件
      const User = {
        props: ['id', 'uname', 'age'],
        template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
      }
      
      // 创建路由实例对象
      const router = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user' },
          {
            // 命名路由
            name: 'user',
            path: '/user/:id',
            component: User,
            props: route => ({ uname: 'zs', age: 20, id: route.params.id })
          }
        ]
      })
</script>

6、编程式导航

? 页面导航分为两种方式:声明式导航和编程式导航。通过点击链接实现导航的方式,叫做声明式导航,比如:网页中的 a 超连接 或者 vue router 里面的 标签。通过调用 JavaScript 形式的API实现导航的方式,叫做编程式导航,比如:网页中的location.href 。

vue Router 中常用的编程式导航 API 有:

  • this.$router.push()
    ? 该API的参数形式有很多:

? ① 路径字符串,例如:this.$router.push(‘/user’)。

? ② 路径对象,例如:this.$router.push({path: ‘/user’})。

? ③ 命名路由对象,例如:this.$router.push({name: ‘/user’})

? ④ 带查询参数,变成 /user?uname=lisi的形式,例如:this.$router.push({ path: ‘/user’,query: { uname } })

  • this.$ router.replace()
    ? 该API与this.$router.push() 作用基本相同。只不过它在跳转到指定 hash 地址,不会增加新的历史记录,只会替换掉当前的历史记录。

  • this.$router.go(n)
    ? 该 API 参数是数字,数字的大小表示浏览器历史中前进或后退的页数,可以为负值,负值代表后退,正值代表前进

<template>
  <div>
    <p>电影</p>
    <button @click="handleclick()">点击跳转</button>
  </div>
</template>

<script>
export default {
name:'Movie',
methods:{
handleclick(){
    this.$router.push({path:'/number1'});
}
}
}
</script>
<style>
</style>

7、导航守卫

导航守卫是用来控制路由的访问权限,比如可以结合token 检查用户是否登录,当未登录的用户想要访问某些页面时,通过路由导航将其跳转到登录页面。vue-router 的导航守卫有全局前置守卫、全局解析守卫、路由独享的守卫等等等

  1. ① 全局前置守卫:
    ? 当给项目设置了全局前置守卫之后,在每次发生路由的导航跳转时,都会触发。所以开发者可以在全局前置守卫中,对路由的访问权限进行控制。
// 创建路由实例对象
const router = new VueRouter({....})

// 设置全局前置守卫
router.beforeEach((to,from,next) => {
    // to 是将要访问的路由对象,包含路由地址等相关信息。
    // from 是将要离开的路由对象,包含路由地址等相关信息。
    // next 是一个内置函数,调用 next() 表示允许通过,
    // next('路由地址') 表示强制跳转到某个页面
    // next(false) 表示不允许跳转
})

基本使用

// 创建路由实例对象
const router = new VueRouter({....})

// 需要权限才能访问的页面路由地址,以数组的形式
const pathArr = ['/home', '/home/users', '/home/rights']

// 设置全局前置守卫
router.beforeEach(function(to, from, next) {
  // to将要访问的路由的地址 是否需要权限
  if (pathArr.indexOf(to.path) !== -1) {
    // 验证权限
    const token = localStorage.getItem('token')
    // 根据结果不同 进行不同的操作
    if (token) {
      next()
    } else {
      next('/login')
    }
  } else {
    next()
  }
})

  • ② 组件内的守卫钩子函数
    组件内的守卫钩子函数是指写在某一页面组件内的钩子函数,只有当页面的路由变化与该组件相关时才会调用执行。一同提供了三种钩子函数,适用于各种不同的场景:
    beforeRouteEnter(to,from,next)
    该守卫钩子函数是在要跳转该组件对应的路由(或该组件对应路由的子路由)并且在该组件渲染之前调用执行的。第一个参数 to表示要跳转到的路由信息对象,常用属性为 to.path 可以获取到要跳转到的路由地址。第二个参数from表示要跳转离开的路由信息对象。因为该守卫函数执行时,组件实例还没有被创建,所以不能获取组件的this ,也就是无法获取或改变组件中的数据,但我们可以通过给第三个参数 next传递一个回调函数,该函数的参数就是组件实例,通过这种方式来操作组件中的数据:
// 守卫钩子函数1
beforeRouteEnter (to, from, next) {
  next((vm) => {
    // 通过 vm 访问组件实例
    console.log(vm.a); // 1
  })
},
data() {
  return {
	a: 1
  }
}

beforeRouteUpdate(to,from):
该守卫钩子函数是在当前路由发生了改变但该组件被复用时调用执行,经过我的实验,只有在动态路由这一种情况下,该方法才会被执行,举例来说就是:如果一个路由地址定义为:/course/:id,当路由地址从/course/1跳转到 /course/2时,该守卫钩子函数才会被执行。函数的两个参数与beforeRouteEnter(to,from)意义相同,但此时组件实例已经创建好了,所以在该守卫钩子函数里面可以操作组件中的数据:

// 守卫钩子函数2
beforeRouteUpdate(to,from){
  // 通过this访问组件实例
  console.log(this.a); // 1
},
data() {
return {
  a: 1
}
}

beforeRouteLeave(to,from):
该守卫钩子函数是在跳转离开该组件时调用执行,也可以直接操作组件中的数据。函数的两个参数与beforeRouteEnter(to,from)意义相同,这个守卫钩子函数通常用来预防用户在还未保存修改前突然离开的情况,可以通过return false 来取消路由跳转,让页面不变:

// 守卫钩子函数3
beforeRouteUpdate(to,from){
  // 提示用户有未保存的内容,是否要离开
  const answer = window.confirm('你还有未保存的内容,是否要离开本页面?')
  // 如果不离开 则取消路由跳转
  if (!answer) return false
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:46:33  更:2022-10-31 11:50:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 15:32:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码