Vue基本使用
0.Vue认识
- MVVM模式。
- 双向绑定(响应式):observer-watcher实现vm到v的数据更新;Dom事件监听实现v到vm的数据更新;
- 渐进式:(1) 如果你已经有⼀个现成的服务端应⽤用,你可以将vue 作为该应⽤的⼀部分嵌入其中,带来更加丰富的交互体验;(2) 如果你希望将更多业务逻辑放到前端来实现,那么VUE的核⼼库及其⽣态系统也可以满⾜你的各式需求(core+vuex+vue-route)。(3) 如果我们构建⼀个大型的应⽤,在这一点上,我们可能需要将东⻄分割成为各自的组件和文件,vue有⼀个命令⾏工具,使快速初始化一个真实的工程变得非常简单(vue init webpack my-project)。对VUE的使用可大可小,它都会有相应的⽅方式来整合到你的项目中。所以说它是一个渐进式的框架。
- 对比AngularJS:
- 响应式的不同做法:vue使用观察者-订阅者模式,每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。观察是指使用Object.defineProperty在getter中通过dep.depend方法收集依赖,在setter可以通过dep.notify方法获取收集到的依赖,然后订阅是指触发render来更新语法树,将值得改变赋值到虚拟DOM,实现部分组件更新。angularJS使用脏值检查,通过scope的数据是否有变更,但只有在指定的事件触发时进⼊入脏值检测,如点击、输入、选择等用户操作;手动调用digest(),timeout;使用ng-click(angular内部帮我们执行了rootScope到各$scope遍历比对所有scope,有变化则更新值和进行页面重绘。
1.深入响应式原理
- 当Vue进行实例化时会对data中的属性进行getter和setter的改写,才是响应式的;Vue可以实现对已经在data中声明的数组和对象的动态监听;所以需要响应式的属性务必在data中声明。
- 对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property,会报错。
- 数组:Vue 对数组的常用方法改写了原型,可以实现响应式,但不能检测包括通过下标索引修改数组和更改数组length这两种变动。可以通过
Vue.set(arr,index,value)或者vm.arr.splice(index,1,value)来实现对数组某一位修改的响应式。用vm.splice(newLength)来实现对数组长度修改的响应式。 - 对象:可以向嵌套对象添加响应式 property,需要使用Vue.set或者set(object,property,value);`
obj = Object.assign({},this.obj,{a:1,b:2});
- 异步更新(DOM)队列:当修改响应式属性时,组件并不会立即被渲染,因为VUE在设计的时候,对于更新DOM是异步的执行的,监听到数据变化时,vue会开启一个队列,并缓存在一次事件循环中发生的所有变更,如果一个watcher(组件)在该次事件循环中被前后多次触发也只会被推入一次队列记入所有的数据变动(这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的),然后在下一次事件循环'tick'中更新组件。如果想要在更新了响应式属性后又需要确保DOM也同步更新了(产生了效果)再取用,则需要使用
this.$nextTick(()=>{}),回调函数将在DOM更新完成后被调用。
2..sync操作符
实现组件属性值props由子组件到父组件的绑定。适用于子组件也会修改状态值的情况。是一个会被扩展为一个自动更新父组件属性的 v-on 侦听器。
<text-document :title.sync="doc.title"></text-document>
当子组件需要更新 title 的值时,它需要显式地触发一个更新事件:
this.$emit('update:title', newValue)
PS:组件中使用v-model默认将值赋予props的value属性。
PPS:在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。
PPPS:props属性验证,注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。
3.ref注册引用
为子组件指定一个索引 ID,给元素或者组件注册引用信息。refs是一个对象,包含所有的ref组件。方便取DOM和操作DOM,减少获取dom节点的消耗;非响应式的,避免在模板和计算属性中使用。PS:$表示refs为vue对象,而不是普通的js对象。
4.标签的is属性
用于动态组件和解除特定标签对于内标签的限制。
- 动态标签:通过使用保留的
<component>元素,动态地绑定到它的is特性,我们让多个组件可以使用同一个挂载点,并动态切换。
- 由于table、ul、ol等标签内无法插入自定义标签,只能插入特定标签,所以使用is属性带入
5.slot分发内容
6.scope 作用域
7.vm.listener
8.子组件根元素禁用Attribute继承
在子组件的选项中设置inhertAttrs:false,该选项不会影响style和class的绑定
9.在组件上使用v-model
<input v-model="searchText">
等价于:
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
当用在组件上时,v-model 则会这样:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
为了让它正常工作,这个组件内的 <input> 必须:
- 将其
valueattribute 绑定到一个名叫value的 prop 上 - 在其
input事件被触发时,将新的值通过自定义的input事件抛出
写成代码之后是这样的:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
现在 v-model 就应该可以在这个组件上完美地工作起来了:
<custom-input v-model="searchText"></custom-input>
10.图片懒加载
使用vue-lazyload插件v-lazy指令,可全局配置默认图和失败图也可局部配置。
11.自定义指令v-crop
1.keep-alive(内置抽象组件)
-
内置抽象组件
-
actived和deactived生命周期,嵌套触发
-
完整生命周期
-
局部内容缓存
- include属性:字符串或正则表达式,只有匹配(名称)到的组件才会被缓存
- exclude属性:字符串或正则表达式,任何匹配(名称)到的组件都不会被缓存
- 页面缓存
- 固定:配置路由,增加属性
meta对象中的keep-Alive属性,且可以通过$route.meta.keepAlive获取,并依次对<router-view>做区分达到统一站点页面是否需要缓存可配的效果。 - 动态:某页面需要根据跳转情况动态配置缓存的话,需要使用导航守卫钩子
beforeRouteLeave(to,from.next)中设置to.meta.keepAlive
- 使用
keep-alive会额外触发activated和deactivated生命周期 - 前进刷新,后退缓存
- 记录页面滚动位置
2.watch和computed区别及应用场景
-
区别:computed具有缓存,可补充setter;
-
应用场景:computed:(1)当对于数组中的各项需要处理或者过滤展示时,不方便使用
v-for直接处理,可定义计算属性过滤排序等加工,使用计算后的属性,而对于不适用计算属性的多层for嵌套情况,内层需要过滤排序等可以额外使用方法;<ul v-for="set in sets"> <li v-for="n in even(set)">{{ n }}</li> </ul> data: { sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]] }, methods: { even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } }(2)可以监听多个响应式属性的变化;
3.修饰符
- 表单修饰符:v-model.lazy,v-model.number,v-model.trim
- 事件修饰符:事件流的三个阶段: 捕获阶段 处于目标阶段 冒泡阶段。
默认是冒泡阶段触发事件。@click.once,@click.stop,@click.self,@submit.prevent,@click.capture,@scroll.passive。修饰符可以串联使用,优先级从左到右。
5.事件处理方法
event 是原生 “DOM 事件”。即操作DOM是触发。
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法。
4.Vue深度监听
5.Vue父子组件传值
props/emit
children
6.nextTick且与setTimeout的比较
nextTick将回调延迟到下次DOM更新循环之后执行
setTimeout则是宏任务的下个队列
7.vue diff
8.vue基本原理
9.vue怎么做优化
10.children
当前组件树的根 Vue 实例。
当前实例的直接子组件。
11.虚拟DOM
12.依赖收集
核心插件—Vue Router
1. 单页应用与多页应用:
SPA 需要路由系统,这也就是 Vue-Router 存在的意义(还记得router-view吧这个路由都塞在一个局部位置,整个的html只在第一次进入请求)。前端做路由的核心,就在于JS可以感知url的变化,改变视图的同时不会向后端发出请求,只是JS的重新渲染,需要额外使用SSR做搜索引擎优化,可以使用Vuex传递数据做状态管理。多页面应用是不同于单页面应用的一种架构设计,在一个项目中,可以使用entry配置多个html文件来实现多页面应用也可以维护每个项目的template.html,并为头部注入用户信息,并且单独构建一个common项目,统一维护第三方依赖。使用的技术和框架等都还是常用的那些。
2. 路由hash模式与history模式的区别:超详细易懂
3. 动态路由匹配与路由组件传参:
可以通过route.query可以获取路由的query参数
4. 嵌套路由:
即在某外层路由页面内仍使用,并在路由配置属性中增加children字段配置子路由
5. 导航路由:
6. vm.$router:
vm.$router.push()
vm.$router.replace()
vm.$router.go(n)/back(n)表示前进或者后退多少步,类似window.history.go/back
7. 命名视图:
对于一个页面需要展示多个视图可以对视图命名,并在路由配置中增加components配置选项。(当然,这些也可以直接通过组件来实现)
8. 重定向路由与别名:
路由配置选项中使用redirect属性;设置别名属性alias可以对路由名称进行简写。
9. 导航守卫:
- 全局守卫:router.beforeEach(),router.beforeResolve(),router.afterEach()
- 路由独享守卫:路由配置中增加beforeEnter
- 组件内守卫:vue实例内增加berforeRouteEnter, berforeRouteUpdate,berforeRouteLeave等
- 全局,路由独享,以及组件内的守卫三者之间是有一定的触发顺序穿插进行的
10. 过渡动效:
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果;使用vue提供的transition封装组件