史上最强Vue,面试、项目全靠它

本文全面探讨Vue.js框架,从基础到高级,包括Vue的优点、数据驱动、MVVM、组件化、生命周期、指令使用、数据闪烁、状态管理Vuex、路由管理vue-router、网络请求axios等。详细解析了Vue组件的创建过程、数据绑定、组件通信、模板编译,以及如何在项目中解决常见问题,如数据闪烁、DOM不更新、初始化页面闪动等。此外,还介绍了如何封装组件、使用scss、监听对象属性变化,以及Vue的插件如状态管理和路由管理的使用方法。文章覆盖了面试中常见的Vue知识点,旨在帮助读者深入理解Vue并提升项目实战能力。
摘要由CSDN通过智能技术生成

史上最强Vue,面试、项目全靠它

vue框架篇

文章目录

vue的优点

轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;

简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;

双向数据绑定:保留了angular的特点,在数据操作方面更为简单;

组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;

视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;

虚拟DOM:dom操作是非常耗费性能的,不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;

运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。

数据驱动的理解

当vue中的数据发生改变的时候,用户的界面也会相应的变化,开发者不需要手动去修改DOM元素。这样可以认为是vue.js帮我们处理了数据和DOM对象之间的映射,我们有更多的精力去处理业务逻辑。这样比频繁的操作DOM元素,效率要高很多。

MVVM的理解

vue中的数据驱动是通过MVVM框架实现的,M指的是data数据部分,V指的是view页面视图部分,VM指的是连接数据和页面视图的中间件。

  • MVVM说明
    数据和页面视图是不能直接通信的,这时候需要中间件来实现双方的数据通信。
    当数据发生变化的时候,中间件监听到了以后通知页面视图进行渲染,如果是有事件触发的时候,中间件监听到了以后,会对data中的数据做出更改
    MVVM最终实现了业务(data)和视图的分离
  • MVVM三要素
    1.响应式 vue如何监听数据的变化
    2.vue模板如何编写和解析,如何把具体的数据替换到模板中,{ {}}双花括号的形式。
    3.vue如何把模板转换为HTML(虚拟DOM的显示和DOM的转换)

组件化的理解

1.组件定义

组件是可复用的的vue实例,可以增强代码的复用性,提高可维护性

2.组件的使用场景

1.通用组件 实现基本的功能,比如输入框组件,下拉菜单组件等等(element-ui中的组件)
2.业务组件 用于完成一定的业务和功能,比如搜索框组件、轮播图组件、tab选项卡组件等。
3.页面组件 组织应用各部分页面内容,用于页面组件的切换,比如商品列表页面组件,购物车页面等。

3.如何使用组件

第一种:components注册
第二种:有状态组件(data) 无状态组件(函数组件)
第三种:组件传值、父传子用props接收,子传父用emit
第四种:组件用于内容的分发,比如插槽的使用

4.vue组件产生的过程

组件配置-Vuecomponent-render-虚拟dom-真实的DOM结构

数据闪烁

如果是{ {msg}}会出现数据闪烁的现象,用v-text="msg"可以解决这个问题

<div id="app">
      <div>{
   {
    msg }}</div>
      <div v-text="msg"></div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
      const app = new Vue({
   
        el: "#app",
        data() {
   
          return {
   
            msg: "aa"
          };
        }
      });
    </script>

请详细说下你对vue生命周期的理解?

总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。

创建前/后: 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。在created阶段,vue实例的数据对象data有了,el为undefined,还未初始化。

载入前/后:在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

更新前/后:当data变化时,会触发beforeUpdate和updated方法

销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在

vue中父子组件的生命周期

渲染的过程
-父beforCreate>父created>父beforMount>子beforCreate>子create>子beforMount>子Mounted>父mounted

子更新创建过程
-父beforUpdate>子beforUpdate>子updated>父updated

父组件更新过程
-父beforUpdate>父updated

销毁过程
-父beforDestory>子beforDestory>子destoryed>父destoryed

vue中的指令和它的用法

v-for 用于遍历数组、对象、数字的值,使用的语法是 name in 数组(对象,数字)

如果遍历的是数组,则可以获取到数组的元素和下标(索引),使用方法为 (item,index) in 数组

如果遍历的是对象,则可以获取到对象的属性名和属性值,使用方法为(属性,值)in 对象

注意:使用v-for指令时,最好给一个key属性,用于优化vue对DOM的渲染

v-model 双向数据绑定指令 一般用于表单元素

v-on 用于添加事件 用@符代替

v-bind 用于绑定一个或多个属性 用:代替

v-html 数据被定义在数据属性中,指明了具体的html内容。对应JavaScript中的innerHTML

属性

v-text 数据被定义在数据属性中,指明了具体的值。将具体的值展示在视图层,对应JavaScript中的innerText属性

v-once 作用是只会渲染对应元素一次,数据更行不会引起视图的更新,目的是为了优化页面的性能

v-if 用于根据条件表法是来带有条件的渲染。如果条件为假,那么页面中将不回渲染当前元素

v-else 在v-if条件不满足时才起作用,不能单独使用,必须配合v-if一起使用

v-show 用于显示或者隐藏元素,它是以style样式的方式来实现的

为什么vue组件中data必须是一个函数?

对象为引用类型,当复用组件时,由于数据对象都指向同一个data对象,当在一个组件中修改data时,其他重用的组件中的data会同时被修改;而使用返回对象的函数,由于每次返回的都是一个新对象(Object的实例),引用地址不同,则不会出现这个问题。

vue中v-if和v-show有什么区别?

v-if和v-show看起来似乎差不多,当条件不成立时,其所对应的标签元素都不可见,但是这两个选项是有区别的:

1、v-if在条件切换时,会对标签进行适当的创建和销毁,而v-show则仅在初始化时加载一次,因此v-if的开销相对来说会比v-show大。

2、v-if是惰性的,只有当条件为真时才会真正渲染标签;如果初始条件不为真,则v-if不会去渲染标签。v-show则无论初始条件是否成立,都会渲染标签,它仅仅做的只是简单的CSS切换。

computed和watch的区别

计算属性computed:
  • 支持缓存,只有依赖数据发生改变,才会重新进行计算
  • 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
  • computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
  • 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
  • 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
  • 不支持缓存,数据变,直接会触发相应的操作;
  • watch支持异步;
  • 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  • 当一个属性发生变化时,需要执行对应的操作;一对多;
  • 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:

immediate:组件加载立即触发回调函数执行

watch: {
   
  firstName: {
   
    handler(newName, oldName) {
   
      this.fullName = newName + ' ' + this.lastName;
    },
    // 代表在wacth里声明了firstName这个方法之后立即执行handler方法
    immediate: true
  }
}

deep: deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler

watch: {
   
  obj: {
   
    handler(newName, oldName) {
   
      console.log('obj.a changed');
    },
    immediate: true,
    deep: true
  }
}

优化:我们可以使用字符串的形式监听

watch: {
   
  'obj.a': {
   
    handler(newName, oldName) {
   
      console.log('obj.a changed');
    },
    immediate: true,
    // deep: true
  }
}

这样Vue.js才会一层一层解析下去,直到遇到属性a,然后才给a设置监听函数。

vue-loader是什么?使用它的用途有哪些?

vue文件的一个加载器,跟template/js/style转换成js模块。

$nextTick是什么?

vue实现响应式并不是数据发生变化后dom立即变化,而是按照一定的策略来进行dom更新。

nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用nextTick,则可以在回调中获取更新后的 DOM

v-for key的作用

当Vue用 v-for 正在更新已渲染过的元素列表是,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不是移动DOM元素来匹配数据项的改变,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。key属性的类型只能为 string或者number类型。

key 的特殊属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用 key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用key,它会基于key的变化重新排列元素顺序,并且会移除 key 不存在的元素。

Vue的双向数据绑定?

在表单元素中通过v-model指令把用户输入的值和data(模型)中的数据进行绑定,页面输入的内容时发生变化,data(模型)中的数据会发生变化,如果是data中的数据发生变化,页面(视图)也会相应做出相应的变化。

组件传值

父传子

通过props传递

父组件: <child value = '传递的数据' />

子组件: props['value'],接收数据,接受之后使用和data中定义数据使用方式一样
子传父

在父组件中给子组件绑定一个自定义的事件,子组件通过$emit()触发该事件并传值。

父组件: <child @receive = 'receive' />

 子组件: this.$emit('receive','传递的数据')
兄弟组件传值
  • 通过中央通信 let bus = new Vue()

A:methods :{ 函数{bus.$emit(‘自定义事件名’,数据)} 发送

B:created (){bus.$on(‘A发送过来的自定义事件名’,函数)} 进行数据接收

  • 通过vuex

prop 验证,和默认值

我们在父组件给子组件传值的时候,可以指定该props的默认值及类型,当传递数据类型不正确的时候,vue会发出警告

props: {
   
    visible: {
   
        default: true,
        type: Boolean,
        required: true
    },
},

请说下封装 vue 组件的过程

首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。

然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据后,想把数据传递给父组件。可以采用emit方法。

Vue.js的template编译

简而言之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点),详细步骤如下:

首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。

然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)

scss是什么?在vue.cli中的安装使用步骤是?有哪几大特性?

css的预编译,使用步骤如下:

第一步:用npm 下三个loader(sass-loader、css-loader、node-sass)

第二步:在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展.scss

第三步:还是在同一个文件,配置一个module属性

第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”

特性主要有:

  • 可以用变量,例如($变量名称=值)
  • 可以用混合器,例如()
  • 可以嵌套

vue如何监听对象或者数组某个属性的变化

当在项目中直接设置数组的某一项的值,或者直接设置对象的某个属性值,这个时候,你会发现页面并没有更新。这是因为Object.defineProperty()限制,监听不到变化。

解决方式:

  • this.$set(你要改变的数组/对象,你要改变的位置/key,你要改成什么value)
this.$set(this.arr, 0, "OBKoro1"); // 改变数组
this.$set(this.obj, "c", "OBKoro1"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值