vue相关

作者: 没有昵_称 | 来源:发表于2020-07-17 09:57 被阅读0次

介绍一下Vue的生命周期

  • beforeCreate:是 new Vue()之后触发的第一个钩子,当前阶段datamethodscomputed以及watch上的属性和方法均不能访问
  • create:在实例创建完成之后,当前阶段已经完成了数据的观测,也就是可以使用数据,但是改变数据不会触发update函数,可以做一些初始数据的获取,当前阶段无法与dom进行交互,如果非要做交互,可以使用vm.$nextTick来访问dom
  • beforemount:发生在挂在之前,在这之前template模板已导入渲染函数编译,当前阶段虚拟dom已近创建完成,即将开始渲染,此时也可以修改数据,但是不会触发update函数
  • mounted:在挂载完成之后,这时候真实dom已经挂载完毕,数据完成双向数据绑定,这时候可以进行dom操作
  • beforeUpdate:发生在更新之前,也就是响应式数据更新,虚拟dom重新渲染之前触发,这个阶段可以进行数据的更改,不会重新渲染
  • update:发生在更新完成之后,当前组件dom已更新完毕,避免这个期间更改数据,因为可能会导致无限循环更新
  • beforeDestroy:发生在实例销毁之前,当前阶段实例完全可以使用,这时候我们可以做一些善后操作:比如清除计时器
  • destroy:发生在实例销毁之后,这时候只剩一个dom空壳子

Vue的响应式系统

VueMVVM框架,当数据模型data变化时,页面视图会得到相应的更新,
其原理对datagetter/setter方法进行了拦截(vue2:Object.defineProperty,vue3:proxy)
利用发布订阅的设计模式,在getter方法中进行订阅,在setter方法中发布通知,让所有订阅者完成响应,当该属性变化时,会执行该属性的setter方法,从而完成该属性的发布通知,通知所有订阅者进行更新

computed与watch的区别

computedwatch都可以观察属性的变化从而做出响应,不同的是:
计算机属性computed更多是作为缓存功能的观察者,它可以将一个或多个data属性进行计算生成一个新的值提供给渲染函数使用,当依赖的属性变化时,computed不会立即计算生成新的值,而是标记成脏数据,下次computed被获取时,才会重新计算并返回
而监听器watch并不具备缓存性,监听器提供一个监听函数,当监听的属性发生变化时,会立即执行该函数

vue双向绑定的原理

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变; 核心:关于VUE双向数据绑定,其核心是 Object.defineProperty()方法


$nextTick

当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值, 你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。


什么是vue-loader

解析和转换.vue文件。提取出其中的逻辑代码 script,样式代码style,以及HTML 模板template,再分别把他们交给对应的loader去处理

用途:js可以写es6,style样式可以写scss或less、template可以加jade等


v-if和v-show的区别

当条件不成立时,v-if不会渲染DOM元素,v-show操作的是样式(display),切换当前DOM的显示和隐藏。

组件中的data为什么是一个函数?

一个组件可以很多地方使用,也就是会创建很多实例,如果data是个对象的话,对象是引用类型,一个实例修改了data数据会影响其他实例
所以data必须使用函数,为每一个实例创建一个自己的data,使同一组件在不同的实例中互不影响

Vue事件绑定原理

每个vue实例都是一个Event Bus,当子组件创建时候,父组件传递事件给子组件,子组件初始化时使用$on方法,将事件注册在组件内部,子组件需要调用时可以通过 $emit 来调用事件, native事件是通过addEventLister在将事件注册到真实dom

slot是什么?有什么作用?原理是什么?

slot又名插槽,是Vue的内容分发机制,slot是子组件的一个模板标签元素,怎么显示由父组件决定,分为:默认插槽、具名插槽、作用域插槽。

  • 默认插槽,一个组件只有一个,slot没有指定name
  • 具名插槽,带有name的slot,一个组件可以有多个
  • 作用域插槽,可以是默认插槽也可以是具名插槽,该插槽不同点是,子组件渲染作用域插槽时候,可以将子组件的数据传递给父组件,父组件根据子组件传递过来的值来决定怎么渲染插槽

实现原理:
当子组件实例化的时候,获取到了父组件传入的slot标签的内容,存放在vm.$slot中,子组件执行渲染函数时候,遇到slot标签,会使用$slot中的内容替换

Vue模板渲染的原理是什么?

vue会使用正则对template字符串进行解析,将标签,属性,指定等转化成AST语法树
遍历AST语法树,将其转化成render函数,遍历过程中,遇到静态节点会对其标记,方便重新渲染时diff比较
再将rander函数转化成虚拟dom,遍历虚拟dom,创建真实dom

template预编译是什么?

vue里,模板编译只会在组件实例化的时候编译一次,生成渲染函数之后,再也不会进行编译,编译对组件runtime是一种性能消耗
而模板编译只是将template转化成render函数,这个过程正好可以在项目构建的时候完成,这样就可以让组件的runtime跳过编译的过程,从而提升性能,这个过程就是预编译

那template和jsx的有什么分别?

template和jsx都是render函数的一种表达方式,不同的是:
jsx相对于template而言,更加灵活,在复杂的组件中更有优势
虽然template显得有些呆滞,但是在代码结构上更符合视图和逻辑分离的习惯,更简单,更直接,更容易维护

说一下什么是虚拟dom

虚拟dom就是dom节点在JavaScript中的一种抽象数据结构,之所以用虚拟dom,是因为操作真实dom的代价比较昂贵,频繁的操作dom会产生性能问题
虚拟dom,在每次数据更新变化时后,会对比新老虚拟dom,匹配找出尽可能少的需要更新的真实dom,从而提高性能

key属性的作用是什么

在对节点diff的过程中,判断是否时同一节点的一个很重要条件就是key是否相等,如果key相等,会尽可能地服用原有节点,key属性时提供给diff使用的

说说Vue2.0和Vue3.0有什么区别

1、重构了响应式,用proxy替换了object.defineProperty
它可以直接监听数组类型的数据变化
它可以直接监听对象本身,不用像object.defineProperty,去遍历对象,提高了性能
可拦截applyownKeyshas等13种方法,而Object.defineProperty
可以直接对对象的属性那个进行新增/删除
2、新增了composition API ,可以更好的逻辑复用和代码组织
3、重构了虚拟dom
编译模板时,将一些静态的节点编译成常量
slot优化,slot编译成lazy函数,slot显示权交给子组件
4、代码结构的调整,更便于 tree shaking,使体积更小
5、使用ts替换flow

vuex和vue的双向数据绑定有什么冲突

vuex里的值需要在Mutation里去修改,但是表单双向绑定了该用户修改时会尝试修改vuex里的state值,这在严格模式下会报错

解决方法,使用get和set,set函数内部去调用mutation,

<input v-model="message">
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      this.$store.commit('updateMessage', value)
    }
  }

vue-router中的history模式和hash模式的区别

hash模式url永远带着#号,我们在开发当中默认使用这个模式。
那么什么时候要用history模式呢?如果用户考虑url的规范那么就需要使用history模式,因为history模式没有#号,是个正常的url适合推广宣传。

当然其功能也有区别,比如我们在开发app的时候有分享页面,咱们把这个页面分享到第三方的app里,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式,但是使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人配合让他配置一下apache或是nginx的url重定向,重定向到你的首页路由上就ok啦。

父子组件生命周期的执行顺序

  • 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
  • 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
  • 父组件更新过程
父beforeUpdate->父updated
  • 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

vue和react的区别

  • 数据:
    vue:双向数据绑定和单向数据流。双向数据绑定:DOM元素绑定的data值,当发生改变后,vue的响应式机制会自动监听data的变化重新渲染。单向数据流:当父组件给子组件传递数据的时候,子组件只可以读取而不能修改数据。可以用watch监听数据的更改,再赋给父组件的变量。
    react:单向数据流。DOM元素依赖于state,但改变state不会改变渲染好的DOM,通过setState()才能重新渲染。父组件传值到子组件,如果顶级的props变了,会重新渲染所有的子组件。

  • 虚拟DOM:
    vue:计算出虚拟DOM的差异,在渲染的过程中跟踪每个组件的依赖关系,不会重新渲染整个组件树
    react:当应用的状态改变时,重新渲染全部子组件,可以通过shouldComponentUpdate生命周期进行优化

  • 模板和jsx:
    vue:具有单文件组件,可以把html、css、js写在一个vue文件里----MVVM框架
    react:依赖于jsx,在JavaScript中创建DOM----视图层框架

你都做过哪些Vue的性能优化?

  • 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
  • v-if和v-for不能连用
  • 如果需要使用v-for给每项元素绑定事件时使用事件代理
  • SPA 页面采用keep-alive缓存组件
  • 在更多的情况下,使用v-if替代v-show
  • key保证唯一
  • 使用路由懒加载、异步组件防抖、节流
  • 第三方模块按需导入
  • 长列表滚动到可视区域动态加载
  • 图片懒加载

内存溢出 内存泄露

内存溢出:是一种程序运行出现的错误; 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误

内存泄露:占用的内存没有及时释放; 内存泄露积累多了就容易导致内存溢出


父组件向下(深层)子组件通讯

通过provide/Inject,向子组件注入属性或者方法

相关文章

网友评论

      本文标题:vue相关

      本文链接:https://www.haomeiwen.com/subject/eaiwhktx.html