- //1.Vue是什么:
一套用于构建用户界面的渐进式JavaScript框架(渐进式:从轻量到小巧的核心库逐渐进入到各式各样的Vue插件库)
2.Vue的特点:
采用组件化模式,提高代码复用率、且让代码更好维护(一个.vue文件就是一个组件)
声明式编码,让编码人员无需直接操作DOM,提高开发效率(之前是命令式)
使用虚拟DOM+优秀的Diff算法,尽量复用DOM节点(diff算法是虚拟dom中比较是否有相同的元素从而进行保留复用)
3.安装Vue
下载开发版本:包含完整的警告和调试模式
生产版本:删除了警告,并进行压缩(项目上线用生产版本)
下载vue开发者工具引入chrom插件 ,
引入代码关闭提示
//阻止vue在启动时生成提示
用了live sever之后系统会在本机5500端口号开启一个小服务器,会将所有的工程文件都作为这台服务器的根资源去使用。系统会自动向5500服务器发请求 去要页签图标,没有页签图标的话会默认报错

要结决的话在根目录上传ico形式的页签图标
4.初始vue:
选择器名一般写给父元素
- 想让vue工作,必须创建一个vue实例,且要传入一个配置对象
- root容器里的代码依然符合html规则,只不过混入了一些特殊的Vue语法
- root容器里的代码被称为【vue模板】
- Vue实例和容器是一一对应的
- 真实开发中只有一个vue实例,并且会配合组件一起使用
- {{xxx}}中的xxx要写js表达式, 且xxx可以自动读取到data中的所有属性
- 一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新:
5.模板语法:
Vue模板语法有2大类:
- 插值语法:
功能:用于解析标签体内容。
写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
- 指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件)举例:v-bind:href=”xxx”或简写为
:href=”xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性。
备注:Vue中有很多的指令,且形式都是:v-???,此处我们只是拿v-bind举个例子。
指令语法:
v-bind: 可以给标签里的任何属性动态的绑定值
v-bind:可以简写为 :
差值语法用来指定标签体内容,指令语法用来指定标签(属性、绑定事件、标签体内容)

6.数据绑定
Vue中有2种数据绑定的方式:
- 单向绑定(v-bind):数据只能从data流向页面。
- 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
备注:
- 双向绑定一般都应用在表单类元素上(如: input,select等)
- v-model:value可以简写为v-model,因为v-model默认收集的就是value值。


7.data与el的2种写法
- el有2种写法
(1).new Vue时候配置el属性
(2).先创建Vue实例vm,随后再通过vm.$mount(‘#root’)指定el的值。
- data有2种写法
(1).对象式
(2).函数式:data函数中返回一个对象
应如何选择:目前哪种写法都可以,以后学习到组件时, data必须使用函数式,否则会报错。
- 一个重要的原则:
由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数, this就不再是Vue实例了。
8.MVVM模型

MVVM模型1. M:模型(Model): data中的数据 2. V:视图(View):模板代码 3. VM:视图模型(ViewModel): Vue实例观察发现:
1.data中所有的属性,最后都出现在了vm身上。
2.vm身上所有的属性及Vue原型上所有属性,在Vue模板中都可以直接使用
9.Object.defineProperty()
“Object.defineProperty() 直接在一个对象上定义一个新属性,或者修改现有属性,并返回该对象。
10.数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作做(读/写)
Vue中的数据代理:
Vue中数据代理的好处:
基本原理:
vm._data = data完全就是一个 实例对象vm从构造函数上保存下来的 数据代理也是操作vm._data
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
给vm中的添加name属性值为get(){return data.name }和set(value){ data.name=value }
11.事件处理
模板:v-on:click=”showInfo” 或者@click = “showInfo”
实例:methods:{
showInfo(event){
console.log(event.target.innerText)
console.log(this)//this就是vm,一般接受了vue的管理的函数为一般函数,不要写箭头函数
}
}
参数回传 @click = “showInfo(66,$event)”//不能把event搞丢了 需要用$event占位
实例:methods:{
showInfo(number,event){
console.log(number )
console.log(event.target.innerText)
console.log(this)//this就是vm,一般接受了vue的管理的函数为一般函数,不要写箭头函数
}
}
函数没必要做数据代理不用再改, 不用写在data中
12.事件修饰符
@click.prevent就是e.preventDefault取消事件默认行为,阻止a标签跳到其他页面
@click.stop 就是e.stopPropagation 阻止事件冒泡 在vue中@click.stop就可以阻止冒泡 ,给被点击本元素添加 阻止向外冒泡
@click.once:事件只触发一次
@click.capture:将事件捕获到自己身上
@click.self:只要event.target是当前操作的元素时才能触发事件
@click.passive 事件的默认行为会立即执行,无需等待事件回调执行完毕 移动端用的多
@scroll 给滚动条加的滚动事件 @wheel给滚轮绑定的滚动事件
修饰符可以连着写 如先阻止冒泡 后取消默认事件 @click.prevent.stop


13.键盘事件
模板中:@keyup和@keydown = “showInfo”
键盘事件后面的修饰:(都是别名) 就是当按下修饰键时触发函数中的事件
@keyup.enter 回车、delete删除、esc退出、space空格、tab换行、up上、down下、left左、right右
其他键修饰:由多个单词组成的 全部小写 两个不同的单词用-连接,不是说键盘所有的键可以绑定事件
tab键比较特殊 按下它 会把当前光标从自己身上移走,所以用@keyup.tab时 光标会移走 不会出现按下按键后响应的结果所以@keydown.tab时才好用
修饰键:ctrl、alt、shift、win 配合keyup和keydown都可以用,但是 配合keyup时:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。 但是@keyup.ctrl.y这样就只能按下ctrl和y才会起作用
配合keydown时 正常触发事件
也可以用keycode(键码)去绑定事件触发,不推荐
Vue.config.keyCodes.自定义键名 = 键码 可以去定制按键别名 不推荐
14.计算属性原始写法
模板中{{fullname()}} 意思是将fullname方法的返回值放在这了 只要对页面的数据进行了修改,fullname函数就会重新调用
只要data中的数据发生改变,vue会重新解析模板 只有重新解析模板 模板才会知道什么地方发生了改变,从而进行更新。
15.计算属性
计算属性:<br /> 1.定义:要用的属性不存在,要通过己有属性计算得来。拿着已经写好的属性 去加工去计算最后生成**全新的属性**<br />计算过程**配置成对象** 用get和set操作<br />**get有什么作用,当有人读取fullName时,get就会被调用,且get的返回值作为fullName的值**<br />** 2.原理:底层借助了Objcet.defineproperty方法提供的getter和setter。**<br />** 3.get函数什么时候执行?**<br />** (1). 初次读取时会执行一次。**<br />** (2). 当依赖的数据发生改变时会被再次调用。**<br />** 4.优势:与methods?实现相比,内部有缓存机制(复用),效率更高,调试方便。**<br /> 5,备注:<br /> 1,**计算属性最终会出现在vm上,直接读取使用即可。**<br /> 2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。<br />注意:<br />**仔细看模板中写的是 data中的属性 还是methods中的方法 还是computed中的计算属性来判断模板中的数据加不加括号.**<br />**get里面的this指的是vm,所以要在get中读取vm下的属性 直接用this**.<br />data里的属性是放在 vm._data中 而最终通过数据代理将属性直接放在vm上, **而计算属性通过将原始数据计算后直接将结果返回给fullname放在vm身上 所以可以直接用差值语法使用{{fullname}}**<br />get什么时候调用:初次读取fullName时(会存缓存,读取好多次时只调用一次get);所依赖的数据发生变化时(所依赖的数据:this.fullName算全名时被用的数据)<br /> 在data中和methods中 写什么属性 vm中就有什么属性(通过数据代理拿到);但是在computed中属性不会在vm身上,**而是将属性内部的get()返回值放在vm身上,放的时候名字叫fullname 值为get的返回值 vm.fullname**<br />set什么时候调用:当fullName被修改时,**当用set修改时 直接修改data中的属性 在vm身上,也是get所依赖的属性 修改后会发生变化**<br /><br />
16.天气案例

技巧:模板里可以直接写简单的表达式 只要是vm下的式子 都可以执行,所以可以在{{}}里面写{{isHot = !isHot}} vm上没有window没有alert 可以传一个window进去然后 再window,alert
坑:只要vm上的执行结果在模板里面没有接收的话 在开发者工具里面修改 值的话 是不会发生改变的 实际上是变了 只是没有显示出来
17.监视属性
watch是一个配置对象 监视谁属性的名字就是谁 被监视属性的值是一个对象 methods中的方法也可以进行监视 。
监视的作用是对数据进行检测 然后做一个新旧值对比 最后做一些逻辑。
watch:{
isHot:{
//handler什么时候调用? 当isHot发生改变时
handler(newValue,oldValue){
//修改之前oldValue是true,修改之后newValue是false
}
immediate:是布尔值 默认值为false //初始化时让handler调用一下
}
}
})

明确知道要监视谁用以上的方式
如果不知道啥时候监视,最后想起来要监视哪个属性的话 用vm.$watch(‘isHot’,{})
方法体和上述的一样 isHot本来就是键名 用引号
18.深度监视
深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。
19.监视简写属性
当没有其他配置项的时候就可以进行简写,有以下两种方式,计算属性也可简写
20.watch与computed对比
computed和lwatch之间的区别:
一般情况下 用计算属性比较简便
1.computed能完成的功能, watch都可以完成。
2.watch能完成的功能, computed不一定能完成,例如:watch可以进行异步操作。(计算属性中不能开启异步任务来维护数据,无法做到将异步任务的返回值,等一等之后交给计算属性当返回值;但是watch可以 因为watch不是靠返回值,靠的是亲自修改)
两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。(要用到vm)
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数。这样this的指向才是vm或组件实例对象。(没学Vue时这些函数的this的指向就是window,但是在这里需要指向vm)
21.绑定class样式
:class是v-bind:class的意思
1.字符串写法。适用于:样式的类名不确定,需要动态指定
2.数组写法。适用于:绑定样式的个数不确定,名字也不确定
3.对象写法。适用于:绑定样式的个数确定,名字也确定,但是要动态决定用不用
22.绑定style样式
class样式写法:class=”xxx”xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用style样式:style=”styleObj”其中styleObj是Vue实例中的样式对象。 里面的值 fontSize这些必须是css中实际存在的,原生有短线连接的 去掉短线单词之间用驼峰命名法。

23.条件渲染
条件渲染:
1.v-if写法:适用于:切换频率较低的场景。
(1).v-if=”表达式”
(2). v-else-if=”表达式”
(3).v-else=”表达式”
v-if v-else-if 用的情况能好一点 因为可以不能进行过多次的判断 一组多个判断用v-if v-else-if
特点:不展示的DOM元素直接被移除。
注意: v-if可以和:v-else-if,v-else一起使用,但要求结构不能被“打断”。
2.v-show写法: v-show=”表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
切换频率比较高的时候 用v-show 因为v-show会保留标签节点 底层是display:none
v-if会彻底删除节点
当data中的数据发生改变时 整个模板需要重新解析
v-if与template标签的配合使用 当符合一定条件时 这个标签里的子元素都会显示

24.列表渲染
用遍历这种方式去生成同样结构的数据,必须给每个数据去绑定唯一标识 :key=”p.id”
for of和for in可以遍历 数组 对象 字符串 遍历指定次数
25.key的作用与原理
key的原理:给节点标识 相当于身份证号码。
所有元素的key都是被Vue底层自用 不会在元素页面显示
如果往数组的最后面用push的话 不写key不影响,系统自动补一个key:index
面试题: react、vue中的key有什么作用? (key的内部原理)
1. 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
2. 对比规则:
(1). 旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虚拟DOM中内容没变,直接使用之前的真实DOM!
②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM.
(2). 旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
3. 用index作为key可能会引发的问题:
1.若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
2.如果结构中还包含输入类的DOM:
会产生错误DOM更新==>界面有问题。
4.开发中如何选择key?
1,最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
26.列表过滤
v-model拿到用户输入—在keyWord中实现双向绑定 放在data里—用watch监视keyword —
当输入的值发生改变后 将输入的值在原始数据中匹配的元素 返回 放到新的数组中 一定不能改变原数组
—但是用监视属性为了避免用输入为空时 匹配到所有的元素 所以一开始就让执行一次让全部显示出来 里面用immediate:true;
计算属性方法实现:
监视属性方法实现:
27.列表排序
对匹配好的数据先不要返回,给每一个button都写一个表达式 click = 1 当点击这个按钮时开始排序,将排好序的数组返回给arr。sort()方法会返回排列好的数组,会改变原数组
当点击相应的按钮时会进行排序是因为 我们改的是 data里的click,并且在计算属性中也用到了 click 模板会重新进行解析按照排好序的顺序解析,当点击原顺序时 因为click没有做修改一直是0,所以模板不做解析,不重新排列
28.更新时的一个问题
但是当点击按钮时 确实是改了信息 但是Vue没有检测到数组里数据的变化,所以页面没有任何更改的显示
这与Vue底层的检测数据方式有关系
解决:需要用到vue上自己的操作数组(能够改变原数组)的方法,因为数组里的元素 默认没有添加setter方法 不会导致页面的更新
解决:
29.Vue检测数据的原理_对象

加工就是将data里面的数据加工成getter和setter的写法
最后name只要一改 就调用vm._data中name的setter 调用完之后data中的数据发生改变 就要重新解析模板 就会生成新的虚拟dom 最终新旧虚拟dom进行对比 最后更新页面
模拟加工过程:

其中vue底层会实现递归 只要data中有对象 哪怕是对象嵌套,都会为所有的对象属性进行getter和setter,vue检测数据的原理就是set 只要将vm上的_data属性进行修改 那么就会重新解析模板 生成虚拟dom 生成对比
加工就是把data中的每一组 key和value都写成 getter和setter的写法 只有加工了才能形成响应式(数据变了 页面就会变)
如果模板在Vm中读取的是一个undefined那么 页面不会展示
30.Vue.set()方法
以后想往vm上添加的数据 不能直接添加(vm.student.sex=”男”)因为没有底层监视 没有加setter 所以不做响应式 不会在页面显示,只有一开始加入data中经过处理的属性 才会在页面进行显示
用Vue.set(target,”属性名”,”属性值”)或者vm.$set(target,”属性名”,”属性值”)
vue.set只允许给data里的对象追加属性 不允许给data直接加属性
31.Vue检测数据的原理_数组
数组里每一个元素不是靠set和get实现监视的 所以说通过操作数组里的索引值改变数组元素是不会在页面显示的
那如果要操作数组就要用 能够改变原数组的方法(push、pop、shift、unshift、splice、reverse、sort)
但是对于不能改变原数组的方法如 filter() slice() concat()这些方法的返回值用原数组接收 就可以改变原数组
如果通过以上方法给数组里添加的元素是对象 那么里面的对象会自动实现get和set,那么操作数组里的对象依然可以用数组索引值去操作数组中的对象,也就是说数组本身没实现get和set但是如果数组里的数据是对象,那么对象实现了get和set便可以用数组下标去寻找 数组中的对象从而对属性进行操作
原理:
但这些方法不是原生方法不是一般数组原型上的方法 而是Vue内部写的方法 但是Vue内部的方法 做了两件事
第一件事正常调用原生数组方法 第二件事重新解析模板引发视图的更新
也就是说Vue上的数组方法是包装数组身上的常用数组的方法实现的
Vue.set也可以操作数组 Vue.set(vm.student.hobby,1,”打台球”),或者vm.$set(vm.student.hobby,1,”打台球”)
32.总结Vue检测数据
数据劫持:做两件事:1.收到数据更改数据set 2. 去解析模板 数据劫持和数据代理都是用Object.definePrototype和setter和getter
计算属性用get和set
Vue监视数据的原理:
- vue会监视data中所有层次的数据。
- 如何监测对象中的数据?
通过setter实现监视,且要在new Vue时就传入要监测的数据。
(1). 对象中后追加的属性,Vue默认不做响应式处理
(2). 如需给后添加的属性做响应式,请使用如下API:
Vue.set(target, propertyName/index, value) 或
vm.$set(target, propertyName/index, value)
- 如何监测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事:
(1). 调用原生对应的方法对数组进行更新。
(2). 重新解析模板,进而更新页面。
- 在Vue修改数组中的某个元素一定要用如下方法:
1.使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、
2.Vue.set() vm.$set()
特别注意:Vue.set()和vm.$set()不能给vm或者 vm的跟数据对象添加属性。
33.收集表单数据
注意点:
- 可以在form中指定提交 用@submit = “事件名” 当点击button时它就触发,要想页面不跳转 就.prevent阻止默认行为
- v-model.trim去掉空格
- type是number说明输入框只能输入数字 v-model.number 将你所写的东西转成数字类型,而不是字符串,这两个一般配合使
- 单选框需要指定value,需要指定相同的name把各选项串联起来
- 多选框需要指定value 和 vm中用数组收集数据
- v-model.lazy 不会立刻收集数据 当去掉焦点时收集数据
- 确定阅读一般为多选框的勾选 不需要指定value,只要勾选后会返回true
- console.log(JSON.stringify(this._data))//一次性将数据提交给服务器
- action用于指定表单提交的地址

34.过滤器
过滤器:<br /> 定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。<br /> 语法:
- 注册过滤器: Vue.filter(name, callback)或 new Vue[filters:[])
使用过滤器: ffxxx |过滤器名]) 或v-bind:属性= “xxx|过滤器名”
备注:
过滤器也可以接收额外参数、多个过滤器也可以串联
- 并没有改变原本的数据,是产生新的对应的数据
-
35.v-text指令
v-text指令:
作用:向其所在的节点中宣染文本内容。
- 与插值语法的区别: v-text会替换掉节点中的内容,[[xxx]]则不会。
36.v-html指令
v-html指令:
1. 作用:向指定节点中宣染包含html结构的内容。
2. 与插值语法的区别:
(1). v-html会替换掉节点中所有的内容,{{xxx}}则不会。
(2). v-html可以识别html结构。
3. 严重注意: v-html有安全性问题!!!!
(1). 在网站上动态宣染任意HTML是非常危险的,容易导致xss攻击。
(2). 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
37.v-cloak指令
v-cloak指令(没有值):
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
- 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。 display:none
38.v-once指令
V-once指令:
- v-once所在节点在初次动态宣染后,就视为静态内容了。
- 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
39.v-pre指令
V-pre指令:
- 跳过其所在节点的编译过程。
- 可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
40.自定义指令_函数式
41.自定义指令_对象式
多用来处理细节问题—对象式
自定义指令总结:定义语法:
(1).局部指令:new Vue({directives:{指令名:配置对象}}) 或directives指令名:回调函数)
(2).全局指令:
Vue.directive(指令名,配置对象)或 Vue.directive (指令名,回调函数)
二、配置对象中常用的3个回调:
(1).bind:指令与元素成功绑定时调用。
(2).inserted:指令所在元素被插入页面时调用。
(3).update:指令所在模板结构被重新解析时调用。
三、备注:
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。
注意:
- 如果模板里的表述比较长 v-big-number 不用大写 用-分开 在函数里面就要用 “big-number”(element,binding){} 有-的话Vue中用”big-number”的方式写
- 所有指令中的this指的都是window 因为this是指的是window的dom元素
- 全局指令写法和过滤器一样
42.引出生命周期
Vue在被调用的时候会干很多事情 这一系列的调用 函数被称为生命周期函数
挂载完毕了=》调用mounted函数(vue完成模板的解析并把真实的dom元素放入页面后调用)this已经指向vm
43.生命周期_挂载
44.生命周期_更新
45.生命周期_销毁
46.生命周期_总结
生命周期:
1,又名:生命周期回调函数、生命周期函数、生命周钩子。
2,是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3,生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4,生命周期函数中的this指向是Vm或组件实例对象。
vm的一生(vm的生命周期):
将要创建===调用beforeCreatei函数。
创建完毕===调用created函数。
捋要挂载===调用peforeMount函数。
(重要)挂载完毕==调用mountedi函数。===========【重要的钩子】
将要更新===调用beforeUpdate函数。
更新完毕===调用updatedi函数。
(重要)将要销毁===调用beforeDestroyi函数。====【重要的钩子】
销毁完毕===>调用destroyed函数。
常用的生命周期钩子:
1.mounted:发送ajax请求、启动定时器、绑定自定义事件、订阌消息等【初始化标作】。
2.beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】关于销毁Vue实例,销毁后借助Vue开发者工具看不到任何信息。
2.销毁后自定义事件会失效,但原生D0M事件依然有效。
3.一般不会再beforeDestroy:操作数据,因为即便操作数据,也不会再触发更新流程了。


