| 生命周期 | 描述 |
|---|---|
beforeCreate | 组件实例被创建之前(没有dom,没有$data) |
created | 组件实例已经完全创建(没有dom,有$data) |
beforeMount | 组件挂载之前(没有dom,有$data) |
mounted | 组件被挂载到实例上之后(有dom,有$data) |
beforeUpdate | 组件数据发生变化,更新之前 |
updated | 组件数据更新之后 |
beforeDestroy | 组件实例销毁之前 |
destroyed | 组件实例销毁之后 |
mounted可以操作dom又可以操作data,还可以操作子组件;而在created的时候不能操作dom也不能操作子组件。
发送请求是异步任务,会在同步任务执行完毕之后执行,即获取到数据也是会在mounted执行完之后。
这个问题具体要看项目和业务情况,因为组件的加载顺序是,会先执行父组件的前3个生命周期,再执行子组件的前4个生命周期。如果业务是父组件引入子组件,并且优先加载子组件的数据,那么在父组件中当前请求要放在mounted中,让子组件的请求先去执行,让子组件的数据先加载出来。
如果请求是在methods里封装好的,在beforeCreate里是拿不到methods的方法的。
beforeCreate阶段没有$data ,拿不到methods方法,created阶段有$data,拿得到methods方法。
this.$nextTickbeforeCreate、created、beforeMount、mounted
如果当前组件加入了keep-alive,只会执行activated;
如果没有加入keep-alive依然执行前四个生命周期beforeCreate、created、beforeMount、mounted
父组件 beforeCreate created beforeMount
子组件 beforeCreate created beforeMount mounted
父组件 mounted
如果使用了keep-alive组件,当前组件会额外增加两个生命周期。
activated:被 keep-alive 缓存的组件激活时调用
deactivated:被 keep-alive 缓存的组件失活时调用。
如果当前组件加入了keep-alive,第一次进入这个组件会执行5个生命周期:beforeCreate created beforeMount mounted activated
created:单一组件进行请求
mounted:有父子组件关系的时候,进行请求;同步操作dom
activated:处理缓存
beforeDestroy:关闭页面的时候进行数据记录
父传子:
this.$parent。子能直接修改父组件的数据子传父:
this.$emit。this.$children[index].xxx 或 this.$refs[name].xxx兄弟互传:
$on接收方,$emit发送方)this.$children[index].xxx 或 this.$refs[name].xxx
this.$parent.xxx
this.$parent
this.$root
用来缓存当前组件
依赖注入,用来实现给后辈组件传递数据
抽取复用部分内容,用slot插槽去实现父组件可以自定义部分特殊的内容;通过v-bind绑定props去实现获取父组件数据;通过自定义事件去实现给父组件传递数据。
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享。
State用来存储公共数据源。全局共享属性。Mutation用于同步变更state中的数据。Action用于异步变更state中的数据,但是在Action中还是要用过触发Mutation的方式间接变更数据。Getter用于对Store中的数据进行加工处理形成新的数据(类似于计算属性),Store中数据发生变化,Getter中的数据也会变化。针对state数据进行二次计算。moudle属性是将store分割成模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。this.$store.state.xxx
computed: { ...mapState(['全局数据名称1','全局数据名称2',...]) }
区别:使用this.$store的方式可以直接修改(不推荐),使用辅助函数的方式不能直接修改
getters不可以修改
相同点:都是来存放全局方法的;不能有return值
区别:mutation是同步的,actions是异步的;mutation是用来修改state的,action是用来提交mutation的
vuex本身不是持久化存储,它只是一个全局数据管理仓库。
实现方式:
vuex是单向数据流
路由模式:history、hash
区别:
详请-> Vue Router基础知识整理
详请-> Vue Router基础知识整理
当前页跳当前页,路径不变,参数变
import Vue from 'vue'
import VueRouter from 'vue-router'
// 解决路由重复跳转错误
const routerPush = VueRouter.prototype.push;
VueRouter.prototype.push = function (location) {
return routerPush.call(this, location).catch(err => { })
};
Vue.use(VueRouter)
$router 路由管理对象(路由跳转)$route 路由单体对象,指某一条路由(获取当前路径相关)全局守卫:全局前置守卫 router.beforeEach:路由进入前;全局后置钩子 router.afterEach:路由进入后
路由独享守卫: beforeEnter 只在进入路由时触发
组件内守卫:beforeRouteEnter在渲染该组件的对应路由被验证前调用、 beforeRouteUpdate在当前路由改变,但是该组件被复用时调用、 beforeRouteLeave在导航离开渲染该组件的对应路由时调用
场景:直接通过数组下标去修改数组造成相应丢失
this.$set(target,key,value)
等待下一次 DOM 更新刷新的工具方法。异步的。
获取更新后的dom;等待dom更新完再执行后续操作。
官方说明:当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。
用来获取dom
获取当前组件的节点
获取当前组件的data数据
获取当前组件的所有子组件(一个数组)
找到当前组件的父组件,无则返回自身
找到当前组件的根组件,无则返回自身
return里外的区别
外:需要用this;不被劫持(没有get/set),不支持双向绑定
内:被劫持,双向绑定
计算结果要修改的话要通过set写法

计算属性computed:(可依赖多个属性):
监听属性watch:(只监听一个属性,可监听到数据变化前的值):
初始化的时候先执行一次:immediate:true
对象数据深层监听:deep:true
computed返回结果有缓存, methods没有。当返回结果在dom中多次用到的时候,用computed性能更佳。
监听属性watch:(只监听一个属性,可监听到数据变化前的值):
计算属性computed:(可依赖多个属性):
props > methods > data > computed > watch
全局:main.js
局部:组件内
Vue2自定义指令说明文档
Vue3自定义指令说明文档
vue2vue3指令钩子有所区别
双向绑定:v-model
单向绑定:v-bind,props接收
vue2中v-for的优先级高于v-if
vue3中v-if的优先级高于v-for
不建议在同一节点一起用
功能:等待下一次 DOM 更新刷新的工具方法。获取更新后的dom。异步。
$nextTick(callback) {
return Promise.resolve().then(() => {
callback();
})
}
官方说明:当你在 Vue 中更改响应式状态时,最终的 DOM 更新并不是同步生效的,而是由 Vue 将它们缓存在一个队列中,直到下一个“tick”才一起执行。这样是为了确保每个组件无论发生多少状态改变,都仅执行一次更新。nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。nextTick() 可以在状态改变后立即使用,以等待 DOM 更新完成。你可以传递一个回调函数作为参数,或者 await 返回的 Promise。
通过Object.defineProperty劫持数据发生的改变,如果数据发生了改变(在set进行赋值的),触发update方法进行更新节点内容({{str}}),从而实现数据双向绑定的原理。
双向数据绑定是采⽤数据劫持结合发布者-订阅者模式的⽅式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据发生变动时发布消息给订阅者,触发相应的监听回调。这样就可以实现数据的双向绑定 关键点是Object.defineProperty()劫持属性。
渐进式框架(Progressive Framework)是一种软件开发框架的设计理念,它允许开发者根据项目需求逐步引入和应用框架的不同特性和功能。
**作用:**让样式在本组件中生效,不影响其他组件
**原理:**给元素节点新增自定义属性,然后css根据属性选择器添加样式
::v-deep
【博主:努力的小朱同学】vue 之 CSS进行样式穿透的方法(/deep/、::v-deep、>>> 、:deep、额外的全局<style>)
Object.defineProperty 对数据进行劫持,并结合发布订阅者模式实现。 Vue 利用 Object.defineProperty 创建一个 observe 来劫持监听所有的属性,把这些属性(遍历data)全部转为 getter 和 setter。Vue 中每个组件实例都会对应一个 watcher 实例,它会在组件渲染的过程中把使用过的数据属性通过 getter 收集为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。(Vue2后期添加的属性劫持不到,会造成数据更新但视图没有更新)Proxy代理,Proxy能够拦截目标对象上的操作(如获取、设置等),从而实现对数据的追踪和更新。与之前版本不同的是,Vue.js 3无需再手动编写getter和setter函数,只需要将原始数据包装成Proxy对象后就可以开始追踪和更新。Proxy 不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
tip:setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地去定义
Vue3 支持多个根节点,也就是 fragment;而Vue2只支持一个根节点
Vue2 是选项API(Options API),一个逻辑会散乱在文件不同位置(data、props、computed、watch、生命周期钩子等),导致代码的可读性变差。当需要修改某个逻辑时,需要上下来回跳转文件位置。
Vue3 除了选项式API外还支持组合式API(Composition API)则很好地解决了这个问题,可将同一逻辑的内容写到一起,增强了代码的可读性、内聚性,其还提供了较为完美的逻辑复用性方案。
用hooks,就是让功能模块细分(提升项目的可维护性)
import { getCurrentInstanc e} from "vue";
const this = getCurrentInstance();
const { ctx } = getCurrentInstance();
API 参考:https://cn.vuejs.org/api/
ref():接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。(基本类型)reactive():返回一个对象的响应式代理。(复杂类型)toRef():可以将值、refs 或 getters 规范化为 refs (3.3+)。也可以基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。(解构一个值)toRefs():将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。(解构多个值)Vue3 提供 Teleport 组件可将部分 DOM 移动到 Vue app 之外的位置。比如项目中常见的 Dialog 弹窗
<button @click="dialogVisible = true">显示弹窗button>
<teleport to="body">
<div class="dialog" v-if="dialogVisible">
我是弹窗,我直接移动到了body标签下 div>
teleport>