前端面试题--vue篇(持续更新中)

1.★★动态路由如何动态获取参数,如何获取?
vue 复制代码
第一种方式: 存:在声明路由路径的时候存入要存放的参数名称
           {
            path:'/News/:id',
            component: News,
           },
            取:在<router-link to=" "></router-link>,在to的位置存放要存放的参数
               格式为/News/6
           <router-link to="/News/6">新闻</router-link>

第二种方式:使用query存储的方式:
           存: <router-link to="{
            path: /News/,
            query:{
                id:10
            }
           }"></router-link>

           取:在News的mounted中取:this.$route.query.id
           特点:1.参数和值都在地址栏体现
                2.刷新值不会丢失

第三种方式:params传参 vue-router4.x已经废弃
            特点:1.必须通过name跳转 否则参数无法传递
                   2.隐式传参 地址栏不体现
                   3.刷新数据丢失
                
2.v-show和v-if的区别
绑定布尔值  true是显示 , false是隐藏
当值为true的时候,v-show和v-if在显示视觉上是没有区别的
当值为false的时候,v-show控制的是display:none属性,v-if直接在节点移除这个元素(Dom树重构)

性价比:状态切换时 v-show性能更高

使用场景:
v-if的使用场景:适用于初始不渲染(结构复杂,切换不频繁)的场景
v-show用于经常切换的页面 ,如tab栏切换
3.vue中如何监听动态路由参数变化
vue 复制代码
第一种方法使用watch监听:
watch:{
	$route(to,from ){
	conslon.log(to,'to发生变化')
	}}

第二种方法使用beforeRouterUpdate:
beforeRouterUpdate(){
conslon.log(to,'to发生变化')
}
4.★组件通信的方式有哪些?
vue 复制代码
组件之间相互通信,传递数据
第一种父向子 : 父亲通过自定标签的自定义属性, 儿子用props:[ ]接收
第二种子向父: 在儿子触发自定义事件 this.$emit('要监听的事件',this.msg(这个参数可以省略))
	      在父亲标签添加监听事件<zhang-san @要监听的事件(和上面的事件一模一样)="fn"/>,随后在父亲的
	      的方法中写上methods:{
			           fn(msg){
				   this.msg =msg
					}
				}
第三种依赖注入:
	父元素设置provide:{
			这里填写要暴露的属性
			}
	子元素设置inject:[ 这里填写要接受的属性]
第四种兄弟之间的通信:bus
	第一个兄弟.设置emitter.emit('哈哈哈',this.msg)
	第二个兄弟.设置emitter.on('哈哈哈',(msg)=>{'哈哈哈',this.msg
						})
第五种ref设置dom:
	在父亲的标签,或者子代的标签中直接设置<button ref="btn"/>
	在父亲的mounted(){
			}中设置:this.$refs.btn.style.background = 'red'
第六种:vuex可以做任意组件间通信
第七种:pinia可以做任意组件间通信
第八种:缓存
5.set up语法糖和set up 的区别
1.不需要使用 export default 导出了,写在 setup语法糖 就会自动帮你导出.
2.set up 语法糖的生命周期去除了create和beforecreate两个生命周期钩子,其他的钩子写法,在前面加上on.
3.不需要对定义的变量进行 return 了,我们定义的 ref变量可以在template直接使用了.
4.组建导入不需要注册,只需要导入即可。
6.谈谈你对路由守卫的理解
react 复制代码
路由守卫就是路由在跳转的时候,触发的钩子函数
路由守卫分为全局守卫、组件级守卫和独享守卫
1:全局钩子: beforeEach、 afterEach
2:独享守卫(单个路由里面的钩子): beforeEnter、 beforeLeave
3:组件内守卫:beforeRouteEnter、 beforeRouteUpdate、 beforeRouteLeave
7.★谈谈你对生命周期的理解
生命周期就是一个组件从创建到卸载的过程
有三个阶段:
初始化阶段:beforeCreate
		 created
		 beforeMount
		 mounted
  更新阶段:beforeUpdate
	      updated
  卸载阶段:beforeUnmount
		 unmounted
8.第一次加载页面会触发哪几个钩子函数
当页面第一次页面加载时会触发 beforeCreate,created,beforeMount,mounted 这几个钩子函数
9.异步请求适合在哪个生命周期调用?
官方实例的异步请求是在 mounted 生命周期中调用的,而实际上也可以在 created 生命周期中调用
10.DOM渲染在那个生命周期阶段内完成
DOM渲染在 mounted 周期中就已经完成只执行一次,运行阶段可以执行多次
11.谈一谈vue2和vue3的区别
1.vue3相比vue2来说,速度更快
2.体积更小
3.vue3可以让组合式api和选项式api一起使用,更容易维护
4.vue3更接近原生,可以自定义渲染api
5.vue3更适应ts
6.vue2的劫持方式是Object.definepropety,vue3是proxy
12.组合式和选项式的区别
组合式:
优点:容易学习和编写,写在特定的位置。
缺点:代码组织差,一个功能会分散开。
Vue2、Vue3支持选项式API

选项式:
优点:逻辑性偏强,功能逻辑(比如数据、watch、方法等)可以写在一块容易查找,后期维护方便。
缺点:相比选项式上手要难些,因为选项式已经规定了位置,按对应位置填写代码即可.
13.vue和react的区别
react 复制代码
1.核心的思想是不同:
	vue是一个灵活易用的渐进式双向绑定的MVVM框架。
	React的核心思想是声明式渲染和组件化、单向数据流,React既不属于MVC也不属于MVVM架构。
2.组件写法上不同
	Vue的组件写法是通过template的单文件组件格式。
	React的组件写法是JSX+inline style,也就是吧HTML和CSS全部写进JavaScript中。
3.Diff算法不同
	vue的diff算法是通过diff算法产生一个虚拟dom,与真实的dom比较,产生一个更好的的虚拟dom,来更新真实dom
	react是直接通过递归遍历VDOM树查找不同,对有变化的部分重新生成真实DOM.
4.响应式原理不同
	React主要是通过setState()方法来更新状态,状态更新之后,组件也会重新渲染.
	Vue会遍历data数据对象,使用Object.definedProperty()将每个属性都转换为getter和setter,每个Vue组件实例 
	都有一个对应的watcher实例,在组件初次渲染的时候会记录组件用到了那些数据,当数据发生改变的时 候,会触发
	setter方法,并通知所有依赖这个数据的watcher实例调用update方法去触发组件的compile渲染方法,进行渲染数据。
5.封装程度不同
	封装程度,vue封装程度更高,内置多个指令和数据双向绑定,react封装度比较低,适合扩展。
14. r o u t e 和 route和 route和router的区别
1.$route 表示当前的路由信息,包含了当前URL解析得到的信息,包含当前的路径,参数,query对象等
	$route.params
		 一个 key/value 对象,包含了 动态片段 和 全匹配片段,如果没有路由参数,就是一个空对象。
	$route.query
		 一个 key/value 对象,表示 URL 查询参数
	$route.hash
		当前路由的hash值 (不带#) ,如果没有 hash 值,则为空字符串
	$route.meta
		路由信息
2.$router用来操作路由的router实例
	路由实例方法:
	push
		1.字符串 this.$router.push('home')
		2.对象this.$router.push({path:'home'})
		3.命名的路由this.$router.push({name:'user',params:{userId:123}})
		4.带查询参数,变成 /register?plan=123this.$router.push({path:'register',query:{plan:'123'}})
	go
		前进或者后退 this.$router.go(-1)  // 后退
	replace
		push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面
	一般使用replace来做404页面
		this.$router.replace('/')
15.ref绑定数据和reactive绑定数据的区别,实现数据劫持的原理是否一样(vue绑定动态数据)
从定义数据角度对比:
	ref用来定义:基本类型数据。
	reactive用来定义:对象(或数组)类型数据。
原理不一样:
	ref通过 Object.defineProperty () 的 get 与 set 来实现响应式(数据劫持)。 
	reactive通过使用 Proxy 来实现响应式(数据劫持), 并通过 Reflect 操作 源对象 内部的数据。
16.Vue中计算属性和侦听器的区别
1. 计算属性有缓存机制, 侦听器没有
2. 计算属性不支持异步操作, 侦听器支持
3. 计算属性可以给vue新增属性, 侦听器必须是data中已有的属性
4. 计算属性只要使用了就会立即执行一次, 侦听器默认只有当数据第一次改变才会执行, 需要设置immediate属性来控制是否立即执行一次
17.proxy的使用
js 复制代码
1.Proxy可以理解成在目标对象前架设一"拦截"层,而外界对该对象访问的时候都必须经过该层拦截,类似过滤器一样的机制。
2.如果proxy的第一个字母大写的话,那么他是一个构造函数,里面有两个参数,第一个参数是目标对象,第二个参数是handler

var target = {};
var handler = {
    get: function(target, property) {
        return 23;
    }
};
var proxy = new Proxy(target, handler);
console.log(proxy.name); // 23

3.也可以当做反向代理:
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:7788',
        ws: true,
        changeOrigin: true,
        pathRewirte:{ //路径重写
             '^/api':''
         }
      },
18.为什么data不能是对象?
原因是因为如果data是一个对象的话,两个组件中设置的data都会引用同一个内存地址,而用函数的话,则会在每次引用的时候返回一个新的地址。
19.你对vuex的理解
vue 复制代码
Vuex 是一个专为 Vue.js应用程序开发的状态管理模式
state: 数据
actions:可以包含异步操作 
mutations: 唯一可以修改state数据的场所 
getters:类似于vue组件中的计算属性,对state数据进行计算(会被缓存)
modules:模块化管理store(仓库),每个模块拥有自己的state、mutation、action、getter
20.vuex的状态持久化
js 复制代码
第一种方式:最简单的做法就是利用插件 vuex-persistedState。
import createPersistedState from 'vuex-persistedstate'

const store = new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  plugins: [createPersistedState({
    storage: sessionStorage,
    key: "token"
  })]//会自动保存创建的状态。刷新还在
})

第二种方式:storage:存储方式。(sessionStorage,localStarage) key:定义本地存储中的key(存储到本地)

原理:持久化插件的核心原理是把store.state对象转为json字符串,保存在WedStorage
21.history和hash路由模式的区别
hash 模式
hash 模式是一种把前端路由的路径用井号 # 拼接在真实 URL 后面的模式。当井号 # 后面的路径发生变化时,浏览器并不会重新发起请求,而是会触发 hashchange 事件。

history 模式
history API 是 H5提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求。

随着history api的到来,前端路由开始进化了,前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由
22.v-if和v-for的优先级
vue2中,v-for的优先级更高,vue2中尽量避免v-if和v-for的同时使用
vue3中,v-if的优先级更高
23.$nexttick的原理
$nexttick的原理::Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。

Vue是异步修改DOM的并且不鼓励开发者直接接触DOM,但有时候业务需要必须对数据更改--刷新后的DOM做相应的处理,这时候就可以使用Vue.nextTick(callback)这个api了
24.如何实现组件缓存
vue 复制代码
1.使用 Vue.js 中的 keep-alive 组件
Vue.js 的 keep-alive 组件可以将子组件缓存起来,以便在下一次渲染时直接使用缓存的组件而不是重新创建。使用 keep-alive 组件很简单,只需要将需要缓存的组件包裹在 keep-alive 组件内即可。
<template>
  <div>
    <keep-alive>
      <my-component v-if="showComponent"></my-component>
    </keep-alive>
    <button @click="toggleComponent">Toggle</button>
  </div>
</template>

<script>
import MyComponent from './MyComponent.vue'
export default {
  components: {
    MyComponent
  },
  data() {
    return {
      showComponent: false
    }
  },
  methods: {
    toggleComponent() {
      this.showComponent = !this.showComponent
    }
  }
}
</script>


2.自己手动缓存:
具体做法是创建一个变量或缓存对象,在组件渲染时将渲染结果缓存到该对象中,在下一次渲染时直接使用缓存结果。
<template>
  <div>
    <div v-if="cachedComponent">{{ cachedComponent }}</div>
    <button @click="toggleComponent">Toggle</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cachedComponent: null,
      showComponent: false
    }
  },
  methods: {
    toggleComponent() {
      if (this.showComponent && this.cachedComponent) {
        // 直接使用缓存结果
        this.cachedComponent = this.cachedComponent
      } else {
        // 渲染新的组件并缓存结果
        this.cachedComponent = this.$createElement(MyComponent)
      }
      this.showComponent = !this.showComponent
    }
  }
}
</script>
25.vue3比vue2多了哪些api?
Composition API:这是 Vue 3 中最受欢迎的新特性之一,它允许你将组件逻辑拆分成更小、更可重用的部分。
Teleport:这是一个新组件,允许你将一个组件的内容挂载到另一个 DOM 元素上,它与 Vue 2 中的 <transition> 元素类似。
Suspense:这是一个新组件,允许你在等待异步组件加载时显示额外的占位符内容。
Fragments:这是一种新的语法,允许你在组件中不使用额外的 DOM 元素来包装内容。
其他新的 API:包括 provide / inject、defineAsyncComponent、watchEffect 等。这些 API 让开发更加方便,也提高了 Vue 3 的性能和灵活性。
26.大屏可视化的适配方案
第一种方式:vw vh   按照设计稿的尺寸,将px按比例计算转为vw和vh
第二种方式:scale   通过scale属性,根据屏幕大小,对图表进行整体的等比缩放
第三种方式:rem+vw vh   	  1.获得 rem 的基准值
						2.动态的计算html根元素的font-size
                          3.图表中通过 vw vh 动态计算字体、间距、位移等
27.10万条数据获取第一个和最后一个相差时间大吗
js 中数组元素的存储方式并不是连续的,而是哈希映射关系。哈希映射关系,可以通过键名 key,直接计算出值存储的位置,所以查找起来很快。
不管取哪个位置的元素的时间复杂度都是 O(1)
结论:消耗时间几乎一致,差异可以忽略不计
28.vue2打包上线空白的问题
js 复制代码
第一种方式:
原因:因为打开页面后没有匹配到任何一个路由,也就是设置在 router 里的路径没有任何一个被匹配到,包括其中设置的 path: '/' 这个路径,因此也就无法加载对应的组件,所以显示一片空白。
解决方式:vue-router 默认使用的是 history 模式,打包时需要改成 hash 模式即可。

第二种方式:
原因:看看网页源码, 对比dist文件夹结构可以看到资源路径的引入是错误的,应该用'./'而不是'/'(路劲)
解决方法:修改路径
// vue.config.js
module.exports = {
    publicPath: './',
}
相关推荐
也无晴也无风雨33 分钟前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang1 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤5 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui