1. pinia是什么?
在中,可以使用传统的来实现状态管理,也可以使用最新的来实现状态管理,我们来看看官网如何解释的: 是 的存储库,它允许您跨组件/页面共享状态。实际上,就是的升级版,官网也说过,为了尊重原作者,所以取名,而没有取名,所以大家可以直接将比作为的
2. 为什么要使用pinia?
3. pinna使用
pinna文档(opens new window)
我们这里搭建一个最新的项目
2.1 创建
创建很简单,调用p中的函数即可,该函数接收两个参数:
我们可以定义任意数量的,因为我们其实一个就是一个函数,这也是的好处之一,让我们的代码扁平化了,这和的实现思想是一样的
2.2 使用
2.3 添加
2.4 读取数据
上段代码中我们直接通过等方式获取到了存储的值,但是大家有没有发现,这样比较繁琐,我们其实可以用解构的方式来获取值,使得代码更简洁一点
2.5 修改数据
2.6 重置
当我们点击重置按钮时,中的数据会变为初始状态,页面也会更新
2.7 批量更改数据
如果我们一次性需要修改很多条数据的话,有更加简便的方法,使用的方法,修改代码,添加一个批量更改数据的方法
2.8 直接替换整个
提供了方法让我们直接替换整个对象,使用的方法
上段代码会将我们提前声明的替换为新的对象,可能这种场景用得比较少
3.1 添加
上段代码中我们在配置项参数中添加了属性,该属性对象中定义了一个方法,该方法会默认接收一个参数,也就是对象,然后该方法返回的是一个新的数据
3.2 使用
上段代码中我们直接在标签上使用了方法,这样可以保证响应式,其实我们中的等属性也可以以此种方式直接在标签上使用,也可以保持响应式
3.3 中调用其它
3.3 传参
4.1 添加
4.2 使用
使用中的方法也非常简单,比如我们在中想要调用该方法
总结
的知识点很少,如果你有Vuex基础,那么学起来更是易如反掌
pinia无非就是以下3个大点:
本质是一个具备缓存的,依赖的属性发生变化就会更新视图。 适用于计算比较消耗性能的计算场景。当表达式过于复杂时,在模板中放入过多逻辑会让模板难以维护,可以将复杂的逻辑放入计算属性中处理
没有缓存性,更多的是观察的作用,可以监听某些数据执行回调。当我们需要深度监听对象中的属性时,可以打开选项,这样便会对对象中的每一项进行监听。这样会带来性能问题,优化的话可以使用字符串形式监听,如果没有写到组件中,不要忘记使用手动注销
computed:
watch:
小结:
回答范例
思路分析
特点:具有响应式的返回值
特点:侦测变化,执行回调
回答范例
基本使用
相关源码
事件修饰符
v-model 的修饰符
键盘事件的修饰符
系统修饰键
鼠标按钮修饰符
Vue 的编译过程就是将 template 转化为 render 函数的过程 分为以下三步
可以。v-model 实际上是一个语法糖,如:
实际上相当于:
用在自定义组件上也是同理:
相当于:
显然,custom-input 与父组件的交互如下:
所以,custom-input 组件的实现应该类似于这样:
keep-alive include/exclude activated deactivated
参考 前端进阶面试题详细解答
这个 API 很少用到,作用是扩展组件生成一个构造器,通常会与 一起使用。
既然是要保持页面的状态(其实也就是组件的状态),那么会出现以下两种情况:
那么可以按照这两种情况分别得到以下方法:
组件会被卸载:
(1)将状态存储在LocalStorage / SessionStorage
只需要在组件即将被销毁的生命周期 (react)中在 LocalStorage / SessionStorage 中把当前组件的 state 通过 JSON.stringify() 储存下来就可以了。在这里面需要注意的是组件更新状态的时机。
比如从 B 组件跳转到 A 组件的时候,A 组件需要更新自身的状态。但是如果从别的组件跳转到 B 组件的时候,实际上是希望 B 组件重新渲染的,也就是不要从 Storage 中读取信息。所以需要在 Storage 中的状态加入一个 flag 属性,用来控制 A 组件是否读取 Storage 中的状态。
优点:
缺点:
(2)路由传值
通过 react-router 的 link 组件的 prop —— to 可以实现路由间传递参数的效果。
在这里需要用到 state 参数,在 B 组件中通过 history.location.state 就可以拿到 state 值,保存它。返回 A 组件时再次携带 state 达到路由状态保持的效果。
优点:
缺点:
组件不会被卸载:
(1)单页面渲染
要切换的组件作为子组件全屏渲染,父组件中正常储存页面状态。
优点:
缺点:
除此之外,在Vue中,还可以是用keep-alive来缓存页面,当组件在keep-alive内被切换时组件的activated、deactivated这两个生命周期钩子函数会被执行
被包裹在keep-alive中的组件的状态将会被保留:
router.js
1. 分析
首先找到的构造函数
源码位置:srccoreinstanceindex.js
是用户传递过来的配置项,如等常用的方法
构建函数调用方法,但我们发现本文件中并没有此方法,但仔细可以看到文件下方定定义了很多初始化方法
首先可以看方法,发现该方法在原型上定义了方法
源码位置:srccoreinstanceinit.js
仔细阅读上面的代码,我们得到以下结论:
方法是完成的初始化
源码位置:srccoreinstancestate.js
我们和这里主要看初始化的方法为,它与在同一文件上
仔细阅读上面的代码,我们可以得到以下结论:
关于数据响应式在这就不展开详细说明
上文提到挂载方法是调用方法
源码位置:
阅读上面代码,我们能得到以下结论:
对的解析步骤大致分为以下几步:
生成函数,挂载到上后,会再次调用方法
源码位置:srcplatformsweb untimeindex.js
调用渲染组件
阅读上面代码,我们得到以下结论:
方法主要执行在初始化时声明的,方法
rendervnode
源码位置:srccoreinstance ender.js
主要功能是调用,将转换为真实,并且更新到页面中
源码位置:srccoreinstancelifecycle.js
2. 结论
不会立即同步执行重新渲染。Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化, Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。
如果同一个watcher被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环tick中,Vue 刷新队列并执行实际(已去重的)工作。
在 Vue2 中, 0bject.defineProperty 会改变原始数据,而 Proxy 是创建对象的虚拟表示,并提供 set 、get 和 deleteProperty 等处理器,这些处理器可在访问或修改原始对象上的属性时进行拦截,有以下特点∶
Proxy 实现的响应式原理与 Vue2的实现原理相同,实现方式大同小异∶
思路分析:
首先思考路由要解决的问题:用户点击跳转链接内容切换,页面不刷新。
回答范例:
一个应用的路由需要解决的问题是 页面跳转内容改变同时不刷新 ,同时路由还需要以插件形式存在,所以:
(1)编码阶段
(2)SEO优化
(3)打包优化
(4)用户体验
( single-page application )仅在 页面初始化时加载相应的 、 和 。一旦页面加载完成, 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 内容的变换, 与用户的交互,避免页面的重新加载
优点:
缺点:
单页应用与多页应用的区别
实现一个SPA
题外话:如何给SPA做SEO
将组件或页面通过服务器生成,再返回给浏览器,如
目前主流的静态化主要有两种:
原理是通过配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个,再通过来解析完整的,返回给爬虫。下面是大致流程图
这是一个实践知识点,组件化开发过程中有个,不在子组件中修改父组件是个常识问题
思路
回答范例
这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。 在这种情况下,最好定义一个本地的 ,并将这个 用作其初始值:
这个 prop 以一种原始的值传入且需要进行转换。 在这种情况下,最好使用这个 的值来定义一个计算属性:
1. 模式
早期的前端路由的实现就是基于 来实现的。其实现原理很简单, 的值就是 中 后面的内容。比如下面这个网站,它的 的值为
hash 路由模式的实现主要是基于下面几个特性
每一次改变 (),都会在浏览器的访问历史中增加一个记录利用 的以上特点,就可以来实现前端路由“更新视图但不重新请求页面”的功能了
特点 :兼容性好但是不美观
2. 模式
采用的新特性;且提供了两个新方法: , 可以对浏览器历史记录栈进行修改,以及事件的监听到状态变更
这两个方法有个共同的特点:当调用他们修改浏览器历史记录栈后,虽然当前 改变了,但浏览器不会刷新页面,这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础。
history 路由模式的实现主要基于存在下面几个特性: