16
社区成员
vue双向绑定原理:其实就是采用 数据劫持 结合 发布者-订阅者模式的方式。
具体实现方法是:new Vue()先将data中的变量引入对象内部,然后为其添加访问器属性。并且在set()函数中添加通知函数。接着会扫描dom树,将扫描到的可能发生变化的元素,保存到额外创建的一棵虚拟DOM树中。 每次只要我们试图修改变量值时,都会自动调用通知函数,向虚拟DOM树发出通知,虚拟DOM树就会立刻扫描自己。查找所有引用这个变量的元素,然后进行页面的更新。
虚拟dom树:保存可能发生变化的元素。
(1). 小: 只保存受影响的元素,其余元素都不保存
(2). 遍历快: 因为元素个数少,所以遍历快:
(3). 修改效率高: 只更新受影响的元素,不受影响的元素不更新
(4). 避免重复操作: 虚拟DOM树天生封装了原生DOM的增删改查方法.
MVVM
表示的是 Model-View-ViewModel
v-show通过display:none隐藏元素
。v-if是通过删除元素隐藏元素
v-show
由false
变为true
的时候不会触发组件的生命周期;v-if
由false
变为true
的时候,触发组件的beforeCreate
、created
、beforeMount
、mounted
钩子,由true
变为false
的时候触发组件的beforeDestory
、destoryed
方法beforeCreate -> created ->beforeMount -> mounted ->beforeUpdate -> updated -> beforeDestroy ->destroyed
created
是在组件实例一旦创建完成的时候立刻调用,这时候页面dom
节点并未生成;mounted
是在页面dom
节点渲染完毕之后就立刻执行的。触发时机上created
是比mounted
要更早的,两者的相同点:都能拿到实例对象的属性和方法。 讨论这个问题本质就是触发的时机,放在mounted
中的请求有可能导致页面闪动(因为此时页面dom
结构已经生成),但如果在页面加载前完成请求,则不会出现此情况。建议对页面内容的改动放在created
生命周期当中。
v-for
优先级比v-if
高,同时用在同一个元素上,会带来性能方面的浪费(每次渲染都会先循环再进行条件判断)
目的是为了防止多个组件实例对象之间共用一个data
,产生数据污染。采用函数的形式,initData
时会将其作为工厂函数都会返回全新data
对象
路由传参:在router里需要传参的组件的路径上,配置上斜杠冒号(/:)想要传递的变量名,并且设置Props属性值为true,然后在组件中用props接传递过来的变量即可
组件之间的通信方式都有哪些
props
与 $emit
进行传递,也可选择ref
$eventBus
,其次可以选择$parent
进行传递attrs
与listeners
或者 Provide
与 Inject
vuex
存放共享的变量key的作用主要是为了高效的更新虚拟dom
key是给每一个对象的唯一id,可以根据key,更准确, 更快的找到对应的节点
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
生命周期函数:activated
与deactivated
当我们从首页
–>列表页
–>详情页
–>再返回
,这时候列表页应该是需要keep-alive
缓存后如何获取数据
每次组件渲染的时候,都会执行beforeRouteEnter
beforeRouteEnter(to, from, next){
next(vm=>{
console.log(vm)
// 每次进入路由执行
vm.getData() // 获取数据
})
},
在keep-alive
缓存的组件被激活的时候,都会执行actived
钩子
activated(){
this.getData() // 获取数据
},
value
,也就是在change
事件之后再进行信息同步
使用场景:比如组件间的状态共享:登录状态;组件间的数据共享:购物车数据,登录的token
state | 数据存放 |
getters | 相当于计算属性,可以返回一个值 |
mutation | 同步操作,修改数据 |
action | 异步操作 |
modules | 模块化 |
原理:vuex实现了一个单项数据流,在全局又有一个state存放数据,当组件要更改state中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取state数据的更新。而当所有异步操作(常见于调用后台接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改state的,还是需要通过Mutation来修改state的数据。最后根据state的变化,渲染到视图上。
而在vue
项目中,我们主要针对CORS
或Proxy
这两种方案进行展开
proxy 在vue.config.js
文件,新增以下代码
amodule.exports = {
devServer: {
host: '127.0.0.1',
port: 8084,
open: true,// vue项目启动时自动打开浏览器
proxy: {
'/api': { // '/api'是代理标识,用于告诉node,url前面是/api的就是使用代理的
target: "http://xxx.xxx.xx.xx:8080", //目标地址,一般是指后台服务器地址
changeOrigin: true, //是否跨域
pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'用""代替
'^/api': ""
}
}
}
}
}
通过axios
发送请求中,配置请求的根路径
axios.defaults.baseURL = '/api'
var
声明的变量既是全局变量,存在变量提升,不存在块级作用域,允许重复声明变量let
所声明的变量,只在let
命令所在的代码块内有效,不存在变量提升,存在块级作用域,同一作用域不允许重复声明变量const
声明一个只读的常量,一旦声明,常量的值就不能改变,不存在变量提升,存在块级作用域,同一作用域不允许重复声明变量数组解构:从一个大的数组中提取出个别元素单独使用([变量1,变量2,变量3] =数组,数组会自动将相同下标位置的元素值赋值给等号左边相同下标位置的变量)
对象解构:从一个大的对象中只提取出个别属性值和方法单独使用( {属性名1: 变量1, 属性名2: 变量2, ...} =对象,等号左边相同属性名的变量,会自动获得等号右边对象里相同属性名的属性值)
参数解构:定义函数时,多个实参值不确定有没有,而且还要求实参值必须传给对应的形参变量,(定义函数时:将形参变量列表,定义在一个对象结构中;调用函数时:实参值列表也必须装扮为对象结构,且属性名必须和定义时使用的属性名一致)
5.箭头函数: 匿名函数,(即让内部this与外部this保持一致,但是对象的方法和dom中的事件处理函数不能用)
6. ...扩展对象, 取代 Object.assign()
7. Promise: 异步编程的一种方案, 可以用来解决 回调地狱
8. class 面向对象:只要创建一种类型,包含构造函数和原型对象时,都用class代替分开写的构造函数和原型对象
9. set 和 map
map映射:也称dictionary字典,一个键值结构,类似于js的对象类型
set集合:特点为内部元素不重复,会自动去重
10.for of: 只要遍历下标为数字的东西(索引数组、类数组对象、字符串),都可用for of代替其他遍历方式。(只能返回元素,不能控制遍历的步调和方向)
11.参数增强:(...定收调打)
参数默认值(希望一个变量,在函数调用时,即使没有传入实参,也能有默认值使用,在函数定义时,声明默认值)
剩余参数(rest,箭头函数不支持arguments,在使用箭头函数时,遇到不确定实参值个数的情况下,都用剩余参数语法代替arguments,var 函数名=(固定形参, ...自定义数组名)=>{},自动创建的是一个纯正的数组)
拆散数组(只要想打散数组,不想替换this,则可以用...语法代替apply,调用函数时:函数名(...数组),常用语法糖:var arr2=[...arr1];var arr3=[...arr1, 元素值1,...arr2, 元素值2 ])
封装异步操作并可以获取其成功或失败的结果
promise的三种状态
1.pending: 等待中,或者进行中,表示还没有得到结果
2.resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行
3.rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行
Promise.all() 并发处理多个异步任务,所有任务都执行完成才能得到结果
Promise.race() 并发处理多个异步任务,只要有一个任务完成就能得到结果
支持一波