0


WebGIS开发面试题:前端篇(四)

本系列内容主要介绍webgis开发过程中可能会遇到的常见面试题和答案,从前端到二维到三维,干货满满。记得关注我不走丢!

需要更多面试题、视频讲解、webgis教程的宝子戳↓↓↓

免费领取2024最新webgis学习教程

前几期内容点击下方链接:

WebGIS开发面试题:前端篇(一)

WebGIS开发面试题:前端篇(二)

WebGIS开发面试题:前端篇(三)

1、Vue 2和Vue 3的路由有什么不同?

1、Vue2的路由挂载到组件实例上,而Vue3的路由,不管跳转还是接收参数都需要按需导⼊

2、路由创建⽅式不⼀样:
Vue2中,通过 new VueRouter 来创建路由实例

import VueRouter from 'vue-router' 
const router = new VueRouter({ ... }) 

Vue3中,可以直接使用 createRouter() 函数来创建⼀个路由实例

import {createRouter} from 'vue-router' 

2、vue3能监听数组吗?怎么监听? watch的第一个参数是什么

Vue3中可以通过监听数组的方式来检测数组的变化,它提供了两种方式来实现这一功能:使用watch或使用computed。
使用watch监听数组,需要使用$watch函数来监听数组,它的用法与监听对象相同,第一个参数是要监听的数组,第二个参数是回调函数,用于处理数组变化时的逻辑操作。需要注意的是,在Vue3中,需要将watch函数放在onMounted函数中才能起作用。其中,第一个参数为要监听的数组,第二个参数为回调函数,第三个参数为可选的选项,其中deep:true表示深度监听,可以监听数组内部元素的变化。另外,watch的第一个参数不一定要是数组,也可以是任何一个应式对象。而watch的第一个参数是要监听的属性或表达式,当被监听的属性或表达式发生变化时,watch回调函数会被触发,并传递两个参数:新值和旧值。

3、v-for和v-if为什么不能一起使用

Vue2
在 Vue.js 中,v-for 和 v-if 是两个非常常用的指令,用于在模板中渲染列表和控制元素的显示。然而,Vue.js 中不允许在同一个元素上同时使用 v-for 和 v-if 指令,这是因为这两个指令的执行顺序和结果可能会互相影响,导致不可预料的结果。
具体原因如下:
1.v-for 比 v-if 的优先级高:当使用 v-for 和 v-if 指令时,Vue.js先执行 v-for,然后才执行 v-if因此,如果在 v-if 中使用了在 v-for 中定义的变量,那么在执行 v-if 时,这些变量可能还没有定义,导致 v-if 的条件判断出错。
2.v-for 会覆盖 v-if 的结果:当使用 v-for 和 v-if 指令时,v-for 可能会覆盖 v-if 的结果。例如,当列表中没有满足 v-if 条件的元素时,v-if 会将整个列表隐藏。但是,如果 v-for 中定义的列表数据为空,那么 v-if 的条件判断就会失效,导致列表仍然显示出来。因此,为了避免这些问题,Vue.js 不允许在同一个元素上同时使用 v-for 和 v-if 指令。如果需要在模板中同时使用这两个指令,可以将它们放在不同的元素上,或使用计算属性来过滤列表数据。

4、vue和mvvm

是的,Vue.js 框架完全实现了 MVVM(Model-View-ViewModel)模式。在 Vue.js 中,模型(Model)对应着组件中的数据,视图(View)对应着组件中的模板,而视图模型ViewModel)则对应着 Vue.js 实例。
具体来说,Vue.js 框架中的 ViewModel 主要包含以下几个方面的功能:
1.数据绑定:Vue.js 提供了数据绑定的功能,将组件中的数据和模板中的视图控件绑定在一起。当组件中的数据发生变化时,视图会自动更新。
2.模板语法:Vue.js 提供了一套简洁明了的模板语法,支持数据绑定、条件渲染、循环渲染等常见的模板功能。
3.计算属性和侦听器:Vue.js 提供了计算属性和侦听器的功能,用于处理组件中的复杂逻辑和数据变化的监听。
生命周期钩子:Vue.is 提供了一系列的生命周期钩子函数,用于在组件创建、更新和销毁等不同的4.生命周期阶段执行相关的逻辑。
综上所述,Vue.js 框架完全实现了 MVVM 模式,并且通过数据绑定、模板语法、计算属性、侦听器和生命周期钩子等一系列功能,使得开发者可以更加轻松地构建和维护复杂的交互式应用程序。

5、v-if和v-show

在Vue.js中,v-if和v-show都是用于控制DOM元素显示和隐藏的指令,但它们的实现方式有所不同,因此在不同的情况下,可以根据需求选择使用哪个指令。
v-if指令是一种条件渲染指令,它根据指定的表达式的结果来判断是否渲染对应的DOM元素。如果表达式的结果为真,则渲染对应的DOM元素;如果表达式的结果为假,则不染对应的DOM元素。v-if指令在渲染的时候会销毁或重新创建DOM元素,因此如果一个元素只是偶尔需要被显示,使用v-if指令可以提高性能。
v-show指令也用于控制DOM元素的显示和隐藏,但它不会销毁DOM元素,而是通过设置DOM元素的display样式来实现显示和隐藏。如果指定的表达式的结果为真,则显示对应的DOM元素,否则隐藏DOM元素。v-show指令在需要经常切换显示和隐藏的元素时更为适用,因为它不会重复创建DOM元素,而是直接修改样式,因此可以提高性能。
因此,如果需要根据条件动态地添加或删除DOM元素,可以使用v-if指令;如果需要频繁地切换元素的显示和隐藏状态,可以使用v-show指令。

6、Vue插槽

简单的理解一下,就是预留了一个可以替换的地方,
在父组件调用子组件的时候,如果想要在子组件的标签体中写一些的内容,不使用插槽是无法显示
的。
一、作用域插槽
https://blog.csdn.net/weixin 40923809/article/details/101782454
1.1 定义
作用域插槽其实就是带数据的插槽,即带参数的插槽,简单的来说就是子组件提供给父组件的参数,该参数仅限于插槽中使用,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。
1.2 编译作用域
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子集作用域内编译。

举个例子:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8" /> 
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
<title>Document</title> 
<script src="../node_modules/vue/dist/vue.js"></script> 
</head> 
<body> 
<div id="app"> 
<button v-show="isShow">按钮</button> 
<son></son> 
</div> 
<template id="tmp"> 
<div> 
<h3>我是⼦组件</h3> 
<button v-show="isShow">⼦组件按钮</button> 
</div> 
</template> 
<script> 
const vm = new Vue({ 
el: '#app', 
data: { 
// ⽗组件的isShow 
isShow: false, 
}, 
components: { 
son: { 
template: '#tmp', 
data() { 
return { 
// ⼦组件的isShow 
isShow: true, 
} 
}, 
}, 
}, 
}) 
</script> 
</body> 
</html> 

此时子组件的按钮会显示,而父组件的按钮不进行显示,

  • 如果在父模板中使用 isShow,访问的是父组件 data 中的值
  • 如果在子模板中使用 isShow,访问的是子组件 data 中的值

通过上述示例,我们可以发现,在父组件中是不能直接访问子组件中的状态的,那么如何解决这个问题?

1.3 作用域插槽的使用
使用了作用域插槽之后可以利用传值的方式来访问子组件中的变量。

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8" /> 
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> 
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
<title>Document</title> 
<script src="https://lib.baomitu.com/vue/2.6.14/vue.js"></script> 
</head> 
<body> 
<div id="app"> 
<button v-show="isShow">按钮</button> 
<!-- 通过v-slot指令找名字为default的插槽, 并指定prop对象对应default插槽 -- > 
<son> 
<template #default="prop"> 
<!-- 通过prop对象访问show属性, 相当于访问了⼦组件的isShow --> 
<button v-show="prop.show">⼦组件按钮</button> 
</template> 
<template #left="left"> 
<h3>{{left.info.name}}</h3> 
</template> 
</son> 
</div> 
<template id="tmp"> 
<div> 
<h3>我是⼦组件</h3> 
<!-- 在slot:default对象中, 定义⾃定义属性show --> 
<slot :show="isShow"></slot> 
<slot name="left" :info="stu"></slot> 
</div> 
</template> 
<script> 
const vm = new Vue({ 
el: '#app', 
data: { 
isShow: false, 
}, 
components: { 
son: { 
template: '#tmp', 
data() { 
return { 
isShow: true, 
stu: { 
name: 'xiaoming', age: 18, 
}, 
} 
}, 
}, 
}, 
}) 
</script> </body> 
</html> 

当子组件中的isShow为false的时页面展示如下:

7、vue-router

1、如何实现动态路由

动态路由,路由懒加载

{ 
path:"/city", 
component:()=>import('./views/City.vue') 
}

2、Vue3的路由跳转

import {useRouter} from 'vue-router'; 
const $router = useRouter(); 
$router.push('/city') 

8、Vue中的路由守卫

Vue 路由守卫主要有三种:

  1. 全局前置守卫(Global before guards):router.beforeEach 注册⼀个全局前置守卫,用来 在路由切换之前进⾏拦截。可以用来进⾏用户身份验证、权限控制等操作。
  2. 路由独享守卫(Per-route guards):在单个路由配置对象中通过beforeEnter 添加⼀个独 享守卫。只在当前路由⽣效,用来控制路由的访问权限或者修改路由的参数等。
  3. 组件内守卫(In-component guards):在组件内通过beforeRouteEnter、 beforeRouteUpdate 和beforeRouteLeave 这三个⽣命周期钩⼦函数来实现对当前组件内路 由的拦截和控制。
    通常情况下,全局路由守卫被用来处理⼀些全局的路由拦截和控制,例如用户登录状态的验证,未 登录用户重定向到登录页面等。而路由独享守卫和组件内守卫主要被用来控制单个路由或者组件内 部的访问权限和数据加载等操作。

7、Vue如何实现跨域

在Vue 中实现跨域请求有多种方式,以下是其中的两种:

  1. 通过配置代理
    Vue CLI 提供了⼀个简单的方式来配置代理,使得在开发环境中可以将 API 请求代理到开发服务器。在 vue.config.js 文件中添加以下内容:
module.exports = { 
devServer: { 
proxy: { 
'/api': { 
target: 'http://api.example.com', // ⽬标服务器地址 
changeOrigin: true, // 是否跨域 
pathRewrite: { 
'^/api': '' // 将请求地址中的 '/api' 替换为空字符串 } 
} 
} 
} 
} 

在上面的配置中,我们将所有以/api 开头的请求地址代理到http://api.example.com 这个地址,同时 启用了跨域选项changeOrigin: true。
2. 使用JSONP
JSONP(JSON with Padding)是⼀种跨域请求的⽅式,通过动态创建script 标签来实现。在Vue 中,我们可以通过第三方库vue-jsonp 来实现:
⾸先,我们需要安装vue-jsonp:

npm install vue-jsonp --save 

然后,在需要使用JSONP 请求的组件中,引入vue-jsonp 并使⽤this.$jsonp() 方法发起请求,例 如:

import Vue from 'vue' 
import Jsonp from 'vue-jsonp' 
Vue.use(Jsonp) 
export default { 
created () { 
this.$jsonp('http://api.example.com/data', { param: 'callback' }).then (response => { 
console.log(response) 
}) 
} 
} 

在上面的例子中,我们使用this.$jsonp() 方法发起请求,并指定了请求地址和参数param:
'callback',这个参数指定了JSONP响应中的回调函数名。响应结果会自动解析并传递给then() 中的回调函数。

8、Vue中watch和computed的区别

在Vue.js中,computed和watch都是用来监听数据变化并执行相应的逻辑。它们的主要区别在 于:

  1. computed属性是基于它的依赖缓存的。也就是说,只有当依赖发⽣改变时,computed才会 重新计算。这意味着,多个computed属性依赖于同⼀个响应式数据,只要这个响应式数据没 有发⽣变化,那么这些computed属性就不会重新计算。而watch则是每当被监听的数据变化时就会执行回调函数,因此不会有缓存的问题。
  2. computed属性通常用于处理数据的逻辑,而watch则通常用于监听数据变化后执行的异步或开销较大的操作。
    综上所述,computed适用于对⼀个或多个响应式数据进行计算,并将计算结果返回给模板进行渲 染;watch适用于观察某个特定的响应式数据,当它发⽣变化时执行相应的操作。

9、hash和history的区别

Vue Router是Vue.js官方的路由管理器,"它可以帮助我们构建SPA(Single Page Application)应用程序。Vue Router提供了两种路由模式:

1、 hash 模式
hash 模式是默认的路由模式。在hash模式下,URL中会以#号分隔,#号后面的部分被称为hash值。通过修改hash值,可以在不刷新页面的情况下切换页面状态,这是Vue Router实现路由的核心机制。

const router = new VueRouter({
mode: 'hash', 
routes: [ 
// 路由配置 
] 
}) 

在hash 模式下,路由的路径前⾯带有 # 号,如:http://example.com/#/user/profile。 原⽣JavaScript实现hash。

<body> 
<button id="btn"> hash跳转</button> 
<script> 
var btn = document.getElementById("btn"); 
window.addEventListener("hashchange",(event)=>{ 
console.log("hash:"+event.newURL) 
console.log("hash:"+event.oldURL) 
console.log("hash:"+location.hash) 
}) 
btn.addEventListener("click",()=>{ 
location.href="#/user" 
}) 
</script> 
</body> 

hash路由的特点

1、hash变化会触发⻚⾯的跳转,即浏览器的前进和后退

2、hash变化不会刷新⻚⾯,spa必备特点

3、hash永远不会提交到server端(前端⾃⼰处理)

2、history 模式

hash是前端的自带路由,和服务器没有交互history 模式使用 HTML5 History API来实现路由的切换。在 history 模式下,URL 中没有 #号,而是直接使用真实的 URL,因此看起来更加美观,在 history 模式下,路由的路径不带有 #号,如:http://example.com/user/profile。

const router = new VueRouter({ 
mode: 'history', 
routes: [ 
// 路由配置 
] 
}) 
- history.pushState 
- window.onpopstate 
<body> 
<button id="btn"> hash跳转</button> 
<script> 
var btn = document.getElementById("btn"); 
btn.addEventListener("click",()=>{ 
const state = { 
name:"page1" 
} 
console.log("切换路由到","page1") 
history.pushState(state,'',"page1") 
}) 
/* 监听浏览器前进和后退 */ 
window.onpopstate = (event)=>{ 
console.log("onpopstate",event.state,location.pathname) } 
</script> 
</body> 

区别:

  • 在 hash 模式下,URL 中的 #后面的部分被称为 hash 值,可以通过修改 hash 值来实现路由切换,不会向服务器发送请求,因此也不会影响浏览器的后退和前进按钮的行为。但是,在 hash 模式下,搜索引擎可能无法正确抓取到网站的内容。
  • 在 history 模式下,URL 中不会出现 #号,通过 HTML5 History API来实现路由的切换,向服务器发送请求,因此需要在服务器端进行相应的配置,以防止页面刷新时出现 404 错误。但是,使用history 模式可以更加美观,且可以让搜索引擎更好地抓取网站的内容。

选择哪种模式取决于具体的场景和需求。如果只是开发一些小型的应用程序或者不需要考虑SEO问题那么可以选择默认的 hash 模式;如果需要更好的SEO效果或者要开发一些大型的应用程序,可以选择history 模式。
history需要后端支持,服务需要额外配置 nginx。

location / { 
try_files $uri $uri/ /index.html; 
} 

**3、两者的选择 **

  • to B的系统推荐使用hash,简单易用,对url规范不敏感
  • to C的系统,可以考虑选择H5 history,但需要服务端支持。

10、watch监听有哪些属性可以配置

  1. 深度监视
    deep:true
    可以监视对象里边的属性
  2. 立即执行⼀次
    immediate:true

本文转载自: https://blog.csdn.net/2301_78220461/article/details/141957623
版权归原作者 WebGIS开发 所有, 如有侵权,请联系我们删除。

“WebGIS开发面试题:前端篇(四)”的评论:

还没有评论