基础
-
data
为啥使用函数返回一个对象
防止多个组件实例共享状态。 -
计算属性vs侦听器
computed
属性具有缓存效果,只有对应的依赖发生变化的时候 才会触发计算,触发更新,相比而言有更好的性能。 -
父子组件通信,兄弟组件通信
① 自定义事件 (针对父子组件)
事件名是完全匹配的,必须和绑定的事件名一致。
② 使用vuex
③ 通过props(针对父子组件) -
生命周期
beforeCreate
// 数据拦截、监听完成 计算属性监听
// watch 和事件回调
// 还没有 render $el 不可见
created
beforeMount
// render调用完成 ,$el 可见
// 不会保证所有的子组件也都一起被挂载 可以使用 vm.$nextTick
mounted
// 数据发生改变,虚拟DOM 打补丁之前
beforeUpdate
// 避免在updated中进行数据修改 (进而触发新的update)
// 这个时候 你可能需要的是 计算属性或者是watcher
updated
// 被keep-alive的组件 激活的时候调用
activated
deactivated
// 组件即将销毁
beforeDestory
destoryed
// 发生异常
errorCaptured
- 父子组件声明周期触发顺序
① 子组件是在render过程中进行初始化操作 所以在父组件的beforeMount 之后 进行触发
② 父组件会在beforeMount
beforeUpdate
之后 进行子组件的生命周期之后 继续触发父组件的声明周期(mounted事件并不保证)。
// 首次渲染
Home component: beforeCreate
Home component: created
Home component: beforeMount
//子组件是在render过程中进行初始化操作 所以在父组件的beforeMount 之后 进行触发
child component: beforeCreate
child component: created
child component: beforeMount
child component: mounted
Home component: mounted
// update操作
Home component: beforeUpdate
child component: beforeUpdate
child component: updated
Home component: updated
-
class
style
绑定
①class
可以是对象 也可以是数组
② 当在一个自定义组件上使用 class 属性时,这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。
③style
可以接收 对象,或者是包含多个对象的数组 -
事件处理
① 绑定事件:v-on
@
② 原生event
获取,内联使用$event
,参数可以通过最后一个参数获取
<div @click="say($event.target.text)"></div>
<div @click="say('ngnice')"></div>
methods: {
say(name, event) {
// code...
}
}
进阶
- 组件
① 组件注册 全局 or 局部
② 通过require.context
后简便的获取指定目录中的所有组件
③ 组件切分的原则:通用、解耦、复用、使用简便,文档清晰。
④ 组件的prop
属性:静态属性一般当做字符串,如果需要传入 数值、布尔值、以及其他对象,需要通过动态属性v-bind
来实现
<compoent-a sum="42"/> // 实际上接收到的是字符串"42"
<compoent-a :sum="42"/> // 实际上接收到的是数值 42
<compoent-a sum="false"/> // 实际上接收到的是字符串 "false"
<compoent-a :sum="false"/> // 实际上接收到的是布尔值 false
<compoent-a sum/> // 实际上接收到的是布尔值 true
// 传入一个对象的所有属性
post: {
name: :"ngnice",
age: 10
}
<compoent-a v-bind="post"/>
等价于
<compoent-a v-bind:name="post.name"/>
<compoent-a v-age="post.age"/>
⑤ 组件必须使用props属性显示的声明 组件依赖的属性,否则不会接收。
-
v-model
自定义
简而言之,v-model
能实现 双向数据绑定
非常适合 组件内外都需要修改状态的情形。
① 定义model
设置 触发的事件和更新的prop
② 添加事件 触发对应的事件和要更新的prop
最新的值
<template>
<input type="checkbox" :checked="checked" @click="clickHandler">
</template>
<script>
/* eslint-disable */
export default {
props: {
checked: Boolean
},
model: {
prop: 'checked',
event: 'aaa'
},
methods: {
clickHandler(e) {
console.log(arguments);
this.$emit('aaa', e.target.checked)
// 直接修改属性的方式 开发环境下 会报警告 并且不会更新成功
// this.checked = !this.checked;
}
}
}
</script>
-
动态组件
① 使用keep-alive
来缓存组件 不用每次重新创建 -
异步组件
异步加载组件:webpack2
和ES2015
语法
components: {
'my-component': () => import('./my-async-component')
}
-
组件化
最终的目的:效率和质量
实现方案:封装、复用、解耦
① 通用基础组件库
② 业务关联组件库(包含特定额业务逻辑) -
插槽
① 让你的组件扩展性更强,复用性更高, 组合更加方便
② 插槽、具名插槽
③ 插槽的作用域
④ 插槽的默认值
高级
- 指令
在不同的钩子函数中进行 不同的处理
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
- 插件
使用Vue.use
使用plugin
一个插件就是一个简单的对象,定义了一个install方法。
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或属性
Vue.myGlobalMethod = function () {
// 逻辑...
}
// 2. 添加全局资源
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// 逻辑...
}
...
})
// 3. 注入组件选项
Vue.mixin({
created: function () {
// 逻辑...
}
...
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
// 逻辑...
}
}
-
mixin
类似于 extend,使用Vue.mixin({...}) 可以使得后面所有的vue实例都生效。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"
-
异步更新队列
在我们修改了view-model
属性的时候,不会立即去执行更新操作,而是通过Promise.then
MutationOberver
或setImmediate
添加到微任务(此队列属于当前的宏任务,会在当前宏任务执行完成之后执行)队列中,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替,添加到延时任务列表中,会在当前宏任务执行结束之前检测是否到达了延时时间。 -
服务端渲染
nuxt.js -
vue
原理 -
从源码看
vuex
-
前端路由
网友评论