更新 补充基础知识
-
前端优化 卡白屏
-
懒加载路由
component:() => import('./views/index')//压缩体积
-
使用骨架屏提高体验(vant组件库)
-
css防顶部,js放底部
-
合并http请求
-
优化代码
-
使用雪碧图,多图在一起
- 混用mixin
- 插槽
指在使用子组件时,中间需插入数据A,可在子组件中插入slot,需插入的数据A会取代slot指定位置(slot会被替代)
- ref 依赖注入看作一部分“大范围有效的 prop”
form ref='post' //命名
this.$refs.post //使用获取数据
//具名插槽
<list>
<h1 slot='head'> 我是标题</h1>
//父组件命名的插槽内容会取代子组件header位置内容,在渲染到页面上
</list>
<slot name="header"></slot> //子组件<list>中命名(占位)
<template v-slot:header>
<h1>Here</h1>
</template> //具名插槽
1. vue生命周期的理解?
总共分为 8 个阶段创建前/后,载入前/后,更新前/后,销毁前/后
- 创建前/后:在 beforeCreate 阶段,vue 实例的挂载元素 el 还没有。
- 载入前/后:在 beforeMount 阶段,vue 实例的$el 和 data 都初始化了,但还是挂载之前为虚拟的 dom 节点,
data.message 还未替换。在 mounted 阶段,vue 实例挂载完成,data.message 成功渲染。
- 更新前/后:当 data 变化时,会触发 beforeUpdate 和 updated 方法。
- 销毁前/后:在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 vue 实例已经
解除了事件监听以及和 dom 的绑定,但是 dom 结构依然存在。
2. vue 组件间的通信有几种方式?
(1) 父组件传递给子组件
父:自定义属性名 + 数据(要传递)=> :value="数据"
子:props ["父组件上的自定义属性名“] =>进行数据接收)
在父组件中注册子组件并在子组件标签上绑定自定义事件的监听。
子:this.$emit('自定义事件名称', 数据) 子组件标签上绑定@自定义事件名称='回调函数'
父:methods: {自定义事件() {//逻辑处理} }
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
$parent / $children:访问父 / 子实例
(2) 兄弟组件传递
通过中央通信 let bus = new Vue() 来触发事件和监听事件
A:methods :{ 函数{bus.$emit('自定义事件名',数据)} 发送
B:created (){bus.$on('A发送过来的自定义事件名',函数)} 进行数据接收
(3) Vuex 适用于 父子、隔代、兄弟组件通信
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化 (4) router也可传参
3. 路由的hash和history模式
(1)hash 模式的实现原理
- 早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。
路由模式的实现主要是基于下面几个特性:
-URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送; hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换; -可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;
- 我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。
- 我用的wath()
(2)history 模式的实现原理
- HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。
- 唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,如下所示: window.history.pushState(null, null, path); window.history.replaceState(null, null, path);
复制代码history 路由模式的实现主要基于存在下面几个特性:
- pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ; 我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);
- history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。
4. v-model 的原理
v-model 本质是语法糖,双向绑定表单事件,为不同的输入元素使用不同的属性并抛出不同的事件
- text 和 textarea 元素使用 value 属性和 input 事件;
- checkbox 和 radio 使用 checked 属性和 change 事件;
- select 字段将 value 作为 prop 并将 change 作为事件。
5. vue的双向数据绑定
- 实现一个
监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。 - 实现一个
解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。 - 实现一个
订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。 - 实现一个
订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。
Object.defineProperty() 只能对属性进行数据劫持,对数组和对象的监听通过,遍历数组 和递归遍历对象进行监听
6. 虚拟 DOM
虚拟 DOM 的实现原理主要包括以下 3 部分:
- 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
- diff 算法 — 比较两棵虚拟 DOM 树的差异;
- pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。
优点:提供不错的性能,无需手动操作 DOM,跨平台(虚拟 DOM 本质上是 JavaScript 对象,方便地跨平台操作)
缺点:无法进行极致优化
Watch具有销毁功能
深层次文章:参考 juejin.cn/post/684490…