- 1.Vue双向数据绑定
- 2.虚拟dom和diff算法
- 3.组件通信
- 4.Vuex
- 5.Vue-router(路由原理,路由守卫,路由传参)
- 6.Vue声明周期
- 7.自定义指令,自定义过滤器
- 8.自定义组件
- 9.常用的指令,修饰符
- 10.vue2.0和3.0的区别
- 11.keep-alive
- 12.多环境变量
- 13.对axios封装(url统一管理,axios请求拦截,响应拦截)
- 14.element-ui、vant-ui 按需引入
- 15.sass配置
- 16.rem,vw/vh 适配
- 17.webpack配置(配置跨域,路径别名,打包分析,cdn引入,去掉console.log,单独打包第三方模块,ie兼容,eslint规范,图片压缩)
- 18.Vue中data为什么是函数
- 19.Let const 和 var 的区别
- 20.冒泡排序
- 21.数组常用的方法
1. vue双向数据绑定原理
vue是采用数据劫持结合发布-订阅
的方式,通过object.defineProperty()
来劫持各个属性的setter
,getter
,在数据发生变动时发布消息给订阅者,触发相应的监听回调来渲染视图
第一步:
需要observer
的数据对象进行递归遍历
,包括子属性对象的属性,都加上setter
,getter
,这样的话,给这个对象的某个值赋值
,就会触发setter
,那么就能监听到数据变化
简单来说就是实现一个数据监听器Observer,它能够对数据对象的所以属性进行监听,如果有变动就可以拿到最新的值并通知订阅者
第二步:
compile
解析模块指令,讲模块中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
简单来说就是实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,替换数据,绑定更新函数
第三步:
Watcher
订阅者时Observer
和Compile
之间的通讯桥梁,主要做的事情是:
1.在自身实例化时往属性订阅器(dep
)里面添加自己
2.自身必须有一个update()
方法
3.待属性变动dep.notice()
通知时,能调用自身的update()
方法,并触发Compile
中的绑定回调
简单来说就是实现一个Watcher,作为Observer和Compile的桥梁,能够收到每个属性变动的通知,绑定相应的回调函数,从而更新视图
第四步:
MVVM
作为数据绑定的入口,整合Observer,Compile和Watcher三者
,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭建起Observer和Compile之间的通信桥梁,达到数据变化->视图更新; 视图交互变化->数据model变更的双向绑定效果
MVVM就是实现Vue双向数据绑定的根本
,MVVM本质上是MVC的改进版,即模型-视图-视图模型
,【模型】
指的是后端传递的数据。【视图】
指的是所看到的页面。【视图模型】
MVVM的核心,他是连接view和model的桥梁
。它有两个方向: 一个是将【模型】转换成【视图】,即后端传递的数据转换成所看到的页面
:实现方式是:数据绑定。第二个是【视图】转化成【模型】,即将所看到的页面转换成后端的数据
:实现方式是:DOM事件监听。这两个方向都实现的话,
我们称之为数据的双向绑定
2.vue虚拟dom,diff算法
虚拟DOM就是为了解决游览器性能问题
而被设计出来的。
就是用对象来模拟dom元素和嵌套关系,指的就是用js对象的形式
,来模拟页面上的DOM嵌套关系
目的:实现页面元素的高效更新,避免大量无谓的计算(若一次操作中有10次更新DOM的动作,虚拟DOM不会立即去操作DOM,而是将10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一个姓attch到DOM树上,再进行后续操作
)
作用:用来比较两次DOM结构
web界面由DOM树(树的意思就是数据结构
)来搭建,当其中一部分发生变化时,其实就时对应某个DOM节点发生了变化
diff算法是作为DOM的加速器
,改进优化了页面渲染的基础和性能保障
用js对象表示dom树结构,用这个树建立一个真正的dom树,插入到文档中,状态更新
,重新构造一棵新树,两树比较差异,把差异应用到真的dom树上,更新视图
3. 组件 通讯
- 回到顶部
1.父传子
父组件是通过props属性给子组件通信的
父组件代码:
<template>
<div>
<h2>{
{
msg}}</h2>
<Son :faMsg="msg"></Son>
</div>
</template>
<script>
import Son from "./Son";
export default {
name:"HelloWorld",
data(){
return{
msg:"父组件"
}
},
components:{
Son}
}
</script>
子组件代码:
<template>
<div>
<h2>{
{
sonMsg}}</h2>
<p>子组件接收到的内容是:{
{
faMsg}}</p>
</div>
</template>
<script>
export default {
name:"Son",
data(){
return{
sonMsg:"子组件"
}
},
props:['faMsg'], //接收faMsg值
//还可以这样,上面的不是很严谨
props:{
faMsg:{
type:String,
default:"123"
}
}
}
</script>
在父组件中给子组件标签上绑定一个属性, 属性上挂载需要传递的值
在子组件通过props:[“自定义属性名”]来接收数据
子传父:
(1) 在父组件中给子组件标签绑定一个自定义事件,给这个事件挂载需要调用的方法
(2) 在子组件的方法通过this.$emit(‘自定义事件名’)来调用这个方法
父组件代码:
<template>
<div>
<h2>{
{
msg }}</h2>
<p>父组件接手到的内容:{