computed 和 watch:
computed 有缓存,data不变则不会重新计算;
watch 如何深度监听:添加 deep:true;handler;
watch 监听引用类型,拿不到oldVal;
v-if 和 v-show 的区别:
v-if: 不符合条件不渲染;更新不频繁或一次性推荐使用;
v-show:类似于 display:none;不显示,依旧渲染;频繁切换推荐使用;
循环(列表)渲染:
遍历对象也可以使用 v-for
key 的重要性。key 不能乱写(如 random 或者 index )
v-for 和 v-if 不能一起使用;v-for 优先级高于 v-if
event 事件:1. event 是原生的;2. 事件被挂载到当前元素;
v-model.trim :截取前后的空格;
v-model.lazy :类似于防抖的效果,输入不会变化,输入结束才会变化;
v-model.number :转换成数字;
props:父组件向子组件传值; $emit:子组件调用父组件的方法;
自定义事件:new Vue() vue本身就具备自定义事件的能力;绑定自定义事件后一定要在 beforeDestroy 里面及时销毁;
绑定:event.off;触发:event.$emit;
this.emit:调用自定义的事件;
生命周期:
挂载阶段:beforeCreate;created;beforeMount;mounted;
更新阶段:beforeUpdate;updated
销毁阶段:beforeDestroy;destroyed
created:实例初始化,页面还没有真正的渲染;mounted:渲染完成;
生命周期(父子组件):index(父);list(子)
创建由外至里,渲染由里至外;
index created > list created > list mounted > index mountedindex before update > list before update > list update > index update
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted->父beforeUpdate->子beforeUpdate->子updated->父updated->父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
Vue 高级特性:
自定义 v-model
$nextTick
slot
动态、异步组件
keep-alive
mixin
// 手写 v-model
<template>
<!-- 例如:vue 颜色选择 -->
<input type="text"
:value="text1"
@input="$emit('change1', $event.target.value)"
>
<!--
1. 上面的 input 使用了 :value 而不是 v-model
2. 上面的 change1 和 model.event1 要对应起来
3. text1 属性对应起来
-->
</template>
<script>
export default {
model: {
prop: 'text1', // 对应 props text1
event: 'change1'
},
props: {
text1: String,
default() {
return ''
}
}
}
</script>
$nextTick
vue 是异步渲染
data 改变之后,DOM 不会立刻渲染
$nextTick 会在 DOM 渲染之后被触发,以获取最新 DOM 节点
<template>
<div id="app">
<ul ref="ul1">
<li v-for="(item, index) in list" :key="index">
{{item}}
</li>
</ul>
<button @click="addItem">添加一项</button>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
list: ['a', 'b', 'c']
}
},
methods: {
addItem() {
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
// 1. 异步渲染,$nextTick 待 DOM 渲染完再回调
// 3. 页面渲染时会将 data 的修改做整合,多次 data 修改只会渲染一次
this.$nextTick(() => {
// 获取 DOM 元素
const ulElem = this.$refs.ul1
// eslint-disable-next-line
console.log( ulElem.childNodes.length )
})
}
}
}
</script>
website: {
url: 'http://imooc.com/',
title: 'imooc',
subTitle: '程序员的梦工厂'
},
<SlotDemo :url="website.url">
{{website.title}}
</SlotDemo>
<template>
<a :href="url">
<slot>
默认内容,即父组件没设置内容时,这里显示
</slot>
</a>
</template>
<script>
export default {
props: ['url'],
data() {
return {}
}
}
</script>
// 作用域插槽
<ScopedSlotDemo :url="website.url">
<template v-slot="slotProps">
{{slotProps.slotData.title}}
</template>
</ScopedSlotDemo>
<template>
<a :href="url">
<slot :slotData="website">
{{website.subTitle}} <!-- 默认值显示 subTitle ,即父组件不传内容时 -->
</slot>
</a>
</template>
<script>
export default {
props: ['url'],
data() {
return {
website: {
url: 'http://wangEditor.com/',
title: 'wangEditor',
subTitle: '轻量级富文本编辑器'
}
}
}
}
</script>
动态组件:
:is = 'component-name' 用法
需要根据数据,动态渲染的场景。即组件类型不确定
<component :is="NextTickName"/>
NextTickName: "NextTick",
异步组件:
import()函数
按需加载,异步加载大组件
components: {
FormDemo: () => import('../BaseUse/FormDemo'),
}
keep-alive:
缓存组件
频繁切换,不需要重复渲染 (如 tab 页)
Vue 常见性能优化
<keep-alive>需要缓存组件</keep-alive>
mixin:
多个组件有相同的逻辑,抽离出来
mixin 并不是完美的解决方案,会有一些问题
Vue 3 提出的 Composition API 旨在解决这些问题
mixin 问题:
变量来源不明确,不利于阅读
多 mixin 可能会造成命名冲突
mixin 和组件可能出现多对多的关系,复杂度较高
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,解决多组件数据通信。 Vuex 基本概念:
state:提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data;
getters:类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据;作用:它是 Vuex 中的计算属性,当 Store 数据源发生变化时,Getter 的返回值会自动更新。
action:Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action;使用dispatch触发。
mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数;使用commit触发
用于 Vue 组件:
dispatch:action时使用。
this.$store.dispatch('actions的名字', 参数)
commit:mutation时使用。
this.$store.commit('mutation名', 实参)
mapState:可以方便的把 Store 中指定的数据,映射为当前组件的计算属性。
computed: {
...mapState(['xxx']),
...mapState({'新名字': 'xxx'})
}
mapGetters:可以把 store 中的 getter 映射为当前组件的计算属性
computed: {
...mapGetters(['xxx']),
...mapGetters({'新名字': 'xxx'})
}
mapActions:可以方便的把 Store 中指定的 Action,映射为当前组件的 methods。
methods: {
...mapActions(['actions名']),
...mapActions({'新名字': 'actions名'})
}
mapMutations:基于 Vuex 提供的 mapMutations 辅助函数,可以方便的把 Store 中指定的方法,映射为当前组件的 methods;
methods: {
...mapMutations(['mutation名']),
...mapMutations({'新名字': 'mutation名'})
}
异步操作必须在 Actions 里面
Vue-router 使用:
路由模式:hash 、 H5 history;
路由配置:
动态路由:动态路径参数 以冒号开头({path: '/user/:id', component: User})。
懒加载:使用 import ,优化性能 (path: '/user', component: () => {'../user'})。
Vue-router 模式:
hash 模式(默认),如 abc.com/#/user/10
H5 history 模式,如 abc.com/user/20 。(mode: 'history')
后者需要server 端支持,因此无特殊需求可选择前者
Vue 组件如何通讯:
父子组件:props,$emit;
兄弟组件:自定义事件;
Vuex方式通讯;