文章目录
1. vue基础
1. 基本原理:
当一个Vue实例创建时,Vue会遍历data中的属性,用 Object.defineProperty(vue3.0使用proxy )将它们转为 getter/setter,并且在内部追踪相关依赖,在属性被访问和修改时通知变化。 每个组件实例都有相应的 watcher 程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。
2. 双向数据绑定:
Vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
数据发生变化,视图也就跟着更新;视图发生变化,数据也会同步更新
3. Computed 和 Watch 的区别
都是用来监听数据变化的属性
Computed:
- 支持缓存,只有依赖的数据发生了变化,才会重新计算
- 不支持异步,当Computed中有异步操作时,无法监听数据的变化
- computed的值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data声明过,或者父组件传递过来的props中的数据进行计算的。
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他的属性,一般会使用computed
- 如果computed属性的属性值是函数,那么默认使用get方法,函数的返回值就是属性的属性值;在computed中,属性有一个get方法和一个set方法,当数据发生变化时,会调用set方法。
Watch:
- 不支持缓存,数据变化时,它就会触发相应的操作
- 支持异步监听
- 监听的函数接收两个参数,第一个参数是最新的值,第二个是变化之前的值
-
监听数据必须是data中声明的或者父组件传递过来的props中的数据,当发生变化时,会触发其他操作,函数有两个的参数:
- immediate:组件加载立即触发回调函数
- deep:深度监听,发现数据内部的变化,在复杂数据类型中使用,例如数组中的对象发生变化。需要注意的是,deep无法监听到数组和对象内部的变化。
深度监听:
监听对象内部属性变化时,直接监听那个属性会发现监听不到变化,因为vm上存在的只有data内的一级属性,外加计算属性。当存在多层属性嵌套时,直接监听内层属性无法做到。
通过外层属性来访问到内层的属性,来监听变化
直接监听整个外层属性,其实监听的是内存地址,内存地址不变,内存地址存的东西再怎么变也不会被监听到。
所以用深度监听就可以实现
总结:
当进行数值计算要依赖其他属性的时候用computed,避免每次取值要重新计算
当在数据变化时执行异步或开销较大的操作时,使用watch
4. data为什么是一个函数而不是对象
JavaScript中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。而在Vue中,更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会相互干扰。
数据以函数返回值的形式定义,这样当每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。避免造成数据污染
5. keep-alive
在组件切换的时候,保存一些组件的状态防止多次渲染,使用keep-alive保存常用的组件
属性:
- include 字符串或正则表达式,只有名称匹配的组件会被匹配;
- exclude 字符串或正则表达式,任何名称匹配的组件都不会被缓存;
- max 数字,最多可以缓存多少组件实例。
6. $nextTick
虽然说vue采用了虚拟dom,但是仍会操作dom,当都dom1发生变化,dom2要从dom1获取数据,发现dom2并未更新视图,要用到$nextTick
- 在数据变化后执行的某个操作,而这个操作需要使用随数据变化而变化的DOM结构的时候,这个操作就需要方法在
nextTick()
的回调函数中。 - 在vue生命周期中,如果在created()钩子进行DOM操作,也一定要放在
nextTick()
的回调函数中。因为在created()钩子函数中,页面的DOM还未渲染,这时候也没办法操作DOM,所以,此时如果想要操作DOM,必须将操作的代码放在nextTick()
的回调函数中。
7.$set(你要改变的数组/对象,你要改变的位置/key,你要改成什么value)
Vue 中给 data 中的对象属性添加一个新的属性时会发现添加成功,但是视图并未更新,是因为在Vue实例创建的时候,并未声明,不属于响应式属性,所以没有触发。
$set()方法相当于手动的去把添加的属性处理成一个响应式的属性,此时视图也会跟着改变了
vm.$set
的实现原理是:
- 如果目标是数组,直接使用数组的 splice 方法触发相应式;
- 如果目标是对象,会先判读属性是否存在、对象是否是响应式,最终如果要对属性进行响应式处理,则是通过调用 defineReactive 方法进行响应式处理( defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 的功能所调用的方法)
8. assets和static的区别
相同点: assets
和 static
两个都是存放静态资源文件。
不相同点:
assets
中存放的静态资源文件在项目打包时,也就是运行 npm run build
时会将 assets
中放置的静态资源文件进行打包上传。而压缩后的静态资源文件最终也都会放置在 static
文件中跟着 index.html
一同上传至服务器。
static
中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。
2. 生命周期
3. 组件通信
- props / $emit
- eventBus中央事件总线
$emit发 / $on接收
- ref / $refs
-
$parent / $children
-
$attrs / $listeners
实现组件之间的跨代通信$attrs
:继承所有的父组件属性(除了prop传递的属性、class 和 style ),一般用在子组件的子元素上$listeners
:该属性是一个对象,里面包含了作用在这个组件上的所有监听器,可以配合v-on="$listeners"
将所有的事件监听器指向这个组件的某个特定的子元素。(相当于子组件继承父组件的事件)
-
依赖注入(provide 发/ inject 收)
-
provide
的书写形式和data
一样 -
provide() {
return { num: this.num };
}
inject: ['num']
-
4. 路由
5. vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
子组件使用时,先通过this.$store找到vuex,然后再找要用到的数据(this.$store.state.msg)
Vuex中所有状态更新的唯一途径是mutation
模块:
- state:存储所有状态的地方
- getter:允许组件从store中获取数据,类似于计算器,会将数据缓存起来,发生变化重新计算
- mutation:唯一可以修改数据的地方,存的是方法(同步)
- action:提交mutation,处理异步 Action 提交的是 mutation,而不是直接变更状态。
- module:允许将单一的store拆分为多个store且同时保存在单一状态树中
什么情况下使用?
不同视图需要依赖统一状态,来自不同视图的行为要变更同一状态
Vuex 和 localStorage 的区别
- vuex存储在内存中
- localstorage 则以文件的方式存储在本地,只能存储字符串类型的数据,存储对象需要 JSON的stringify和parse方法进行处理。 读取内存比读取硬盘速度要快
- Vuex能做到数据的响应式,localstorage不能
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 刷新页面时vuex存储的值会丢失,localstorage不会。
如何在组件中批量使用Vuex的getter属性
使用mapGetters辅助函数, 利用对象展开运算符将getter混入computed 对象中
import {mapGetters} from 'vuex' export default{ computed:{ ...mapGetters(['total','discountTotal']) } }
6.Vue3.0
Vue3.0有什么更新
- 消除了 Vue 2 当中基于 Object.defineProperty ,用Proxy实现
- 组合式api
- 只能监听简单类型的变化,不能监听复杂类型
7. Vue的性能优化
(1)编码阶段
- 尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
- v-if和v-for不能连用
- 在更多的情况下,使用v-if替代v-show
- 使用路由懒加载、异步组件
- 防抖、节流
- 第三方模块按需导入
- 图片懒加载
(2)SEO优化
- 预渲染
- 服务端渲染SSR
(3)打包优化
- 压缩代码
- 使用cdn加载第三方模块