邢台高端网站建设价格,服务好的赣州网站建设,搭建网站需要的软件,宁夏建设投资集团公司网站Hello#xff0c;各位小伙伴#xff0c;接下来的一段时间里#xff0c;我会把我的课程《Vue.js 3.0 核心源码解析》中问题的答案陆续在我的公众号发布#xff0c;由于课程的问题大多数都是开放性的问题#xff0c;所以我的答案也不一定是标准的#xff0c;仅供你参考喔。… Hello各位小伙伴接下来的一段时间里我会把我的课程《Vue.js 3.0 核心源码解析》中问题的答案陆续在我的公众号发布由于课程的问题大多数都是开放性的问题所以我的答案也不一定是标准的仅供你参考喔。本期的问题如果你想利用依赖注入让整个应用下组件都能共享某个数据你会怎么做为什么这个问题本身并不难因为你只要知道了依赖注入的实现原理你就可以轻松回答出只要在应用的根实例上 provide 某个数据然后在子组件 inject 使用就相当于整个应用的组件共享该数据了。看上去使用 provide/inject 就可以实现全局数据共享这个能力似乎和 Vuex 提供的能力类似那么它可以替代 Vuex 吗Vuex 的核心概念Vuex 是什么官方的解释是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 本质上是一种全局单例模式的方式来管理组件的共享状态。在这种模式下我们的组件树构成了一个巨大的“视图”不管在树的哪个位置任何组件都能获取状态或者触发行为。在 Vuex 中有四个核心的概念我们来简单过一下。Statestate 是 Vuex 中最基础的概念它用于数据的 存储举个例子import { createStore } from vuex
const store createStore({state: {todos: [{ id: 1, text: ..., done: true },{ id: 2, text: ..., done: false }]}
})
我们可以通过 store.state.todos 来访问到其中的 todos 数据。Getter有些时候我们希望获取的数据可能不是单一的在 state 中的数据可能需要做一些逻辑运算我们可以使用 getter它就是 store 的计算属性。延续前一个例子import { createStore } from vuex
const store createStore({state: {todos: [{ id: 1, text: ..., done: true },{ id: 2, text: ..., done: false }]},getters: {doneTodos: state {return state.todos.filter(todo todo.done)}}
})
我们可以通过 store.getters.doneTodos 访问到所有已完成的 todos 数据。Mutation数据有读就会有写为了确保数据的改变可追踪更改 state 数据的唯一的方式是提交 mutation。延续前一个例子import { createStore } from vuex
const store createStore({state: {todos: [{ id: 1, text: ..., done: true },{ id: 2, text: ..., done: false }]},getters: {doneTodos: state {return state.todos.filter(todo todo.done)}},mutations: {finishToDo(state, index) {state.todos[index].done true}}
})
我们可以通过 store.commit(finishTodo, 1) 来修改第二个 todo 的完成状态。Actionaction 类似 mutation不同在于在 action 内部并不直接修改数据还是通过提交 mutation 来更改数据此外 action 内部还能包含任意的异步操作。延续前一个例子import { createStore } from vuex
const store createStore({state: {todos: [{ id: 1, text: ..., done: true },{ id: 2, text: ..., done: false }]},getters: {doneTodos: state {return state.todos.filter(todo todo.done)}},mutations: {finishToDo(state, index) {state.todos[index].done true}},actions: {delayFinishTodo({commit}, index) {setTimeout(() {commit(finishToDo, index)}, 1000)}}
})
我们可以通过 store.dispatch(delayFinishTodo, 1) 延时 1s 后修改第二个 todo 的完成状态。至此我们了解了 Vuex 的四个最核心的概念目前为止我们都是通过原生 JavaScript 去操作 store 实例并没有和组件关联那么我们如何在组件中访问到 store 实例呢在组件中访问 store在 Vue.js 3.0 中我们通过 createStore 创建了 store 实例后会在创建 App 对象的时候注入进去。import { createApp } from vue
import App from ./App.vue
import store from ./storecreateApp(App).use(store).mount(#app)
当执行 createApp(App).use(store) 的时候相当于注册了 store 的插件会执行到 store 提供的 install 方法来看看 4.0 版本的 Vuex 是如何实现 install 方法的export class Store {install (app, injectKey) {app.provide(injectKey || storeKey, this)app.config.globalProperties.$store this}
}
在注册插件的时候内部通过 app.provide 把 store 实例 provide 到了根实例中此外store 实例也被添加到了全局属性的 app.config.globalProperties.$store 中。这么做之后我们就可以在组件中轻松访问到 store 实例了。其中 app.provide 是给 Composition API 方式编写的组件用的因为一旦使用了 Composition API 我们在组件中想访问 store 的话会在 setup 函数中通过 useStore API 拿到如下import { useStore } from vuex
export default {setup() {const store useStore()}
}
useStore 的实现如下import { inject } from vue
export const storeKey store
export function useStore (key null) {return inject(key ! null ? key : storeKey)
}
原来 Vuex 就是利用了 provide/inject 依赖注入的 API 实现了在组件中访问到 store由于是通过 app.provide 把 store 实例 provide 到根实例中所以在 app 内部的任意组件中都可以 inject store 实例并访问了。除了 Composition APIVue.js 3.0 依然支持 Options API 的方式去编写组件显然在 Options API 组件中我们依然可以通过 this.$store 访问到 store 实例因为实例的查找最终会找到全局 globalProperties 中的属性。所以我们看到 provide/inject 在 Vuex 中的作用就是让组件可以访问到 store 实例。Vuex 的其它能力Vuex 除了管理组件的共享状态还有一些其他好用的特性这里我介绍三个常用的特性。模块由于使用单一状态树应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时store 对象就有可能变得相当臃肿。为了解决以上问题Vuex 允许我们将 store 分割成模块module。每个模块拥有自己的 state、getter、mutation、action、甚至是嵌套子模块——从上至下进行同样方式的分割const moduleA {state: () ({ ... }),mutations: { ... },actions: { ... },getters: { ... }
}const moduleB {state: () ({ ... }),mutations: { ... },actions: { ... }
}const store createStore({modules: {a: moduleA,b: moduleB}
})store.state.a // - moduleA 的状态
store.state.b // - moduleB 的状态
另外在 store 创建之后你可以使用 store.registerModule 方法动态注册模块import { createStore } from vuexconst store createStore({ /* options */ })// 注册模块 myModule
store.registerModule(myModule, {// ...
})// 注册嵌套模块 nested/myModule
store.registerModule([nested, myModule], {// ...
})
插件Vuex 的 store 接受 plugins 选项这个选项暴露出每次 mutation 的钩子。Vuex 插件就是一个函数它接收 store 作为唯一参数const myPlugin (store) {// 在 store 初始化的时候调用store.subscribe((mutation, state) {// 每次提交 mutation 的时候调用})
}
然后像这样使用import { createStore } from vuex
const store createStore({// ...plugins: [myPlugin]
})
官方内置了 Logger 插件用于一般的调试import { createStore, createLogger } from vuex
const store createStore({// ...plugins: [createLogger()]
})
通常我们会在开发环境中使用它用来输出提交的 mutation 和生成状态快照。严格模式为了保证数据的变化可追踪我们要求所有状态的更改都应该通过提交 mutation 来触发因此在严格模式下一旦发生了状态变更且不是由 mutation 函数引起的将会抛出错误。我们可以在创建 store 的时候开启const store createStore({// ...strict: true
})
由于开启严格模式会有一定的性能损耗我们也只会在开发环境中开启它。总结综上我们发现 Vuex 提供的能力还是很丰富的而仅仅用 provide/inject 是不能替代 Vuex 的那么 provide/inject 有哪些应用场景呢其实这个在课程中已经说了我比较推荐在组件库的开发中使用因为对于一个特定组件它和其嵌套的子组件上下文联系很紧密。我出这个题主要是希望你能做到以下两点从源码层面探索了解 provide/inject 的实现原理。延伸思考 provide/inject 在实现全局数据共享需求与 Vuex 的相同与差异。要记住分析和思考的过程远比答案重要。你好我是若川江西人~(点击蓝字了解我)历时一年只写了一个学习源码整体架构系列 有哪些必看的JS库jQuery、underscore、lodash、sentry、vuex、axios、koa、redux关注若川视野回复pdf 领取优质前端书籍pdf回复1可加群长期交流学习我的博客地址https://lxchuan12.gitee.io 欢迎收藏觉得文章不错可以 分享、点赞、在看 呀^_^另外欢迎留言交流小提醒若川视野公众号面试、源码等文章合集在菜单栏中间【源码精选】按钮欢迎点击阅读也可以星标我的公众号便于查找