什么是 vuex? 详述 Vuex 的工作流程
官方介绍: Vuex 是一个专为 vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件的状态, 并以相应的规则保证状态以一种可预测的方式发生变化.
Vuex 其实就是一个 Vue 的集中状态管理工具, 类似于 redux, 但使用方法很明显优化了许多
什么时候使用 Vuex?
官方的话说, 在你需要用的时候自然而然就知道自己什么时候要用了
在我看来, 当项目需要使用公共数据, 并且这个公共数据的访问量较大的时候, 我们可以使用 Vuex, 用来集中管理公共的数据, 而一些小型的项目, 我们可以靠中央通信总线的发布订阅模式来实现数据管理与通信
Vuex 的工作流程
首先通过 dispatch 提交一个 action
在 action 中我们可以执行一些异步的操作, 或者根据不同的情况分发不同的 mutation
接着在 action 中调用 commit, 触发一个 mutation
所有修改 state 的操作, 全部应该放在 mutation 中来做
而 state 更新之后, 会调用 Vue 的底层方法, 通知视图进行更新渲染
Vuex 不像 redux,redux 在任何项目工程内都可以使用, 不仅限于 react, 但是 Vuex 是基于 Vue 的底层实现的一个状态管理工具, 其实 Vuex 中的 store 本质就是没有 template 的隐藏着的 vue 组件
详述 Vuex 的核心属性及使用
state
state 存储了 Vuex 的基本数据, 在 state 中存储的数据都是经过 Vue 底层 watcher 侦听的数据, 可以实现响应式数据
actions
actions 存放了 Vuex 中所有的异步操作, 可以在 actions 中通过 commit 分发不同的 mutation, 在不同的情况下执行不同的方法
mutations
mutations 存放了 Vuex 中所有关于 state 的操作, 修改 state 只能通过 mutations, 否则的话数据不会响应式更新
getters
getters 就类似与 Vue 实例中的 computed, 计算属性, 所有关于数据的复杂计算应该放在 getters 中来操作
modules
modules, 类似于 redux 中的 reducer, 每一个 module 都拥有自己的 state,mutations,actions,getters; 将整个 store 根据功能或者数据分解成不同的模块, 最后合并在一个 Store 中
Vuex 的使用
- import Vue from 'vue'
- import Vuex from 'vuex'
- Vue.use(Vuex);
- // 这里我就不贴出对应模块的代码了
- export default new Vuex.Store({
- modules: {
- shopCart, // 购物车模块
- user // 用户模块
- }
- })
- // 使用模块
- import {mapState,mapActions,mapMutations,mapGetters} from 'vuex';
- // Vue 实例
- export default {
- computed: {
- ...mapState(['user','shopCart']), // 拿到 store 中的 user 模块和 shopCart 模块
- ...mapGetters(['total']) // 拿到 getters 计算属性中的总价, 不区分模块
- },
- methods: {
- ...mapActions(['getUserData']), // 拿到 actions 中的 getUserData 方法, 不区分模块
- ...mapMutations(['addGoodsToShopCart']) // 拿到 mutations 中的 addGoodsToShopCart 方法
- }
- }
Vue 和 jQuery 的区别
jQuery 直接操作 DOM, 使用选择器以及便捷的 DOM 操作方式来修改视图以及数据
Vue 不直接操作 DOM, 而是通过双向数据绑定的方式, 将 DOM 节点在 Vue 内部转化对象的形式, 通过修改数据直接修改视图
jQuery 是一个前端类库, 只是提供了很多便捷操作 DOM 的方法, 而 Vue 是一个框架, 有一套完整的体系
Vue 中的 slot 是什么?
在 Vue 中, 我们一般使用 UI 界面来划分组件, 而每一个 UI 界面可以划分很多个组件, 不同的 UI 界面中难免会有相似之处, 这种相似的地方, 我们如何通过一种优雅的方式来达到复用这个 UI 组件呢? 就是使用 slot 插槽了
slot 插槽, 其实就是用来做内容分发, 使得可以最大程度的复用组件, 达到每次使用同一个组件的时候可以根据情况创建不同的内容的功能
匿名插槽
不具有 name 属性的 slot 就是匿名插槽, 也可以叫默认插槽
由父组件提供样式和内容, 子组件只负责显示
匿名插槽 / 默认插槽只可以使用一次
<slot > 里边写的是默认值 </slot>
在子组件内定义 slot 时, 内部可以定义默认值, 当父组件有内容分发的时候, 显示父组件的内容, 没有的时候, 显示默认内容
具名插槽
有 name 属性
在组件中可以使用 N 次 (name 值不同的情况下)
父组件通过 html 模板上的 slot 属性关联具名插槽
<template v-slot: 插槽名称 ><div > 插槽内容 </div></template>
没有 slot 属性的 HTML 模板默认关联匿名模板
父组件提供样式和内容
<slot name="插槽名称"></slot>
作用域插槽 (带数据的插槽)
父组件只提供样式, 子组件提供内容
在 slot 上面绑定数据
子组件的值可以传给父组件使用
父组件展示子组件数据有 3 种方式: flex 显示, 列表显示, 直接显示
使用 v-slot 必须使用 template; 之前使用的是 slot-scope, 但是这个属性已经在 2.6.0 废弃了, 现在使用 v-slot 指令来代替原有的 slot-scope 属性
scope 返回的值是 slot 标签上返回的所有属性值, 并且是一个对象的形式保存起来
- // 子组件中
- <slot :data="data" :message="message"></slot>
- // 父组件中
- <template v-slot="scope">
- <div class="data-list">
- <span v-for="(item,index) in scope.data" :key="index">{{item}}</span>
- </div>
- <div class="data-message">
- {{scope.message}}
- </div>
- </template>
SPA 首屏加载慢, 该如何解决?
抽取 CSS 文件
使用 CDN 资源
使用路由模块化加载
按照页面或者组件分块懒加载
使用 gzip 减小网络传输的流量大小
使用服务端渲染的方式
使用预渲染的方式
结言
感谢您的查阅, 代码冗余或者有错误的地方望不吝赐教; 菜鸟一枚, 请多关照
来源: http://www.jianshu.com/p/3064577fc0b2