面试

时间:2024-10-27 08:38:08

1.闭包

‌‌闭包‌是指在嵌套定义的函数中,一个内部函数引用了外部函数中的局部变量,并且外部函数返回了这个内部函数对象。闭包可以保存和访问它创建时的环境,即使在外部函数结束之后。

特点

  1. 访问内部变量‌:闭包可以访问其外部函数中的局部变量,即使外部函数已经执行完毕。
  2. 内存占用‌:闭包会占用一定的内存,因为局部变量不会被垃圾回收机制回收。
  3. ‌封装变量‌:闭包可以用于创建私有变量,封装内部实现细节。
  4. 保持状态‌:闭包可以保持某个状态,使函数记住之前的操作。

应用场景

  1. 封装变量‌:闭包可以用于创建私有变量,封装内部实现细节,避免全局变量的污染。
  2. 保存状态‌:闭包可以保持某个状态,使函数记住之前的操作。
  3. 函数工厂‌:闭包可以用于创建具有特定功能的函数,类似于工厂模式。
  4. 异步操作‌:闭包在异步编程中非常有用,可以保存上下文信息,避免回调地狱。

2.promise

3.全局数据的保存

用户信息
token
路由

数据保存有哪些方法
vuex
localstorage
sessionstorage

两者用法一致,相比于cookie,存储容量增加到了5M之多;区别点:

  • localstorage是持久化存储,除非自己手动删除,关闭浏览器后依然存在;而sessionstorage关闭浏览器后自动删除。
  • localstorage作用范围是整个浏览器,简单来说只要是用同一个浏览器打开的不同窗口还是不同网页之间都能够共享数据;而sessionstorage只能在同一个窗口下共享数据。

4.多模板切换,布局,系统主题颜色

切换怎么把颜色带过去

在Vue.js中更改系统颜色通常涉及CSS变量的使用。你可以在全局样式文件中定义CSS变量,并在组件中使用它们来实现颜色的动态更改。

在全局样式文件中定义CSS变量(例如main.css):

:root {
  --primary-color: #3097d1; /* 默认主题颜色 */
  --accent-color: #e91e63; /* 默认辅助色 */
}

在Vue组件中使用这些CSS变量:

<template>
  <div :style="{ color: primaryColor }">
    <!-- 内容 -->
  </div>
</template>
 
<script>
export default {
  data() {
    return {
      primaryColor: 'var(--primary-color)',
      // 如果需要更改颜色,可以在这里设置新的值
      // 例如: '#000000'
    };
  },
  // 如果需要在运行时更改颜色,可以添加方法来更新primaryColor的值
  methods: {
    changeColor(newColor) {
      this.primaryColor = newColor;
    }
  }
};
</script>

如果要在用户交互时更改颜色,可以添加事件监听器来触发changeColor方法:

<template>
  <button @click="changeColor('#ff0000')">Change to Red</button>
</template>

每次调用changeColor方法时,它都会更新primaryColor的值,并且由于:style的绑定,使用这个变量的所有元素都会自动更新它们的颜色。

在 Vue 项目中全局切换系统的深色和浅色模式,你可以通过几种方式来实现。以下是一个设计思路,包括使用 CSS 变量、Vuex(或 Vue 的响应式数据)来管理主题状态,以及通过监听系统主题变化来自动切换主题。
 
步骤 1: 定义 CSS 变量
首先,在全局样式文件(如 App.vue 的 <style> 或单独的 CSS 文件中)定义一些 CSS 变量,这些变量将用于控制颜色主题。
 
css
:root {  
  --primary-color: #007bff;  
  --text-color: #000;  
  --background-color: #fff;  
  /* 其他颜色变量 */  
}  
  
[data-theme="dark"] {  
  --primary-color: #6c757d;  
  --text-color: #fff;  
  --background-color: #343a40;  
  /* 深色模式下的颜色变量 */  
}
步骤 2: 使用 Vuex 管理主题状态(可选)
如果你的 Vue 项目使用了 Vuex,那么将主题状态存储在 Vuex store 中会是一个很好的选择。这样,你可以在任何组件中通过访问 store 来获取和设置主题。
 
javascript
// store/index.js  
import Vue from 'vue';  
import Vuex from 'vuex';  
  
Vue.use(Vuex);  
  
export default new Vuex.Store({  
  state: {  
    darkMode: false, // 初始设置为浅色模式  
  },  
  mutations: {  
    toggleDarkMode(state) {  
      state.darkMode = !state.darkMode;  
    },  
  },  
  actions: {  
    // 如果需要,可以在这里添加异步操作  
  },  
  getters: {  
    isDarkMode: state => state.darkMode,  
  },  
});
步骤 3: 监听系统主题变化并更新 Vuex 状态
在应用的入口文件(如 main.js 或 main.ts)中,监听系统的 prefers-color-scheme 媒体查询,并更新 Vuex store 中的主题状态。
 
javascript
// main.js  
import Vue from 'vue';  
import App from './App.vue';  
import store from './store';  
  
// 监听系统主题变化  
function updateTheme() {  
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;  
  store.commit('toggleDarkMode', prefersDark);  
}  
  
updateTheme(); // 初始设置  
  
// 监听媒体查询变化  
window.matchMedia('(prefers-color-scheme: dark)').addListener(updateTheme);  
  
new Vue({  
  store,  
  render: h => h(App),  
}).$mount('#app');
注意:上面的 toggleDarkMode mutation 可能需要根据实际情况进行调整,因为直接将其设置为 prefersDark 可能会导致与用户手动切换主题时的行为不一致。你可能需要引入一个额外的状态或逻辑来区分系统主题和用户自定义主题。
 
步骤 4: 在 Vue 组件中应用主题
在你的 Vue 组件中,你可以通过绑定一个类名到根元素或使用计算属性来动态地应用主题。
 
vue
<template>  
  <div :class="{ 'dark-theme': isDarkMode }">  
    <!-- 组件内容 -->  
  </div>  
</template>  
  
<script>  
import { mapGetters } from 'vuex';  
  
export default {  
  computed: {  
    ...mapGetters(['isDarkMode']),  
  },  
};  
</script>
或者,如果你更喜欢不使用 Vuex,你也可以直接在根组件(如 App.vue)中监听系统主题变化,并通过 provide / inject 或 $emit / $on 机制将主题状态传递给子组件。
 
结论
通过结合 CSS 变量、Vuex(或 Vue 的响应式数据)以及媒体查询监听,你可以在 Vue 项目中轻松地实现全局的深色和浅色模式切换。这种方法的优点是易于维护和扩展,同时保持了代码的清晰和可重用性。

5.同一个搜索,不同的搜索条件,输入框不同的校验方法

6.自定义一个组件,包括哪些属性

在Vue中,可以通过创建一个单文件组件(.vue)来定义一个自定义组件。这个文件包括template、script和style标签。
以下是一个简单的自定义Vue组件的例子:

<template>
  <div class="my-custom-component">
    <h1>{{ title }}</h1>
    <p>{{ message }}</p>
    <button @click="greet">Say Hi</button>
  </div>
</template>
 
<script>
export default {
  props: {
    title: String,
    message: String
  },
  methods: {
    greet() {
      alert('Hi!');
    }
  }
}
</script>
 
<style scoped>
.my-custom-component {
  /* 组件样式 */
}
</style>

要使用这个组件,你需要先导入它,然后在父组件中注册并使用它。例如:

<template>
  <div>
    <my-custom-component title="Welcome" message="Hello there!" />
  </div>
</template>
 
<script>
import MyCustomComponent from './components/MyCustomComponent.vue';
 
export default {
  components: {
    MyCustomComponent
  }
}
</script>

在这个例子中,MyCustomComponent定义了两个属性title和message,以及一个方法greet。在父组件中,你可以通过属性传值的方式来设置这些属性,并且可以通过注册的标签名来使用这个组件。

7.多个父组件之间传值

在Vue中,多个父组件之间传值可以通过一个全局状态管理库(如Vuex)来实现,或者使用事件总线(Event Bus)模式。

8.接口异常

api返回异常
http请求的状态码异常
对应的api挂了

在Vue中,接口异常可能涉及以下几种情况:

  • 网络问题:如无法连接到服务器,或请求超时。
  • 服务器错误:服务器内部错误,如500等HTTP状态码。
  • 数据处理错误:后端返回的数据格式不符合预期。
  • 请求参数错误:向服务器发送了错误的请求参数。

解决方法:

  • 网络问题:检查网络连接,设置合理的超时时间,使用try-catch处理网络请求。
  • 服务器错误:在请求中添加错误处理,比如使用axios的.catch方法或者vue-resource的error回调。
  • 数据处理错误:确保数据处理逻辑正确,检查后端返回的数据格式。
  • 请求参数错误:验证请求参数的正确性,并提供用户反馈。

当出现错误时,需要在响应拦截提供异常提示

9.Vue性能优化方法

Vue 应用的性能优化可以从多个方面入手,以下是一些关键的性能优化方法:

  1. 使用v-if和v-show判断是否渲染元素,v-if为真时才渲染,v-show则总是渲染但可以通过CSS隐藏。

  2. 避免在列表渲染时使用v-if,因为它会导致渲染函数的重新构建。

  3. 使用计算属性或监听器来缓存计算结果,避免在模板中进行复杂的计算。

  4. 使用key属性来帮助Vue识别列表中各项的唯一性,优化列表渲染的过程。

  5. 避免在模板中进行复杂的表达式,可以将逻辑移到计算属性或方法中。

  6. 使用Webpack的terser-webpack-plugin插件和uglifyjs-webpack-plugin进行代码压缩和mangle。

  7. 使用路由懒加载来提升初始加载速度。

  8. 使用Vue的SSR(服务器端渲染)来提高非首屏页面的加载速度。

  9. 使用Vue Devtools进行性能分析,并遵循其提出的优化建议。

  10. 对于大型应用,考虑使用Vue的插件如Vuex和Vue Router的优化模式。

  11. 如果是大数据很长的列表,全部渲染的话一次性创建太多 DOM 就会非常卡,这时就可以用虚拟滚动,只渲染少部分(含可视区域)区域的内容,然后滚动的时候,不断替换可视区域的内容,模拟出滚动的效果
    原理是监听滚动事件,动态更新需要显示的 DOM,并计算出在视图中的位移,这也意味着在滚动过程需要实时计算,有一定成本,所以如果数据量不是很大的情况下,用普通的滚动就行

  12. v-for 遍历避免同时使用 v-if
    为什么要避免同时使用 v-for 和 v-if

在 Vue2 中 v-for 优先级更高,所以编译过程中会把列表元素全部遍历生成虚拟 DOM,再来通过 v-if 判断符合条件的才渲染,就会造成性能的浪费,因为我们希望的是不符合条件的虚拟 DOM都不要生成

在 Vue3 中 v-if 的优先级更高,就意味着当判断条件是 v-for 遍历的列表中的属性的话,v-if 是拿不到的

  1. 第三方插件按需引入
    比如 Element-UI 这样的第三方组件库可以按需引入避免体积太大,特别是项目不大的情况下,更没有必要完整引入组件库
  2. 路由懒加载
    我们知道 Vue 是单页应用,所以如果没有用懒加载,就会导致进入首页时需要加载的内容过多,时间过长,就会出现长时间的白屏,很不利于用户体验,SEO 也不友好

所以可以去用懒加载将页面进行划分,需要的时候才加载对应的页面,以分担首页的加载压力,减少首页加载时间

  1. keep-alive缓存页面
    比如在表单输入页面进入下一步后,再返回上一步到表单页时要保留表单输入的内容、比如在列表页>详情页>列表页,这样来回跳转的场景等

我们都可以通过内置组件 来把组件缓存起来,在组件切换的时候不进行卸载,这样当再次返回的时候,就能从缓存中快速渲染,而不是重新渲染,以节省性能

<template>
  <div id="app">
    <keep-alive>
      <router-view/>
    </keep-alive>
  </div>
</template>

也可以用 include/exclude 来 缓存/不缓存 指定组件
可通过两个生命周期 activated/deactivated 来获取当前组件状态

  1. 事件的销毁
    Vue 组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件

而对于定时器、
addEventListener 注册的监听器等,就需要在组件销毁的生命周期钩子中手动销毁或解绑,以避免内存泄露

<script>
export default {
    created() {
      this.timer = setInterval(this.refresh, 2000)
      addEventListener('touchmove', this.touchmove, false)
    },
    beforeDestroy() {
      clearInterval(this.timer)
      this.timer = null
      removeEventListener('touchmove', this.touchmove, false)
    }
}
</script>
  1. 图片懒加载
    图片懒加载就是对于有很多图片的页面,为了提高页面加载速度,只加载可视区域内的图片,可视区域外的等到滚动到可视区域后再去加载

Vue开发中的性能优化小技巧