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: './',
}