- Vue更新使用v-for渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是
简单复用此处每个元素,为每项提供一个唯一key特性,Vue会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素
- 有相同父元素的子元素必须有独特的 key,重复的 key 会造成渲染错误,key应唯一。
- 遍历数组时,不建议用索引作为key值 -> 数组反转或进行其他操作后,元素Key值会变化 -> vue会重新生成元素,造成浪费
- 重新渲染后,会立即执行$.nextTick -> 可以当做Promise来链式调用
- v-for 比 v-if 具有更高的优先级
- 如果 v-model 表达式的初始值未能匹配任何选项, select 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这
样的情况下,iOS 不会触发 change 事件。
- 使用方法也可以实现与计算属性类似的效果,但是只要页面重新渲染,该函数就会执行,当函数逻辑过多时,会造成性能浪费 -> 建议使用计算属性来实现
- 只有当依赖的响应式属性变化了,计算属性才会重新计算
- 侦听属性:响应数据(data&computed)的变化,当数据变化时,会立刻执行对应函数
- 侦听器VS计算属性:
- 两者都可以观察和响应Vue实例上的数据的变动。
- watch擅长处理的场景是:一个数据影响多个数据。
计算属性擅长处理的场景是:多个数据影响一个数据。
- 在侦听器中可以执行异步,但是在计算属性中不可以
- Axios是一个基于promise的HTTP库
axios(config)
axios(url, [config])
最常用的配置:
axios({
method: 'get', // post、get、put....
baseURL: '', // 请求的域名,基本地址
url: '', // 请求的路径
params: {}, // 会将请求参数拼接在url上
data: {}, // 会将请求参数放在请求体中
headers: {}, // 设置请求头,例如设置token等
timeout: 1000, // 设置请求超时时长,单位:ms
})
- 拦截器
请求拦截器
axios.interceptors.request.use(config => {
// 在发送请求之前做些什么
return config;
})
响应拦截器
axios.interceptors.response.use(response => {
// 对响应数据做点什么
return response;
})
在实际开发过程中,一般在拦截器中统一添加错误处理
const instance = axios.create({});
instance.interceptors.request(config => {
}, error => {
return Promise.reject(error);
})
instance.interceptors.response(response => {
}, error => {
return Promise.reject(error);
})
- 组件:带有名字的可复用的vue实例
- 一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝 -> 组件复用之后,每个实例之间数据不会互相影响
- 父子之间通过props传参是单向的:父 -> 子
- 当组件接收了一个非Prop特性时,该特性会被添加到这个组件的根元素上
- 子 -> 父传递数据:$emit
子组件:触发自定义事件
<button @click="$emit('enlarge-text', 0.2)">放大字号</button>
父组件:监听该自定义事件
@enlarge-text="postFontSize += $event"
- 可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素 -> 可以实现在根元素上监听原生事件,如监听focus等
- 在组件上使用v-model指令,也是绑定了value特性,监听了input事件
为了让 v-model 指令正常工作,这个组件内的 <input> 必须:
- 将其value特性绑定到一个叫 value 的prop 上
- 在其input事件被触发时,将新的值通过自定义的input事件抛出
Vue.component('base-input', {
props: ['value'],
template: `
<input
:value="value"
@input="$emit('input', $event.target.value)"
/>
`
})
- sync 修饰符: 本质上也是一个语法糖
在组件上使用:
<base-input :value.sync="searchText"></base-input>
等价于:
<base-input
:value="searchText"
@update:value="searchText = $event"
/>
- 插槽:向组件内传递内容
如果组件内没有包含slot元素,则该组件即使在标签内写了内容,
也相当于一个简单的自闭合标签。
插槽在父模板中应用,使用的即是父模板的数据,而不是组件作用域内的数据
在向具名插槽提供内容的时候,我们可以在一个 template 元素上使用 v-slot 指令
<my-cmp>
<template v-slot:header>
<h1>头部</h1>
</template>
</my-cmp>
- 插槽 prop:能够让插槽内容访问子组件的数据
template: `
<span>
此时插槽使用的就是组件作用域内的数据
<slot v-bind:user="user"></slot>
</span>
`
默认插槽的缩写语法不能和具名插槽混用 -> 会导致作用域不明确
- 动态组件
<component :is="cmpName"></component>
每次组件切换时,都会创建一个新的组件实例
->
可以用一个 <keep-alive> 元素将动态组件包裹起来
-> 失活的组件将会被缓存
-> 要求被切换到的组件都有自己的名字
- 访问根实例 $root
- 访问 父组件实例 $parent
组件嵌套过深时,会失控
->
使用'依赖注入'解决
- provide 选项: 允许我们指定想要提供给后代组件的数据/方法
- inject 选项: 来接受指定想要添加在实例上的属性
- 访问子组件实例或子元素 $refs :不是响应式的
- 创建低开销的静态组件 v-once
- 混入:分发 Vue 组件中的可复用功能
当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项
- 自定义指令: 复用底层的DOM操作
钩子函数:
bind
inserted
update
componentUpdated
unbind
钩子函数参数:
- el: 指令所绑定的元素,可以用来直接操作DOM。
- binding:对象,包含以下属性:
name:指令名,不包括 v- 前缀。
value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。
无论值是否改变都可用。
expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,
表达式为 "1 + 1"。
arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,
修饰符对象为 { foo: true, bar: true }。
- vnode:Vue 编译生成的虚拟节点。
- oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
- 过滤器:可串联
{{ msg | filterA | filterB }}
- 路由
通过在 Vue 根实例的 router 配置传入 router 实例,
$router、 $route 两个属性会被注入到每个子组件。
$router
路由实例对象
$router.push 向 history 栈添加一个新的记录
$router.replace 替换掉当前的 history 记录
$router.go(n) 在 history 记录中向前或者后退多少步
$route
只读,路由信息对象
$route.path 对应当前路由的路径,总是解析为绝对路径
$route.params 一个 key/value 对象,包含了动态片段和全匹配片段
$route.query 一个 key/value 对象,表示 URL 查询参数
$route.hash 路由的 hash 值 (带
$route.fullPath 完成解析后的 URL,包含查询参数和 hash 的完整路径
$route.matched 一个数组,包含当前路由的所有嵌套路径片段的路由记录
$route.name 当前路由的名称
$route.redirectedFrom 如果存在重定向,即为重定向来源的路由的名字
动态路由匹配
const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
组件可以从 this.$route.params中拿到参数值
- 路由导航守卫
1. 导航被触发。
2. 在失活的组件里调用离开守卫 beforeRouteLeave。
3. 调用全局的 beforeEach 守卫。
4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
5. 在路由配置里调用 beforeEnter。
6. 解析异步路由组件。
7. 在被激活的组件里调用 beforeRouteEnter。
8. 调用全局的 beforeResolve 守卫 (2.5+)。
9. 导航被确认。
10. 调用全局的 afterEach 钩子。
11. 触发 DOM 更新。
12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。