vuex
可以用在兄弟组件之间传值,并在任意组件内引用1,
npm install vuex --save2,
在store.js内import Vue from 'vue'
import Vuex from 'vuex'
export defaul new Vuex.store({
有四个属性
1,state(用于数据存储)
例:state:{
count:1,
a:2
b:3
}
2,mutations(用于同步数据修改)
例:mutations:{
add(state){
state.count++
}
}
可以直接操作state中的数据
3,actions(用于异步数据修改)
例:actions:{
addCount({commit}){
commot('add')//调用同步修改mutation中的方法
}
}
不可以直接操作state中的数据,通常调用mutation中的方法
4,getters(计算过滤属性)
例:getters:{
sum(state){
return state.a+state.b//可以方便操作state内的各个属性并返回在组件内调用
}
}
})
const state:{
}
const mutations:{
}
const action:{
}
const getters:{
}
export defaul new Vuex.store({
state,
mutations,
action,
getters
})
3,
在组件内部引用
在script标签内
import { mapState mapMutations , mapActions , mapGetters } from 'vuex' //解构赋值
export default {
methods:{
内部可以引用mapMutations和mapActions内部的函数
}
computed:{
内部可以应用mapState和mapGetter内部的函数或属性
}
}
方法一: methods:{ ...mapMutations(['方法名']) addcount(){ this.add()//调用mutation里的方法 } } 方法二: computed:{ ...mapState(['count'])//取出state里的属性count getCount(){ return this.count } 或-------------------------------------------------- getCount(){ return this.$store.state.count } } 方法三: computed:{ mapState({ count:state=>state.count })
4,
在页面中渲染方法一:
适用于所有情况
{{$store.state.count}}
方法二:
适用于利用设置属性的情况下
{{getCount}}
方法三:
适用于不在methods或mutations内设置方法时直接调用store.js中的函数
@click="$store.commit('方法名',参数)"
@click="方法名"
5,
异步修改示例(接口请求,定时器...)import Vue from 'vue'
import Vuex from 'vuex'
export defaul new Vuex.store({
state:{
count:1,
userinfo:''
}
mutations:{
add(state){
state.count++
}
setInfo(state,data){
state.userInfo:data
}
}
actions:{
getInfo(){
$ajax({
success:function(){
res
}
})
}
let res=...
commit('setInfo',res)//可以调用同步处理时的方法
}
6,解决vuex中页面刷新后数据丢失的问题
原因 因为store中的数据是保存在内存中的,当刷新页面时,页面会重新加载vue实例,vuex中的存储在store中的数据会重新进行初始化。
解决办法及心路历程
由于vuex中的数据保存在运行内存中,因此,将其保存在缓存中就可以解决这个问题;
缓存主要有Session Storage,Local Stroage,Cookie三种,如何进行选择?
由于sessionStorage 缓存只在该页面存在时有效,所以就选择它了
应该在那个阶段,如何将VUEX中的内容存在sessionStroage中?
1,vuex中的state数据只有在mulation中能够被修改,可以在mulation中利用sessionStroage.setItem进行修改,当页面刷新时用sessionStorage.getItem获取到值,用this.store.state,JSON.parse(sessionStorage.getItem("store"))))替代原来vuex中的state;
2,在app.vue中用beforeunload方法中将store.state存储到sessionstorage中
created () {
//在页面加载时读取sessionStorage里的状态信息
if (sessionStorage.getItem("store") ) {
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store"))))
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener("beforeunload",()=>{
sessionStorage.setItem("store",JSON.stringify(this.$store.state))
})
}
为什么不能直接用sessionStroage替代vuex进行存储呢? sessionStroage等用于不同页面之间的存储比较合适,当两个组件利用vuex中数据源进行通信时,一个组件中的数据源发生变化时,另一个组件中的相应数据也会响应式变化,而sessionStroage和localStroage做不到。
redux
可以用在兄弟组件之间传值,并在任意组件内引用1,
安装步骤:npm install -g create-react-app
create-react-app react-app
cd react-app
npm install redux react-redux
npm start
2,
首先,在Index.js中利用store来存储和改变数据import {Procider} from 'react-redux'
import store from './store'//以js结尾可以省略
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>
,
document.getElementById('root'));
其次,创建store.js
createStore创建一个 Redux store 来以存放应用中所有的 state,应用中应有且仅有一个 store;其中暴露 dispatch, subscribe, getState, replaceReducer 方法。
import {createStore} from 'redux'
import reducer from './reducer'
利用initState设置对象具有的属性并赋初值,存储的是状态管理的一些变量
let initState = {
num: 0,
userInfo: {},
}
// createStore 第一个参数是一个reducer(fun) 第二个参数是一个obj
let store = createStore(reducer, initState)
export default store
然后,创建reducer.js
用于对store.js中的数据进行具体的操作
import { combineReducers } from "redux"
// state 需要有默认的初始值
第一个参数是设置初始值,第二个参数是action
const num = (state=0, action) => {
switch(action.type) {
case 'add':
return state+1;
case 'del':
return state-1;
default:
return state
}//对于数据进行具体的操作
}
combineReducers() 生成一个函数,这个函数来调用你的一系列 reducer,每个reducer 根据它们的 key 来筛选出 state 中的一部分数据并处理,然后这个生成的函数再将所有reducer的结果合并成一个大的对象
const reducer = combineReducers ({
num
})
export default reducer
然后,创建action.js
将action 暴露给store.js
action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作,多数情况下,type 会被定义成字符串常量
const add = (text) => {
return {
type: 'add',
text
}
}
const del = (text) => {
return {
type: 'del',
text
}
}
export {
add,
del
}//导出两个方法的方式
最后,在App.js中
import {add, del} from './action'//引入同一个文件中两个方法
import store from './store'//引入存储的文件
--------------------------------------------------------------
在页面中调用函数的方式
<button onClick = { () => {
store.dispatch(add(1))//直接调用action内部的方法
}}>add</button>
--------------------------------------------------------------
在页面中显示store内的数据的方法
方法一:
{$store.getState().num}
getState()方法能够得到state中所有的值,但是对于state的修改不会显示在页面内
方法二:
import {connect} from 'react-redux' //用来连接组件和redux,获取redux中的数据
{this.props.num}
const mapStateToProps = (state) => {
return {
num: state.num//将state内的各个属性改为props
}
export default connect(mapStateToProps)(App);//向函数传递了两个参数第一个参数是props属性下的num,第二个参数是组件App
}