1. v-if & v-show:
v-if 是'真正的'条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建.
v-if 也是惰性的,如果在初始渲染时条件为假,那么什么都不做- - 直到条件第一次为真的时候才会开始渲染条件块,相比之下,v-show
就简单得多- - 不管初始条件是什么,元素总会被渲染,并且只是简单的基于css进行切换.
一般来说,v-if 有更高的切换开销,而 v-show 有更高的出事渲染开销.因此,如果需要非常频繁的切换,那么使用v-show好一点;如果在
运行时条件不太可能改变,则使用v-if 好点.
2. Vue元素
创建一个Vue实例时,需要传入一个选项对象,它可以包含数据(data)、模板(template)、挂载元素(el)、方法(methods)、生命周期钩子(lifecyclehook)等选项
3. Vue的生命周期
1)开始创建
2)初始化数据
3)编译模板
4)挂载DOM->渲染
5)更新->渲染
6)卸载
钩子函数:八个阶段
注:Vue实现响应式不是数据发生变化后DOM立即变化,而是按一定的策略进行DOM的更新
1、$nextTick([callback])方法——在下次DOM更新循环结束之后执行延迟回调
1)created截断访问DOM必须要在$nextTick的回调中才能获取到
2)在修改数据后使用$nextTick,才可以在它的回调中获取更新后的DOM节点
2、$forceUpdate方法——迫使Vue实例重新渲染(不建议滥用)
仅仅影响实例本身和插入插槽内容的自组件,而不是所有子组件
4. 模板语法
差值: {{}}绑定普通文本 v-html指令 输出真正的HTML
指令: v-bind绑定指令 (v-bind:href简化为:href)
v-on事件绑定指令 (v-on:click简化为@click)
v-if/v-else/v-if-else/v-show/v-for/v-model
:class
:style
5.修饰符
修饰符是由开头的指令后缀来表示的
事件修饰符 <form @submit.prevent="onSubmit" /> event.preventDefault()
<button @click.stop="clickEvent" /> event.stopPropagation()
按键修饰符 <input type="type" @keyup.enter="submit" />
.trim修饰符 <input type="type" v-model.trim="dataValue" />
6. computed
计算属性:通常我们会在模板中绑定表达式,模板是用来描述视图结构的,如果模板中的表达式存在过多的逻辑,模板会变的臃肿不堪,维护变得非常困难。因此,为了简化逻辑,当某个属性的值依赖于其他属性的值时,我们可以使用计算属性。
computed VS methods:
1. 计算属性是基于它们的依赖进行缓存的
2. 每当触发重新渲染时,调用方法总会再次执行
computed VS watch:
1. computed监听多个依赖属于发生变化去触发执行函数,偏向于计算、数据的处理
2. watch本质是监听单一依赖属性发生变化去触发执行函数,偏向于属性值的监听
注:在Vue.js0.12.8版本之前,只要读取相应的计算属性,对应的getter就会重新执行。Vue.js0.12.8版本中,在这方面进行了优化,即只有计算属性依赖的属性值发生了变化时才会重新执行getter。
eg: this.item.isSelected属性会变化,而computed会进行缓存,因此一点点击没效果,后将cache属性设置为false即可。
7. vue-router
1)前端路由:直接找到与地址匹配的一个组件或对象并将其渲染出来
2)引入:
3)路由的常用模式:
· Hash 使用URLhash值作为路由,支持所有浏览器
· History 依赖HTML5 History API和服务器配置
路由配置:
4)路由的参数类型:
· $router.params
· $router.query(查询字符串参数)
· $router.meta(常量参数)
5)路由对象router的常用方法
router.push(location, onComplete?, onAbort?)
router.replace(location, onComplete?, onAbort?)
router.go(n)
router.back(n)
8. axios
基于Promise的HTTP库
9. 组件通信
非父子组件的通信
10. Vuex状态管理库
采用集中式存储来管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化
1)优点:共享状态、跟踪状态的变化、统一管理和易维护
2)引入:
3)原理图和核心概念
11. $router和$route的区别
$router——VueRouter实例,提供导航的方法,this.$router.back()
$route——当前router跳转对象,可以获取name/path/query/params等
12. 路由导航守卫
router.beforeEach注册全局前置守卫
13. 页面建的消息通信——嵌套路由
消息发送
消息接收
14. 插件——通常为Vue添加全局功能
添加全局方法或者属性Vue.httpService = httpService;
添加Vue实例方法 Vue.prototype.$httpService = httpService;
添加全局资源:组件/指令/过滤器等 Vue.component('app-header', AppHeader);
通过全局mixin方法添加一些组件选项,如:vue-router
15. v-ref & v-el
v-ref: 在父组件上注册一个子组件的索引,便于直接访问。不需要表达式,必须提供参数id。可以通过父组件的$refs对象访问子组件
v-el: 为DOM元素注册一个索引,方便通过所属实例的$els访问这个元素。可以用v-el:some-el设置this.$els.someEl
16. 样式绑定
DRY(Don't Repeat Yourself)
由于CSS总是充满各种不得不重复的写法,所以推荐使用less,安装webpack支持less编译的包的方法:
安装完成后在webpack.config.js的modules设置内加入以下配置:
注:通过import将样式文件导入是一种全局性的做法,容易导致样式冲突。如果希望样式表仅应用于当前组件,可以使用<style scoped>,然后用CSS的@import当如样式表:
17. 在所有的过滤器中是没有this引用的,过滤器内的this是一个undefined的值,所以不要在过滤器内尝试引用组件实例内的变量或方法,否则会引发空值引用的异常。
18. 服务端获取数据
Vue的标准库并没有提供访问远程服务器(AJAX)功能,所以我们需要安装另一个库-vue-resource。vue-resource并不是Vue官方提供的库,而是有PageKit(https://github.com/pagekit)团队所开发的,它的体积小,学习成本低,是Vue项目中用于访问远程服务器的一个优秀第三方库。
安装: npm i vue-resource -D
引入: import Vue from 'vue'
import VueResource from 'vue-reousrce'
Vue.use(vueResource)
使用:this.$http.get(url).then(res => {
console.log(res);
})
19. Vue组件间共享对象
Javascript语言对象在赋值的时候,是将其引用地址赋值给了一个新的变量,所以改变心对象属性时,会同时改变原对象属性。
20. Vue响应式写法注意点
注意:Vue不能检测到对象昂属性的新增或删除
1)对象属性的修改建议采用this.$set方式
2)数组利用索引赋值采用this.$set(this.dataList, index, newValue)
21. 设计模式——订阅发布模式
1)定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象
2)主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态
22. input type="number"聚焦有问题
23. vux组件库
24. props传入的value值是不允许在子组件中进行修改的,修改的话vue会报错,会改变的两不妨到computed方法里面去,数据层转换,显示的采用computed,比过滤器好用,会进行缓存,data是模型值,用watch监听变化,computed只是用来做展示的
单向数据流:.sync父组件传值给子组件,子组件通过emit事件给父组件传递消息
.sync是个语法糖,最后还是得由子组件发送消息给父组件
25. deep 对象的引用地址不变,vue监听不到变化,需要加上deep,不然属性值变化监听不到
26. $dispatch和$broadcast替换已经弃用,因为基于组件树结构的事件流方式实在是让人难以理解,所以在组件结构扩展的过程中变得越来越脆弱。这种方式确实不太好用,并且$dispatch和$broadcast也没有解决兄弟组件间的通信问题。对于$dispatch和$broadcast最简单的升级方式就是:通过使用事件中心,允许组件自由交流,无论组件处于组件树的哪一层。
父子组件的相互通信。使用v-on监听子组件上$emit的变化。
跨多层父子组件通信,用集中式的事件中间件可以做到简单的升级。
eg: 假设我们有个 todo 的应用结构如下:
Todos ├─ NewTodoInput └─ Todo └─ DeleteTodoButton |
可以通过单独的事件中心管理组件间的通信:
// 将在各处使用该事件中心 // 组件通过它来通信 var eventHub = new Vue() |
然后在组件中,可以使用 $emit
, $on
, $off
分别来分发、监听、取消监听事件:
// NewTodoInput // ... methods: { addTodo: function () { eventHub.$emit('add-todo', { text: this.newTodoText }) this.newTodoText = '' } } |
// DeleteTodoButton // ... methods: { deleteTodo: function (id) { eventHub.$emit('delete-todo', id) } } |
// Todos // ... created: function () { eventHub.$on('add-todo', this.addTodo) eventHub.$on('delete-todo', this.deleteTodo) }, // 最好在组件销毁前 // 清除事件监听 beforeDestroy: function () { eventHub.$off('add-todo', this.addTodo) eventHub.$off('delete-todo', this.deleteTodo) }, methods: { addTodo: function (newTodo) { this.todos.push(newTodo) }, deleteTodo: function (todoId) { this.todos = this.todos.filter(function (todo) { return todo.id !== todoId }) } } |
在简单的情况下这样做可以替代 $dispatch
和 $broadcast
,但是对于大多数复杂情况,更推荐使用一个专用的状态管理层如:Vuex。
27. slot分发内容:单个插槽、多个插槽(具名插槽)、作用域插槽(将子组件的值传到父组件使用)
在使用组件时,常常要像这样组合它们:
<didi>
<didi-header></didi-header>
<didi-footer></didi-footer>
</didi>
注意两点:
1)<didi>组件并不知道它的挂载点会有什么内容,挂载点的内容是由<didi>的父组件决定的
2) <didi>组件很可能有自己的模板
为了让组件可以组合,我们需要一种方式来混合父组件的内容和子组件自己的模板。这处理称为内容分发(或“transclusion”)。Vue.js实现了一个内容分发API,参照了当前Web组件规范草稿,使用特殊的<slot>元素作为原始内容的插槽。
28. 动态组件:多个组件可以使用同一个挂载点,然后动态地在它们之间切换。使用保留的<component>元素,动态地绑定到它的is特性。