• 前端面试题整理(2.0)


    Watch与计算属性的选择

    在某些情况下,watch和计算属性可以达到相同的效果。如果需要在数据变化时执行异步操作或有副作用时,应该使用watch。而如果进需要根据数据进行简单的变换和计算,则更适合使用计算属性。

    什么是路由:前端路由指的是一种将浏览器URL与特定页面或视图关联起来的技术。在传统的Web开发中,当用户点击链接或输入URL时,服务器会接收到请求并返回相应的HTML页面。而在前端路由中,当用户点击链接或者输入url时,浏览器会根据路由规则对URL进行解析,并使用JavaScript控制夜间的展示。

    前端路由通常使用JavaScript库来实现,比如React Router、Vue Router等。他们允许开发者定义路由规则,并根据这些规则来显示不同的组件或页面。例如,当用户点击一个链接时,前端路由会将URL解析为一个路由路径,然后根据路径匹配相应的组件或者页面并显示在页面上,而不需要向服务器发起请求。

    前端路由可以提高Web应用的性能和用户体验,因为它允许应用实现快速的页面切换和动态的内容加载,同时减少了服务器的负载。

    路由模式

    ①hash模式

    使用URL的hash来模拟一个完整的URL,当URL改变时,页面不会重新加载,其显示的网络路径中会有“#”号。比如http://example.com/#/about。这是最安全的模式,因为它兼容所有的浏览器和服务器。

    ②history模式

    依赖于HTML5的history,pushState API,所以要担心IE9以及以下版本,目前不同担心。并且还包括back、forward、go三个方法,对应浏览器的前进,后退,跳转操作。就是浏览器左上角的前进、后退等按钮进行的操作。

    使用:

    1. 在src下创建Router目录,并在目录里创建index.js文件

    导入:{createRouter,createWebHashHistory} from ‘vue-router’

    //使用createRouter创建路由实例

    Const router =createRouter({

    //确定路由模式,当前使用hash模式

    History:createWebHashHistory(),

    //定义路由表

    Routers:[

    {

    //路由地址

    Path:”/a”,

    //对应路由显示组件

    Component:()=> import (‘./../a.vue’)

    }

    ]

    })

    //导出

    Export default router

    1. 在入口文件引入,并挂载

    Import App from ‘./App.vue’

    Const app=createApp(App)

    //使用use方法挂载到Vue上

    app.use(router)

    app.mount(‘#app’)

    1. 在App.vue文件中使用router-view展示路由

    页面中实现路由跳转

    1. 普通跳转

    使用push方法

    具体使用方式:this.$router.push(‘/b’)

    1. 替换当前页面

    使用replace方法

    使用方式:this.$router.replace(‘/b’)

    注意:使用this.$router对象里的replace方法,接收一个路由地址作为参数,

    从a页面替换到b页面,不会在历史记录中新增数据。

    1. 前进或后退到浏览器历史记录中的特定页面

    使用go方法

    使用方式:this.$router.go(-1) //正数为前进几页,负数为回退几页,常用的是-1,回退一页。

    路由传参

    1. params传参

    需要在路由表中定义,参数使用/进行拼接,定义后默认为必传参数

    定义:跳转到b页面需要携带id和name两个参数

    则在路由表中定义:{path:”/b/:id/:name”}

    在路由表中定义完成后,在跳转之前的组件中进行定义

    This.$router.push({

    Name:’b’,

    //要传递的参数,会自动拼接在url上

    Params:{

    name:’张三’,

    id:1

    }})

    然后可以在B页面接收参数:

    Created(){

    //使用$route的params对象接收

    Console.log(this.$route.params)

    }

    1. query传参

    参数使用?进行拼接,参数之间用&隔开,不需要在路由表中定义

    在跳转之前的组件中进行定义:

    //使用?进行拼接参数之间用&隔开

    //类似于get请求参数

    第一种方式:this.$router.push(‘/b?id=1&name=张三’)

    //如果参数非常多也可以直接传入一个query对象,采用第二种方式

    This.$router.push({

    //路由路径

    Path:’/b’,

    //要传的参数会自动拼接在url上

    query:{

    name:’张三’,

    id:1

    }

    })

    接收参数:{created(){console.log(this.$route.query)}}

    嵌套路由

    点击顶栏导航按钮。页面跳转,导航栏保持不变,页面改变。

    比如说在路由地址a下面有两个子路由a1和a2

    那么需要在children定义当前路由下的子路由,

    Children是一个数组,写法和上面几乎一致

    children:[{

    path:”/a1”,

    Component:()=>import(“./../a1.vue”),},

    {

    Path:”/a2”,

    Component:()=>import(“./../a2.vue”)

    }]

    在A页面中展示对应子路由(在a页面使用router-view展示对应子路由,使用router-link进行跳转)

    路由守卫

    概念:提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的,单个路由独享的,或者组件级的。简单理解:导航守卫就是路由跳转过程中的一些钩子函数,再直白点路由跳转是一个大的过程,这个大的过程分为跳转前中后等细小的过程,在每一个过程中都有一个函数,这个函数能让你操作一些其他的事的时机,比如跳转前是否验证登录,这就是导航守卫。

    全局守卫

    指路由实例上直接操作的钩子函数,它的特点是所有路由配置的组件都会触发,直白点就是触发路由就会触发这些钩子函数。钩子函数的执行顺序包括beforeEach、beforeResolve、afterEach三个。

    ①beforeEach

    在路由跳转前触发,参数包括to,from,next三个,这个钩子函数的主要用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚。

    router.beforeEach((to,from,next)=>{

    //to 将要访问的路径

    //from 代表从哪个路径跳转而来

    //next是一个函数,表示放行,使用beforeEach必须调用next

    //next()放行  next(‘/login’)强制跳转})

    ②beforeResolve

    这个钩子和beforeEach类似,也是路由跳转前触发,参数也是to,from,next三个,和beforeEach区别官方解释为:区别是在导航被确定之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

    在beforeEach和组件内beforeRouterEnter之后,afterEach之前调用。

    ③afterEach

    和beforeEach相反,他是在路由跳转完成后触发,参数包括to,from没有next,他发生在beforeEach和beforeResolve之后。

    BeforeEnter单个路由独享

    beforeEnter在路由配置中定义的钩子函数,它会在路由被激活之前调用。它和全局前置守卫的参数一样,但是只对该路由生效。

    组件内守卫

    指在组件内执行的钩子函数,类似于组件内的生命周期,相当于为配置路由的组件添加的生命周期钩子函数。钩子函数按执行顺序包括beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave三个。

    ①beforeRouteEnter

    路由进入之前调用,参数包括to,from,next。该钩子在全局守卫beforeEach和独享守卫beforeEnter之后,全局beforeEnter之后,全局beforeResolve和全局afterEach之前调用,要注意的是该守卫内访问不到组件的实例,也就是this为undefined,也就是他在beforeCreate生命周期前触发。在这个钩子函数中,可以通过传一个回调给next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数,可以在这个守卫中请求服务端获取数据,当成功获取并能进入路由时,调用next并在回调中通过vm访问组件实例进行赋值等操作,(next中函数的调用在mounted之后:为了确保能对组件实例的完整访问)

    BeforeRouteEnter(to,from,next){

    //这里还无法访问到组件实例,this===undefined

    Next(vm=>{

    //通过’vm’访问组件实例

    })

    }

    ②beforeRouteUpdate

    在当前路由改变时,并且该组件被复用时调用,可以通过this访问实例。参数包括to,from,next。

    对于一个带有动态参数的路径/foo/:id,在/foo/1和/foo/2之间跳转的时候,组件实例会被复用,该守卫会被调用,当前路由query变更时,该守卫会被调用。

    ③beforeRouteLeave

    导航离开该组件的对应路由时调用,可以访问组件实例this,参数包括to,from,next。只有调用next才可以跳转

    路由懒加载

    在打包构建应用时,JavaScript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

    // 将

    // import UserDetails from './views/UserDetails.vue'

    // 替换成

    const UserDetails = () => import('./views/UserDetails.vue')

    生命周期

    概念

    Vue生命周期可以简单分为四个阶段:创建阶段,挂载阶段,更新阶段,销毁阶段。

    每个Vue实例在被创建时要经过一系列的初始化过程--例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。

    ①创建阶段

    BeforeCreate():在组件实例创建之前调用,此时组件的数据观测、事件监听和模板编译尚未开始,因此无法访问到组件的响应式数据、计算属性、方法等。

    Created()

    在组件实例创建之后调用,此时组件的数据观测、事件监听和模板编译已经完成,可以访问到组件的响应式数据、计算属性、方法等,但是还没有挂载到DOM上,因此无法访问到组件的元素或子组件。常用于发送网络请求。

    ②挂载阶段

    beforeMount():在组件挂载到DOM之前调用,此时组件的虚拟DOM已经创建,但是还没有插入到父容器中,可以对虚拟DOM进行一些操作或修改。

    Mounted():在组件挂载到DOM之后调用,此时组件的虚拟DOM已经插入到父容器中,并且生成了真实的DOM节点,可以访问到组件的元素或子组件,并且可以执行一些需要DOM的操作。

    ③更新阶段

    BeforeUpdate():在组件更新之前调用,此时组件的数据已经发生变化,但是还没有更新到DOM上,可以在这个钩子中获取更新前的状态,并进行一些比较或逻辑处理。

    Updated():在组件更新之后调用,此时组件数据已经更新到DOM上,并且完成了重新渲染,可以在这个钩子中获取更新后的状态,并进行一些后续操作或效果处理。不能在这个生命周期里做响应式操作,否则会死循环。

    ④卸载阶段

    beforeUnmount():在组件卸载之前调用,此时组件还处于可用状态,可以在这个钩子中执行一些清理操作,如移除事件监听器、取消网络请求、停止定时器等。

    Unmounted():在组件卸载之后调用,此时组件已经从DOM中移除,并且停止了所有的响应式效果和事件监听,无法再访问到组件的任何属性或方法。

  • 相关阅读:
    [数据结构]栈和队列面试题解析
    [100天算法】-连通网络的操作次数(day 46)
    用HTML+CSS做一个学生抗疫感动专题网页设计作业网页
    《DevOps实践指南》- 读书笔记(五)
    企业信息系统应急响应预案
    刘馨蔓:“她是行走的发光体”|OneFlow U
    LeetCode——动态规划篇(一)
    Metrics-Server总结
    QT串口调试助手V2.0(源码全开源)--上位机+多通道波形显示+数据保存(优化波形显示控件)
    案例 | 3D可视化工具HOOPS助力SolidWorks edrawings成功引入AR/VR技术
  • 原文地址:https://blog.csdn.net/mez_Blog/article/details/134008590