目录
入门
1.怎样创建
页面上搞一个模版
New Vue({
关联模版
el:
})
生成vm实例
2.data: 数据 建议 用函数返回值 {}
挂载到哪vm 实例上 可以更新
指令
3.v-on: 绑定事件监听
写法v-on:事件类型=’函数‘
简写 @+事件类型=’函数‘
事件类型:click change input
函数:methods 内的方法
不入参 e内拿到 事件对象
入参 v-on:事件类型=’函数(入参)‘ 不是函数执行 只是为了入参
想要 事件对象 :$event v-on:事件类型=’函数(入参,$event)
事件修饰符 .prevent :取消默认事件 .stop:取消冒泡 .once 修饰优化我们绑定的事件
4.v-model: 双向绑定
v-model:数据
数据变更 视图更新
视图变更 数据更新
用法:收集我们的表单元素的value
给表单元素 加上 v-model:数据
如果 选项是多个的话 给每个选项 绑定value
如果是多选 需要 绑定是数据 需要是数组
5.v-text: 在我们的 文本节点单向绑定数据 v-text="数据 或者表达式"
数据变更 视图更新
简写 {{数据}}
6.v-html:和v-text差不多 多了解析 html的功能
v-html="数据" 如果数据 是一段html 文本 会 解析展示到绑定的 节点处
7.v-if 控制一个元素的 显示隐藏 后面跟一个布尔值 true 显示 false隐藏
原理 :通过控制 元素 的创建和销毁 去控制隐藏显示 耗费性能
频繁切换 建议 v-show
v-else-if
v-else 和if一样
8.v-show 控制一个元素的 显示隐藏 后面跟一个布尔值 true 显示 false隐藏
原理 : 给元素 添加 style=”display:none“ 隐藏元素
9.v-for 循环遍历出 一个元素 生成多个改元素
v-for=”item in 数组数据“ item 是数组的每一项值 可以在 绑定的节点属性和内部 都能拿到
用于 列表 或则 li
10. v-bind 把数据 绑定到我们的属性节点
v-bind:属性名称=”数据或表达式“ 简写 :属性名称=”数据或表达式“
11.methods: 放我们的函数
methods: {
函数,
函数
}
12.computed 计算属性
用法 computed:{
count(){
return 计算的结果
},
count:{
get(){
return 计算的结果
},
每次 改变 计算属性的值 会调用
set(data){
data 是给计算属性 的新值
}
}
}
特点 有缓存 只要依赖数据 不变 我就不去重新计算 走缓存
计算属性可以和data中的状态有关也可以无关,可以修改(很少用)
用法:{{count}}
13.watch 侦听器
作用: 监听数据被改变后 会触发的动作
watch:{
数据名(){
监听到变动时 会触发的内容
}
数据名:{
deep: true,//布尔值
// 深度监听 监听内部所有值
immediate: true,//布尔值
// 让我们handler 上来默认执行一次
handler固定的名称
handler(){
监听到变动时 会触发的内容
}
}
}
特点 : 内部能写异步
14.template: 指定模版
当制定了模版 组件的内容 用模版
不再用 el 或者 $mount关联d的 元素的内容
15.动态类名 和动态样式
通过绑定数据 动态改变 元素上类 和样式
控制元素样式
str="xbox box1"
//字符串
:class="str"
obj={类名:布尔值,类名2:布尔值} 布尔true 表示有这个类 否则无
:class='obj'
arr=[类名,类2] 有那些类名 都绑上
:class='arr'
:style
str="color:red"
:style="str"
obj={属性名:属性值,属性名2:属性值}
:style="obj"
arr=[{属性名:属性值,属性名2:属性值},{属性名:属性值}]
:style="arr"
操作数据 改名页面的样式
16.template 幽灵标签
作用 把一堆标签集合一块
给一推标签元素 提供一个 统一的根元素
实际不存在
组件:
创建VC
Vue.extend({}) 对象内 是我们的配置 和根组件配置一样
template:指定模版
data
methods
computed
watch
内部的this 都指向 vc
注册: 全局:注册一次 随处可以用 局部:哪里用 哪里注册
全局:Vue.component(组件名, 组件值)
使用 类似 html标签用法
<组件名称></组件名称> 去帮我们 new VC 生成一个vc
深入
指令
指令本质是对DOM操作的封装。vue帮我们内置了很多的指令,也可以允许自定义指令。也是把一些常用的DOM操作进行封装,封装成自定义指令。自定义指令的目的:复用
自定义全局指令:Vue.direactive("指令名",{}/fn) 在任意组件中都可以使用自定义全局指令。自定义局部指令:通过direactive选项来自定义局部指令的。只能在当前组件有效
常用自定义指令https://zhuanlan.zhihu.com/p/337659611
插件
在vue生态中,除了vue本身,其它的所有的与vue相关的第三包都是以插件的形式提供。是一种更加高级的代码复用技巧。可以在插件中集成之前说的代码复用技巧。
响应式
vue2中的数据响应式,主要靠defineProperty。当状态发生了变化,肯定会触发set操作,进而触发re-render生成新的虚拟DOM,新旧的虚拟DOM会进行diff运算,找到差异,交给Vue背后更新队列去执行循环更新。说白了就是更新界面。
如果改变data,引发set操作,如果想获取最新的dom,需要使用nextTick。
vue的响应式系统缺陷,组件嵌套的非常深,data的数据结构也非常深,可能会导致响应式系统失效。如果失效需要使用$forceUpdate(); 强制更新
模板编译
模板是vue中非常常用的部分,一个组件通常必备一个模板。模板不是html。模板中有指令,有插值,有JS表达式,
那么模板到底是什么?模板最终肯定需要转化成js代码(render函数)。原生html不识别指令,html是静态标记语言,不具备运算能力。
vue-template-complier将模板编译成render函数。执行render函数生成vnode。在开发环境下,使用webpack的vue-loader,会编译模块。基于vnode再执行patch和diff。
vue的初次渲染过程
第一步:解析模板为render函数
第二步:触发响应式,监听data中的属性,getter和setter
第三步:执行render函数,生成vnode, 进而进行patch(elem,vnode)( 这一步会触发data getter,在getter中进行依赖收集(把数据“观察”起来)注意:不一定是所有的数据都会被观察。是否被观察取决于模板中是否使用。)
第四步:把vnode转化成真实DOM,渲染到页面上。
数据更新过程
第一步:修改数据,会触发data setter
第二步:重新执行render函数,生成新的vnode(newVnode)
第三步:进行patch(vnode,newVnode),patch的过程就是diff的过程
官方解释图链接https://v2.cn.vuejs.org/v2/guide/reactivity.html
异步渲染
进行patch(vnode,newVnode),patch的过程就是diff的过程。找到差异,更新差异,这个渲染是
异步。主要原因是因为可以汇总data的数据变化,一次性渲染,尽量少的减少渲染次数,提高性能。
生命周期
let vm = new Vue({
el: "#app",
// 1)初始化methods中的方法和初始化生命周期的钩子函数
beforeCreate() {
// 不能获取data中的数据 基本项目中没有 在React中,所有的钩子函数都有用,在Vue中,有些钩子函数基本上没有
console.log("beforeCreate.....");
},
// 2)注入一些数据,初始化响应式系统,响应式系统是发生创建组件实例阶段
created() {
console.log("created.....");
// 1)发ajax请求 2)获取路由参数...
},
// 找模板 先看有没有el选项,如果有,再看有没有template选项,如果有,template就是模板,如果没有,el的Outhtml就是模块。会把模板变成render函数,内部会调用render函数,生成虚拟DOM。虚拟DOM转化成真实DOM,进行挂载。
beforeMount() {
// 在项目中,基本上没什么用
console.log("beforeMount.....");
},
// 1)发ajax请求 2)开定时器 3)DOM操作 4)建立ws连接 5)实例化echarts实例 ....
mounted() {
console.log("mounted.....");
},
// 数据变化,一定会触发beforeUpdate
// 监听器:数据变化,也可以监听到
// 监听器能实例的逻辑,按理说在beforeUpdate和updated也可以实现,只不过代码逻辑就复杂
// 在React中,是没有监听器的,在React中监听器就是靠ComponentUpdated
beforeUpdate() {
console.log("beforeUpdate.....");
},
// 要生成新的虚拟DOM,新的虚拟DOM和老的虚拟DOM就会进行DIFF算法对比差异
// 通过patch,会找到两个虚拟DOM树的最小差异,找到后,进行异步更新
// nextTick有什么用?....
// 当v-for时,为什么要加key? 有了唯一的key,就可以尽快的找到的新旧虚拟DOM树的差异,快速更新DOM。
updated() {
// 基本上不用,假如没有监听器,数据变化我们要做一些事件,只能像React一样,逻辑只能写在Updated中
// 在updated中不能更新数据了,会导致死循环
console.log("updated.....");
},
// 什么操作会导致组件销毁?
// 1)手动调用 $destory()
// 2)路由切换
// keep-alive 动态组件 ....
beforeDestroy() {
// 清空定时器 解除事件绑定 清缓存...
console.log("beforeDestroy.....");
},
// 移除当前组件的watcher
// 移除所有的子组件
// 移除所有监听器
// 数据变了,响应式系统就失效了,DOM就无法更新了。
destroyed() {
console.log("destroyed.....");
},
组件通信汇总
1)父子组件通信:父传子使用自定义属性(props),子传父使用自定义事件($emit())。
2)状态提升:当兄弟组件之间需要共享数据时,我们通常的做法是把这个数据定义它们的共同的父组件中,再通过自定义属性实现数据共享。
3)provide/inject:这是在组件树中,自上而下的一种数据通信方案,也就是说只能父级组件中向后代组件传递。需要注意的是,当provide提供动态数据(声明式变量)时,动态数据发生变化,后代组件们不会自动更新。这是为什么呢?你自己从生命周期流程的角度去思考。
4)ref通信:ref是Vue内置的一个属性,每一个HTML元素或组件都有这个属性;ref作用在HTML元素上得到DOM实例,ref作用在组件上得到组件实例。使用ref访问组件实例,进一步可以访问组件中的数据和方法。
5)插槽通信:借助<slot>组件实现从子组件向父组件传递数据,借助this.$slots访问父组件中的插槽实例。(在自定义组件中使用this.$slots访问父组件给的插槽实例;在父组件插槽中使用#default='scoped'访问子组件<slot>回传的数据。这种通信在组件库中、工作中,非常常见!)
6)$parent/$children:借助$parent/$children可以实现,在任一组件中访问组件树中的其它任意组件实例,可以做到在组件中随意穿梭。($parent表示的是当前组件的父组件实例,$children表示的是当前组件的子组件们。)
7)$attrs/$listeners:借助$attrs可访问父组件传递过来的自定义属性(除了class和style外),借助$listenrs可以访问父组件给的自定义事件。在某些场景下,$attrs/$listeners可以替代props/$emit()这种通用的通信方案。
8)事件总线:借助于Vue内置的事件系统($on/$emit/$off/$once)实现“订阅-发布”式的通信,这种通信方式是一种与组件层级无关的“一对多”的通信。
9)Vuex通信:这是Vue架构中终极的通信方案,也是Vue架构中用的最多的一种通信方案。