在很多情况下,State是Store对象的最重要的组成部分,是Store对象的核心,因为开发者在创建一个Store对象时,首先考虑的是State如何设计。在Pinia中,State是一个返回初始状态值的函数,通过函数的形式,既可以支持客户端,也能响应服务端。
1 构建和访问State
接下来在名称为useSchStore 的Store对象中,构建一个State函数,并在函数中,返回三个初始的状态值,一个名称为name,表示学校名称,另一个名称为count,表示在校学生数量,最后一个名称为grade,表示学校年级分类,具体实现的代码如下所示:
import { defineStore } from "pinia";
export const useSchStore = defineStore("sch_id", {state:()=> {return {name: "精英学校",count: 1200,grade:["小学","初中"],}}
})
为了使返回的对象属性能自动推断所属类型,建议使用箭头函数的方式来构建State,完成构建后,可以通过Store实例访问到State函数返回的属性值,并对其进行操作,例如,访问count属性,并在原有基础上增加1,实现代码如下所示
<script>
import { schStore } from "../../store/schStore"
export default {mounted(){const store = schStore();console.log(store.count);store.count++console.log(store.count);}
}
</script>
在上述加粗代码中,先使用变量store保存schStore的实例化对象,然后通过这个实例化对象直接访问count属性,并在控制台输出该属性的当前值,首次加载时,当前值为初始值,因此,第一次输出值为1200。
count属性值不仅可以访问输出,还可以进行操作,当执行store.count++语句后,当前的count属性值已加1,由原来的1200变成了1201,因此,第二次输出值为1201。
2 重置和变更State
当保存Store的实例化对象后,不仅可以访问和操作state对象的属性值,还可以直接调用$retset()方法,使用state对象重新还原成初始值,如下列代码所示:
<script>
import { schStore } from "../../store/schStore"
export default {mounted(){const store = schStore();console.log(store.count);store.count++console.log(store.count);store.$reset();console.log(store.count)}
}
</script>
在上述代码的加粗部分中,虽然前面对count属性进行了加1的操作,并输出count属性值为1201,但当调用$reset()重置方法后,State对象中的全部属性都还原为初始值,因此,再次输出count属性值时,则为初始值1200。
既可以通过Store 的实例化对象访问State的属性并变更它的值,还可以借助mapState函数将State属性映射为只读的计算属性,如果调用mapWritableState函数,则State属性映射后,还可以进行修改,实现代码如下所示:
<script>
import { mapState } from 'pinia'
import { schStore } from "../../store/schStore"
export default {computed: {...mapState(schStore, ['name'])},mounted(){console.log(this.name)}
}
</script>
在上述加粗代码中,调用mapState函数,可以将State中的name属性映射成computed对象中的只读成员,可以在mounted函数中直接访问,因此,上述代码执行后将会在控制台输出State对象中的name属性初始值,即输出“精英学校”字样。
虽然这种映射的方式可以访问State中的某个属性值,但它是只读的,不能修改这个属性的值,如果需要修改映射的值,可以调用mapWritableState函数,如下代码所示:
<script>
import { mapWritableState } from 'pinia'
import { schStore } from "../../store/schStore"
export default {computed: {...mapWritableState(schStore, ['name'])},mounted(){console.log(this.name)this.name = "重点中学";console.log(this.name)}
}
</script>
在上述加粗代码中,以可写的方式,将State中的name属性,映射成computed对象的一个成员,第一次输出默认的初始值“精英中学”,由于该属性允许修改,因此,经过修改后,第二次输出修改后的name属性的当前值“重点中学”。
3 其他操作方式
如果需要批量变更State中的多个属性值,可以调用Store实例化对象中的$patch方法,它可以用对象的形式在同一时间内,一次性更新多个属性值,如下列代码所示:
<script>
import { schStore } from "../../store/schStore"
export default {mounted() {const store = schStore();store.$patch({name: "全省重点中学",count: 2000})console.log(store.name)console.log(store.count)}
}
</script>
在上述加粗代码中,调用实例化对象store中的$patch方法,可以同时更新name和count这两个属性值,因此,代码执行后,第一次输出更新后的name属性值“全国重点中学”,第二次输出更新后的count属性值“2000”。
虽然这种对象形式的更新方式,可以一次更新多个属性值,但如果属性值是数组,这种更新方式的性能就非常低,为了解决这个问题,在调用$patch方法时,也允许使用一个函数的形式来实现多个属性的更新,如下代码所示:
<script>
import { schStore } from "../../store/schStore"
export default {mounted() {const store = schStore();store.$patch(state => {state.grade.push("高中");state.count = 5000;})console.log(store.grade)console.log(store.count)}
}
</script>
在上述加粗代码中,$patch方法中的state表示箭头函数的参数,代表Store对象中的State对象,因为是函数式操作,因此,可以直接通过push方式向数组类型的属性添加成员,也可以以赋值的方式重置属性值,操作完成后,第一次在控制台输出grade属性的全部内容“小学”、“中学”和“高中”,第二次在控制台输出重置后的count属性值 5000。