最新Vue常见基础面试题(看这一篇就够了)(二)

简介: 最新Vue常见基础面试题(看这一篇就够了)(二)

安装 axios🌟🌟

  • 安装依赖》运行依赖》axios
  • 使用 axios 发送请求
  • 利用 Vue.prorotype 挂载到原型上


vue 动画🌟🌟

文档(opens new window)


利用类名添加动画

在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to: 2.1.8 版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to: 2.1.8 版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。


  • 首先给需要添加动画的元素用 transition 包裹起来
  • 利用类名实现动画
.v-enter,
.v-leave-to {
  transform: translate(200px, 0);
}
.v-enter-active,
.v-leave-active {
  transition: transform 1s;
}
.v-enter-to,
.v-leave {
  transform: translate(0, 0);
}


自定义动画类名

<transition name="box2">
  <div class="box" v-show="flag"></div>
</transition>
.box2-enter,
.box2-leave-to {
  opacity: 0;
}
.box2-enter-active,
.box2-leave-active {
  transition: opacity 1s;
}
.box2-enter-to,
.box2-leave {
  opacity: 1;
}


结合 css 动画库设置动画🌟🌟

  • 引入 css 动画库
  • 通过 enter-active-class、leave-active-class 设置动画
<transition
  enter-active-class="animated bounceIn"
  leave-active-class="animated bounceOut"
>
  <div class="box" v-show="flag"></div>
</transition>


vuex 的缺陷🌟🌟🌟

vuex 的数据属于应用级别的数据,应用刷新,数据会重置 (具有响应式, 不能持久存储)

结合本地存储来使用

单纯的使用本地: 本地的数据(持久存储,不具有响应式)


vue 单页面应用的优缺点🌟🌟🌟🌟

缺点:

  • 不利于 seo
  • 兼容到 ie9
  • 初次加载耗时相对增多

优点

  • 用户体验好,不用重新刷新整个页面
  • 前后端分离
  • mvvm 设计模式
  • 减轻服务期压力,只需要服务器提供数据


加深面试题

关于项目打包你都做了什么? 你的项目优化具体做了哪些? 你的项目如何打包的?🌟🌟🌟🌟🌟

  • 移除 console,借助 babel 插件 babel-plugin-transform-remove-console
  • 判断环境,只在发布阶段使用上面的插件, 通过 process.env.NODE_ENV ‘production’ || “development”
  • 因为开发阶段和发布阶段入口代码有区别,通过 chainWebpack 配置自定义的打包入口,
// 配置自定义入口文件
chainWebpack: config => {
  // when: 相当于if 第一个参数:(条件) 第二个参数(满足条件执行的回调函数) if(条件) { 满足条件执行的逻辑 }
  // 开发期间 --- main-dev.js
  config.when(process.env.NODE_ENV === 'development', config => {
    config
      .entry('app')
      .clear()
      .add('./src/main-dev.js')
  })
  // 发布阶段 --- main-prod.js
  config.when(process.env.NODE_ENV === 'production', config => {
    config
      .entry('app')
      .clear()
      .add('./src/main-prod.js')
  })
}
  • 发布阶段为了减小打包体积, 忽略 js 打包,配置 externals,关于 css 样式,在发布的入口文件中注释掉即可, 加载 cdn 资源文件,加载 cdn 资源文件的优势,减小自己服务器的压力,同时 cdn 资源会就近原则访问
  • 只在发布阶段使用 cdn 资源,通过给 htmlwebpackPlugin 添加标识,标识为不同的值,此时就可以在 html 中判断 htmlwebpackPlugin 标识为开发阶段还是发布阶段从而按需加载 cdn 资源
  • 路由懒加载,路由按需加载, 匹配到哪个路由规则,加载对应的资源文件


虚拟 dom🌟🌟🌟

本质上就是一个 JS 对象,用来描述你希望在屏幕上看到的内容


作用:描述了真实dom结构,核心属性

真实的dom节点有很多属性的,如果直接操作真实的dom,消耗性能

vue里面template写的结构转换render函数,render函数执行会返回虚拟dom结构 >> 渲染出真实dom


优势:

1、数据更新的时候,虚拟dom对比(旧的虚拟dom结构和新的虚拟dom结构进行对比),对比出差异以后,更新到真实的dom里面(最小化操作dom)

2、同级比较,如果标签名不一致或者key不一致直接替换,不会进行深层次对比

3、次序深度优先

跨平台

浏览器,小程序 , 支付宝小程序,抖音小程序,打包安卓,ios应用 ,electron桌面应用

vue/react >> 虚拟dom 渲染的时候根据不同的平台去进行渲染

渲染浏览器环境的方法

渲染小程序的方法

dom diff的性能好

跨平台


Diff 算法🌟🌟🌟🌟

虚拟 dom 高效更新执行过程


  • 初次渲染时,会根据 model 数据创建一个虚拟 DOM 对象(树)
  • 根据虚拟 DOM 生成真正的 DOM,渲染到页面
  • 当数据变化后,会重新根据新的数据,创建新的虚拟 DOM 对象(树)
  • 与上一次得到的虚拟 DOM 对象,使用 Diff 算法比对(找不同),得到需要更新的内容
  • 最终,React 只将变化的内容更新(patch)到 DOM 中,重新渲染到页面
  • 什么是虚拟 dom:用 js 对象来表示页面上 dom 元素的的样式体现
  • 虚拟 dom 的作用:高效更新页面,还有就是让 react 脱离了浏览器的概念
  • 怎么来高效更新页面的:就是在第一次渲染页面的时候生成一份初始的虚拟 dom 树,然后当数据改变之后,再生成一份虚拟 dom 树,然后根据新旧 dom 树进行对比,对比完成之后,把有区别的进行更新
  • diff 算法的作用就是:新旧虚拟 dom 树在对比的时候就是通过 diff 算法来对比的
  • diff 算法又是怎么去对比的:tree diff、component diff、element diff


面试语术:

你知道虚拟 dom 吗?简单又谈一下?

本质上就是一个 JS 对象,用来描述你希望在屏幕上看到的内容,虚拟 dom 可以实现高效更新,(后面如果自己能说一气说出来)

如何实现高效更新的?

利用新旧虚拟 dom 树进行对比,从而进行局部进行更新

如何进行新旧 dom 树进行对比?

利用 diff 算法,主要是 tree diff 树对比,component diff 组件对比,element diff 元素对比

加上一些其他话术

所以虚拟 dom 在前端中不管是 vue、react 等等都采用


axios 配置代理服务器🌟🌟🌟🌟

什么是跨域?

在浏览器里面域名、端口、ip 地址、协议,有任何一项不同,则跨域

A 网站:http://localhost:8080/#/

B 网站:http://localhost:3000/#/

处理跨域的方式?

JsonP(只能处理 get 请求)、cors(后端开启)、代理服务器

module.exports = {
  devServer: {
    host: 'localhost',
    port: 8080,
    proxy: {
      '/api': {
        target: 'http://localhost:3000', // 要跨域的域名
        changeOrigin: true // 是否开启跨域
      },
      '/get': {
        target: 'http://localhost:3000', // 要跨域的域名
        changeOrigin: true // 是否开启跨域
      }
    }
  }
}


小程序分包加载🌟🌟🌟

某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。

在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分。

在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。


目前小程序分包大小有以下限制:

  • 整个小程序所有分包大小不超过 12M
  • 单个分包/主包大小不能超过 2M


对小程序进行分包,可以优化小程序首次启动的下载时间,以及在多团队共同开发时可以更好的解耦协作。

代码演示,分包加载之前

pages: [
  'pages/tabs/home',
  'pages/tabs/cates',
  'pages/tabs/search',
  'pages/tabs/cart',
  'pages/tabs/my',
  'pages/goods_list',
  'pages/goods_detail/main',
  'pages/order',
  'pages/orderList'
]


抽离之后

pages: [
      'pages/tabs/home',
      'pages/tabs/cates',
      'pages/tabs/search',
      'pages/tabs/cart',
      'pages/tabs/my',
      'pages/order',
      'pages/orderList'
    ],
    subpackages: [
      {
        name: 'goods',
        root: 'goods',
        pages: [
          'goods_list',
          'goods_detail/main'
        ]
      }
    ]


图片或者图标等资源文件使用线上资源


v-if 和 v-for 避免结合使用🌟🌟🌟

因为 v-for 的优先级大于 v-if,所以会先根据所有数据生成结构,然后在根据,v-if 进行按需渲染

<div id="app">
  <ul>
    <li v-for="item in arr" v-if="item%2===0">{{ item }}</li>
  </ul>
</div>
<script src="./vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      arr: [1, 2, 3, 4]
    }
  })
</script>


我们可以采用计算属性来避免此问题,这样的话,先通过计算属性,计算出要渲染的数据,然后直接循环计算属性即可

<div id="app">
  <ul>
    <li v-for="item in newArr">{{ item }}</li>
  </ul>
</div>
<script src="./vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      arr: [1, 2, 3, 4]
    },
    computed: {
      newArr() {
        return this.arr.filter(item => {
          return item % 2 === 0
        })
      }
    }
  })
</script>


vue 中 route 和 router 的区别🌟🌟🌟🌟

  • route 是当前路由信息,可以获取到当前路由地址参数等等
  • router 是全局路由(VueRouter)实例对象,可以通过 router 进行路由的跳转后退等等


如何封装一个插件🌟🌟

  • 定义一个 button 组件,在 index.js 中引入并注册
  • 在 components 中创建一个 index.js
import sgButton from './button.vue'
function install (Vue) {
  Vue.component(sgButton.name, sgButton)
}
export default {
  install
}
  • 在 main.js 中导入该 js 文件,当调用 Vue.use 方法,会默认调用内部的 install 方法


面试题

你有封装过插件吗? Vue.use 的原理是什么?

当调用 Vue.use 方法,会默认调用内部的 install 方法,install 这个方法默认的第一个形参就是 Vue,这样的话我们就可以通过 Vue 注册一些全局组件,给 Vue 扩展一下方法。


vueI18n 的使用🌟🌟

vue 中实现语言切换的方式如何实现的

1.NPM 项目安装

cnpm i vue-i18n


2.使用方法

/* 国际化使用规则 */
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
<!-- 需要国际化的数据定义在此处 -->
const messages = {
  en: {
    message: {
      hello: 'world hello'
    }
  },
  zh: {
    message: {
      hello: '世界'
    }
  }
}
<!-- 使用i18n -->
const i18n = new VueI18n({
  locale: 'zh',
  messages
})
export default {
  data () {
    return {
      hello: this.$t('message.hello')
    }
  },
  i18n
}


3.页面数据使用

<div id="#app">
  <p>{{ $t("message.hello") }}</p>
</div>


4.案例练习

定义基本结构

<div id="app">
  <button>切换语言</button>
  <ul>
    <li>首页</li>
    <li>新闻</li>
    <li>关于</li>
    <li>概况</li>
  </ul>
</div>
ul{
  list-style: none;
  li{
    width: 20%;
    height: 70px;
    line-height: 70px;
    background: green;
    color: #fff;
    float: left;
    margin-left: 2%;
    text-align: center;
    line-height: 70px;
  }
}


定义语言包

zh.js

export default {
  nav: ['首页', '新闻', '概况', '关于']
}


en.js

export default {
  nav: ['home', 'news', 'gk', 'about']
}


在 main.js 中引入语言包

.import zh from './i18n/zh.js'
import en from './i18n/en.js'
Vue.use(VueI18n)
const i18n = new VueI18n({
  locale: 'en',
  messages: {
    zh,
    en
  }
})


数据渲染和切换

<template>
  <div id="app">
    <button @click="changeLang">切换语言</button>
    <ul>
      <li v-for="(item, index) in $t('nav')" :key="index">
        {{ item }}
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    methods: {
      changeLang() {
        this.$i18n.locale = this.$i18n.locale === 'en' ? 'zh' : 'en'
      }
    }
  }
</script>


keep-alive🌟🌟🌟🌟

  1. vue自带的组件 >> 主要功能是缓存组件 >> 提升性能
  2. 使用场景:可以少网络请求,如果当前组件数据量比较大,就可以节省网络请求 >> 提升用户体验
  3. 举例:如果详情页面之间进行切换,就可以使用keep-alive进行缓存组件,防止同样的数据重复请求
<keep-alive>
       <router-view />
    </keep-alive>

de91218556174c6d97d5e3ace667b56e.png


一、Keep-alive 是什么

keep-alivevue中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM


keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们


keep-alive可以设置以下props属性:

  • include - 字符串或正则表达式。只有名称匹配的组件会被缓存
  • exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存
  • max - 数字。最多可以缓存多少组件实例


关于keep-alive的基本用法:

<keep-alive>
  <component :is="view"></component>
</keep-alive>


使用includesexclude

<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>


匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值),匿名组件不能被匹配

设置了 keep-alive 缓存的组件,会多出两个生命周期钩子(activated与deactivated):

  • 首次进入组件时:beforeRouteEnter > beforeCreate > created> mounted > activated > … … > beforeRouteLeave > deactivated
  • 再次进入组件时:beforeRouteEnter >activated > … … > beforeRouteLeave > deactivated


二、使用场景

使用原则:当我们在某些场景下不需要让页面重新加载时我们可以使用keepalive

举个栗子:

当我们从首页–>列表页–>商详页–>再返回,这时候列表页应该是需要keep-alive

首页–>列表页–>商详页–>返回到列表页(需要缓存)–>返回到首页(需要缓存)–>再次进入列表页(不需要缓存),这时候可以按需来控制页面的keep-alive


vue-router 中 hash 和 history 的区别

  • history 没有#/,会比 hash 好看
  • history 模式是采用的 h5history.pushState API 来完成 URL 跳转而无须重新加载页面
  • hash 是利用 location.hash 进行跳转的
  • hash 是不需要后台配置支持的
  • history 不过这种模式要玩好,还需要后台配置支持


this.$nextTick()的作用

这个函数是可以等 dom 重新更新完成会调用

数据渲染完成,页面完成更新即调用 this.$nextTik

当修改了数据,dom 是异步同步的,所以,如果更改了数据,在修改数据下面重新操作 dom 会出问题,需要保证 dom 也更新完成才能操作。

目录
相关文章
|
5月前
|
JavaScript 前端开发 应用服务中间件
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
这篇文章分析了Vue项目在服务器部署后出现404错误的原因,主要是由于history路由模式下服务器缺少对单页应用的支持,并提供了通过修改nginx配置使用`try_files`指令重定向所有请求到`index.html`的解决方案。
【Vue面试题三十】、vue项目本地开发完成后部署到服务器后报404是什么原因呢?
|
5月前
|
JavaScript
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
这篇文章深入探讨了Vue中的`slot`概念,包括它的定义、使用场景和分类(默认插槽、具名插槽和作用域插槽),并通过代码示例展示了如何在组件中使用插槽来实现内容的分发和自定义。同时,文章还对插槽的工作原理进行了分析,解释了`renderSlot`函数和`$scopedSlots`对象的角色。
【Vue面试题十五】、说说你对slot的理解?slot使用场景有哪些?
|
5月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
5月前
|
JavaScript 前端开发 数据处理
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
这篇文章讨论了Vue中实现权限管理的策略,包括接口权限、路由权限、菜单权限和按钮权限的控制方法,并提供了不同的实现方案及代码示例,以确保用户只能访问被授权的资源。
【Vue面试题二十八】、vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
|
5月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
4月前
|
缓存 JavaScript 前端开发
vue面试题
vue面试题
179 64
|
3月前
|
JavaScript 前端开发
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
53 0
vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】
|
5月前
|
JavaScript 安全 前端开发
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
这篇文章介绍了Vue项目中解决跨域问题的方法,包括使用CORS设置HTTP头、通过Proxy代理服务器进行请求转发,以及在vue.config.js中配置代理对象的策略。
【Vue面试题二十九】、Vue项目中你是如何解决跨域的呢?
|
5月前
|
JavaScript 前端开发 编译器
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
这篇文章介绍了Vue 3相对于Vue 2的改进和新增特性,包括性能提升、体积减小、更易维护、更好的TypeScript支持、新的Composition API、新增的Teleport和createRenderer功能,以及Vue 3中的非兼容性变更和API的移除或重命名。
【Vue面试题三十二】、vue3有了解过吗?能说说跟vue2的区别吗?
|
5月前
|
JavaScript 前端开发 API
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?
这篇文章讨论了Vue项目中错误的处理方式,包括后端接口错误和代码逻辑错误的处理策略。文章详细介绍了如何使用axios的拦截器处理后端接口错误,以及Vue提供的全局错误处理函数`errorHandler`和生命周期钩子`errorCaptured`来处理代码中的逻辑错误。此外,还分析了Vue错误处理的源码,解释了`handleError`、`globalHandleError`、`invokeWithErrorHandling`和`logError`函数的作用和处理流程。
【Vue面试题三十一】、你是怎么处理vue项目中的错误的?