在研读 Vue3 的指导文档的时候,我们会被反复提醒重大变化就是提供了组合式 API。
简单来说通过组合式 API,我们可以将 Vue 视图所依赖的数据和逻辑剥离出来。
而我们以前处理数据时,除了当前组件的数据还会有父组件传入的数据,以及使用 Vuex 进行管理的全局数据。
在官方文档中着重提供了一个父组件调用子组件的数据传递和响应性的 DEMO,我的第一反应就是这个方案完全可以替代 Vuex 进行全局状态管理。
PS:不知道为什么,官方没有提到这一点。或许并不推荐或害怕滥用行为?
考虑进行替代之前,我们需要梳理下全局状态管理能力的要点(可以参考 Vuex 的实现)。
我们需要看在 Vue3 中能够提供这些特性:
既然我们发现全局状态管理的诉求在 Vue3 中能够充分实现,那就开始尝试吧。
我们单独规划一个目录用于创建全局数据,比如我放在 src/context 路径下。
其中用户全局数据放在 src/context/user.js,本文主要是提供方案,没有写过多的复杂逻辑。
import { reactive, provide, readonly, inject } from 'vue'
// 用户全局变量命名
const UserSymbol = 'USER'
// 用户全局变量(建立为响应式变量)
const user = reactive({ name: '333', authKeys: [] })
// 用户变量修改方法
const login = ( loginInfo ) => { user.name = loginInfo }
// 用户全局数据提供方法
export const userProvide = () => {
// 提供一个只读的变量和修改方法
provide( UserSymbol, {user: readonly(user), login} )
}
// 用户全局数据注入方法
export const userInject = () => {
return inject(UserSymbol)
}
在 src/context/index.js 对用户全局数据统一管理,因为我们未来还会有其他类型或者模块的数据。
// 导入用户模块全局数据
import { userProvide, userInject } from './data/user'
// 导出相关的注入方法
export { userInject }
// 导出相关的提供方法
export const contextProvider = () => {
userProvide()
}
App.vue 作为根组件,依照概念我们在根组件中提供的数据,整个应用的其他组件都是子组件,自然可以自由访问数据。
// 导入全局上下文方法
import { contextProvider } from './context'
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
setup() {
// 根组件注册全局上下文
contextProvider()
},
components: {
HelloWorld
}
}
HelloWorld 子组件中尝试读取数据。
<template>
<div class="hello">
<h1>以下为子组件</h1>
<h1>{{ user.name }}</h1>
</div>
</template>
<script>
import { userInject } from '/src/context'
export default {
name: 'HelloWorld',
setup() {
const { user } = userInject()
return { user }
}
}
</script>
结果可以成功读取到 user.name 为 333,因此整个流程是畅通的,我们成功完成了【特性1全局访问】。
我们在子组件中导出了 user,上文我们说过为了确保可控的修改,导出的数据时只读的,我们编写一个方法尝试修改下。
<template>
<div class="hello">
<h1>以下为子组件</h1>
<h1>{{ user.name }}</h1>
<el-button type="primary" @click="setName()">我来修改</el-button>
</div>
</template>
编写一个方法 setName() 如下:
methods:
{
setName() {
// user 是只读的,理论上我们无法修改
this.user.name = Math.ceil(Math.random()*1000) + ''
}
}
尝试修改,确实无法修改,报错如下:
回顾我们在定义全局数据时,不仅导出了数据,同时暴露一个修改方法,这个方法就是用于修改数据的。
因此我们修改子组件 HelloWorld.vue 如下:
<template>
<div class="hello">
<h1>以下为子组件</h1>
<h1>{{ user.name }}</h1>
<el-button type="primary" @click="setName()">我来修改</el-button>
</div>
</template>
<script>
import { userInject } from '/src/context'
export default {
name: 'HelloWorld',
setup() {
// 注入修改方法
const { user, login } = userInject()
return { user, login }
},
methods:
{
setName() {
// 调用提供的修改方法
this.login(Math.ceil(Math.random()*1000) + '')
}
}
}
</script>
自此,我们完成了【特性2全局更新】【特新3可控修改】。
通过上方的样例,我们基本可以确认,Vue3 自身就能够实现全局状态管理,可以尝试用来替代 Vuex 吧。
当前还没有观点发布,欢迎您留下足迹!
instantclick.js利用预加载技术使得网站页面跳转时的速度得到大大提升,通过预加载数据替换当前的DOM结构体来达到减少页面请求返回的数据量,提供事件监听钩子函数便于完成页面初始化
HTML 中加载 SVG 有很多种方式,但如果需要在 HTML 中通过 CSS 样式自由控制 SVG 样式就必须将 svg 标签插入网页找那个成为 DOM 的一部分,本文借助 SVGInject 插件可以快速完成这一操作
在业务中我们会出现不同的项目依赖与不同版本的 node.js,总不能每次跑项目的时候都去重新安装对应版本的 node.js 和依赖,使用 nvm 可以让多个版本的 node.js 共存,并提供管理和切换
智能移动终端大爆发的现阶段,手机访问网页已经成为人们不可或缺的使用习惯,开发自适应网页大势所趋,实际上无论改造还是开发本身并不复杂,但是掌握更好的开发模式会使得你编写页面更加高效快捷
绝大多数网站都会有个顶部导航,对于手机端而言为了便于访问导航常常会做固顶操作,通过CSS样式配合Jquery的scroll()方法或原生JS监听滑动事件方法,可以轻松实现下滑隐藏,上滑显示的效果
多数网站首页的数据往往是最庞大的,三到五秒打开都算比较优秀,因此设置一个开场(预加载)动画特效能够大幅度提升用户感官体验,这里分享本站使用的加载动画,整体比较简约清新