VUE
VUE的基本原理
一个vue实例创建时,会遍历data中的属性,用Object.defineProperty(vue3.0中使用proxy)将它们转化为getter/setter,并在内部追踪相关依赖,在属性被访问和修改时通知变化
每个组件都有相应的watcher实例,它会在组件渲染过程中将属性记录为依赖,当依赖项的setter被调用时通知watcher重新计算,致使关联的组件更新
VUE的优点
轻量级框架
上手快,学习成本低
双向数据绑定,保留了angular的特点,数据操作更简单
组件化,保留了react的特点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势
视图、数据、结构分离,使数据更改更简单
虚拟DOM,操作DOM是非常消耗性能的,不再使用原生的DOM操作节点,极大解放了DOM操作
相较于react运行速度更快
双向数据绑定原理:
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter, getter,在数据变动时发布消息给订阅者,触发相应的回调
单向数据流和双向数据流的理解
-
v-bind和vuex就是单向数据流
如一个父组件有两个子组件,分别为a和b ,父组件向子组件传递数据,两个组件都接收到了父组件传递过来的数据,在组件a中修改父组件传递过来的数据,子组件b和父组件的值不会发生变化 这就是单向的数据流
-
v-model就是双向数据流
Model数据变化会触发View的刷新, View层用户改变数据也会在Model中同步
defineProperty()的使用方法
defineProperty()有三个参数
-
1.将要被修改的对象
-
2.将要被修改的对象的属性
-
3.将要被修改的属性的描述符,就是一个对象,里面有两个属性get和set
var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function () { return this._year; }, set: function (newValue) { if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2
v-model实现原理
v-model实际上是一个语法糖
v-bind绑定value指向message变量
v-on绑定input事件
触发input事件时通过$event.target.value将值赋给message
<input v-model="sth" />
// 等同于
<input
v-bind:value="message"
v-on:input="message=$event.target.value"
>
使用Object.defineProperty()缺点:
无法检测到对象属性的新增或删除 无法监听数组变化, Vue 内部通过重写函数的方式解决了这个问题
vue2.0如何监听数组的变化:
数组
-
this.$set(array, index, data)
//这是个深度的修改,某些情况下可能导致你不希望的结果,因此最好还是慎用 this.dataArr = this.originArr this.$set(this.dataArr, 0, {data: '修改第一个元素'}) console.log(this.dataArr) console.log(this.originArr) //同样的 源数组也会被修改 在某些情况下会导致你不希望的结果 复制代码 -
splice
//因为splice会被监听有响应式,而splice又可以做到增删改。 复制代码 -
利用临时变量进行中转
let tempArr = [...this.targetArr] tempArr[0] = {data: 'test'} this.targetArr = tempA
对象
-
this.$set(obj, key ,value) - 可实现增、改
-
watch时添加
deep:true深度监听,只能监听到属性值的变化,新增、删除属性无法监听this.$watch('blog', this.getCatalog, { deep: true // immediate: true // 是否第一次触发 }); -
watch时直接监听某个key
watch: { 'obj.name'(curVal, oldVal) { // TODO } }
Vue3.0如何解决Object.defineProperty()缺点:
Vue3.0中使用Proxy(对象代理)可以完美的监听到任何数据的变化 缺点:兼容性问题
data为什么是一个函数而不是对象:
javascript的对象是引用类型,多个组件引用同一个data对象时,当其中一个组件修改对象的数据时其他组件的数据也会发生变化
写成函数的形式当组件复用时,就会返回一个新的data,每个组件都有私有数据空间,不会影响其他组件
常见的事件修饰符
.stop 防止冒泡
<div @click="div">
<button @click.stop="button"></button>
</div>
// 当点击button时,先执行button的点击事件,再执行div的点击事件,加上.stop后,就只会执行button的
.prevent 防止执行预设行为
<a href="http://www.baidu.com" @click.prevent="a">百度</a>
// 加上.prevent后,就会阻止默认的跳转行为
.captrue 与事件冒泡的方向相反,事件捕获由外到内
<div @click.capture="div">
<button @click="button"></button>
</div>
// 先触发div事件,再触发button事件
.self 只会触发自身事件,不包含子元素
.once 只触发一次
MVVM、MVC、MVP的区别:
MVC,MVP,MVVM是三种常见的软件架构设计模式, 主要通过分离关注点的方式来组织代码结构
-
MVVM
MVVM分为View、Model、VIewModel
View代表UI视图,负责数据显示
Model代表数据模型,数据和业务逻辑都在Model中定义
ViewModel负责监听Model中数据的改变并且控制视图的更新,处理用户交互操作
Model和View是没有直接联系的 它们是通过ViewModel进行联系的
Model和ViewModel有着双向数据绑定的关系
Model数据变化会触发View的刷新 View层用户改变数据也会在Model中同步
-
MVC
MVC分为Model、View、Controller
View负责页面的显示逻辑
Model负责存储页面的业务数据,以及对数据的操作
Controller层是View和Model的纽带,主要负责用户与应用的响应操作
view发布指令给controller,controller选择model,model驱动view
-
MVP
MVP与MVC唯一的不同点在于Presenter和Controller
MVP通过使用Presenter来实现View层和Model层的解耦,View层的接口暴露给了Presenter,可以实现View和Model的同步更新
MVC中的Controller只知道Model的接口,没有办法控制View层更新
对于axios的理解:
axios是一种基于Promise封装的HTTP客户端,是对ajax的进一步封装
特点:
浏览器端发起XMLHttpRequest请求
node端发起http请求
支持Promise API
可以拦截请求和响应
自动转换成JSON数据
token过期时,在响应拦截器中 的 两种处理方法
方法一:用户有感知,重新登录
在响应拦截器中:当用户token过期,请求响应出现401状态码,在响应之前清除token,强制用户跳转到登录页面,尽行重新登录
方法二:用户无感知,直接获取新的token进行请求
在响应拦截器中:当用户token过期,请求响应出现401状态码,清除token,调用获取新token的接口,将新的token存到本地,然后把新获取的token添加到 error.config.headers ,最后重新发起请求并返回
axios || ajax请求一般放在哪个钩子函数中
一般放在created钩子函数中,因为此时data已经初始化,可以缓存获取到的数据,并且请求比较快,用户体验好
mounted中也可以发送请求,但是由于mounted是在模板渲染成html页面后调用,请求比较慢,如果数据比较庞大,这时候可能会导致页面闪屏
请求拦截器和响应拦截器
请求拦截器可以用来配置公共的请求头,加载弹窗等,示例代码中弹窗使用的mint-UI,也可以使用其他UI框架,注意使用前安装、引入; 请求拦截器 在请求发送前进行一系列操作,例如在每个请求体上加上token,统一做处理,以后要改也容易
响应拦截器可以用来针对后端返回的类型做统一的处理,比如给一些提示;请求拦截里如果加了加载框,这里也可以统一关闭;
响应拦截器 接收响应后进行一系列操作,例如服务器返回登陆状态失效,需要重新登陆,跳转到登录页
ajax、fetch的区别
-
ajax
ajax是一种创建交互式网页应用的网页开发技术
是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术
本质是使用XMLHttpRequest对象来请求数据
它是jquery库里自带的一个方法
-
fetch
fetch是原生js,没有使用XMLHttpRequest对象
基于标准Peomise实现,支持async/await
v-if和v-show的区别:
v-if是动态的向DOM树内添加或删除元素
v-show是通过设置DOM元素的display来控制元素的显示隐藏
v-if有更高的切换消耗
v-show有更高的初始渲染消耗
v-if适合运营条件不大改变
v-show适合频繁的切换
一般权限按钮上会用到v-if
v-for 与 v-if 的优先级
当它们处于同一节点, v-for的优先级比v-if更高 ,这意味着 v-if将分别重复运行于每个 v-for循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:
上面的代码只传递了未完成的 todos。
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或