什么是Vuex?详述Vuex的工作流程
- 官方介绍:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
- Vuex其实就是一个Vue的集中状态管理工具,类似于redux,但使用方法很明显优化了许多
-
什么时候使用Vuex?
- 官方的话说,在你需要用的时候自然而然就知道自己什么时候要用了
- 在我看来,当项目需要使用公共数据,并且这个公共数据的访问量较大的时候,我们可以使用Vuex,用来集中管理公共的数据,而一些小型的项目,我们可以靠中央通信总线的发布订阅模式或者Vue.observable来实现数据管理与通信
-
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上面绑定数据
- 子组件的值可以传给父组件使用
- 使用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减小网络传输的流量大小
- 使用服务端渲染的方式
- 使用预渲染的方式