pinia个人学习笔记

替代vuex的,可好用了

基本使用

写一个pinia

一种是这样用的,state返回的东西呢,在外部就可以直接用

//counter.js
import { defineStore } from 'pinia'

export const mainStore = defineStore('main',{
  state:()=>{
    return {
      name: 'hello',
      counter: 0
    }
  },
  getters:{},
  actions:{
      
  }

})

另一种写法是

//counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
    const obj = reactive({
        name:'tom'
    })
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment ,obj }
})

这个return什么的,也是可以拿到的

调用他

//导入store
import {mainStore,useCounterStore} from "@/stores/counter";
//pinia
onMounted(()=>{
  //  使用store
  const store = mainStore()
  console.log(store.name) //hello

  //  使用store
  const param = useCounterStore()
  console.log(param.count) //0
  param.increment() //让count++
  console.log(param.count) //1
})

改变值

像常量一样地改变

和vuex一样,pinia存在的意义就是为了响应式地保存全局的值和改变值,但是pinia改变值可简单了
还是上面地例子,使用useCounterStore

import {useCounterStore} from "@/stores/counter";
//pinia
onMounted(()=>{
    
    // 此时,param = {
    //     count = 0 , 
    //     doubleCount = 0 , 
    //     increment = () => { count.value++ }
    // }
    const param = useCounterStore()
    
    console.log(param.count) // 0
    
    //在这里,就进行了pinia的值的改变,很普通地改变,不写注释完全没有注意到是利用pinia进行全局调用了
    //再也不用像vuex一样发action之类地这么麻烦
    param.count ++
    
    //此刻,在其他组件中打印,也是 1 !!
    console.log(param.count) // 1

})

如果不想用单个对象接受,喜欢用const { a,b} = obj这种方式,调用一个方法就可以

import {storeToRefs} from "pinia/dist/pinia";

onMounted(()=>{
  // const store = mainStore()
  // console.log(store.name)

    //storeToRefs是pinia提供的
  const { count } = storeToRefs(useCounterStore())
  console.log(count.value) // 0 

  count.value ++
  // param.count ++
  console.log(count .value) // 1

})

传对象,改对象都是可以地

比如加多一个obj = {name:'tom''}给useCounterStore

//counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
    const obj = reactive({
        name:'tom'
    })


  return { count ,obj }
})
  const store = useCounterStore()

  console.log(store.obj.name) //tom

  store.obj = {
    age : 12
  }
  console.log(store.obj.age) //12 srore.obj.tom是不存在的了

$patch的改变方式

像上面的store.count ++,也确实是可以胜任大多数工作了。
$patch是用于同时改变多个值的情况
比如一个按钮,点击事件,那就是

//点击事件
const changPinia = () => {
    const store = useCounterStore()

    // 多个值进行改变
    store.$patch({
        count: 1,
        obj: {
            name: 'jack'
        }
    })
    console.log(store) //就是改变值之后的了
}

$patch((state) => {} 的方式

这个我也不知道和上面有什么区别,官方说的我也不懂额
反正可以这样用

const changPinia = async () => {
  const store = useCounterStore()

  store.$patch((state) => {
    state.count = 1
    state.obj.name = 'jack'
    //这种是不行的
    // state.obj = {
    //   name: 'jack'
    // }
  })
  console.log(store)
}

在这里,传一个对象={}就传不过去,不知道为什么

在store里面写函数进行调用

可以看到上面的例子,useCounterStore除了到处count,还有一个increment函数,这个数可以让count++,直接调用,也是响应式的,其他组件拿到的值也会更新

onMounted(()=>{

  const store = useCounterStore()
  console.log(store.count) // 0

  store.increment() // store.count ++ 
  console.log(store.count) //1


})

直接调用store里面的函数,在setup写法是function就行,在选项式中要长这样,写在action里面

export const mainStore = defineStore('main',{
  state:()=>{
    return {
      name: 'hello',
      counter: 0
    }
  },
  getters:{},
  actions:{
    change(){
      this.counter = 1
    }
  }
})

选项式和组合式pinia的转换

一开始的2个例子,一个就是用选项式的,一个就是组合式的,目前尤雨溪推荐组合式的

export const mainStore = defineStore('main',{
  state:()=>{
    return {
      name: 'hello',
      counter: 0
    }
  },
  getters:{
    counterShow(state){
      return state.counter + 2;
    }
  },
  actions:{
    change(){
      this.counter = 1
    }
  }
})

转换成组合式就是

export const mainStore = defineStore('main', () => {
    //state
    const name = ref('hello')
    const counter = ref(0)

    // getters
    const counterShow = computed(() => {
        return counter.value + 2
    })

    //action
    const change = () => {
        counter.value++
    }
    return {name, counter, counterShow, change}
})

调用的方法都是一样的

全局注册避免重复打包

可以看到,pinia的使用流程是这样的


但是如果user store在每个组件都用到,每个组件都要将store打包一次,就会越来越大了

所以我们最好用一个全局注册的总入口,组件调用先调用总入口,再从总入口调用对应的store

但是!我不知道怎么做,没实践过,给后日留坑了

注意的点

1)注意的是,pinia要使用的时候,最好都是在内部生成一个store的,不要在外面生成,比如

setup

//不好
const store = mainStore()

onMounter(()=>{
    //好
    const store = mainStore()
    
})

2)番外:useStorage的使用

useSessionStorage('sid',"asd") 
//等价于
sessionStorage.setItem("sid","asd")

useSessionStorage('sid',null)
//等价于
sessionStorage.getItem("sid")

3)如果和localStorage或者useSessionStorage绑定了,也会自动改变

比如一开始就定义了 const sid = ref(useSessionStorage('sid',null))
那么在用pinia的时候改变了sid的值,不用手动改他会直接将sessionStorage中的值也一起修改的

建议就是,基础类型传空,对象类型需要设置一下

  //相当于获取值
  const sid = ref(useSessionStorage('sid', null))
  //相当于获取值,要加配置{}则不传,不然会默认传个{}的
  const userInfo = reactive(useSessionStorage('userInfo', {},{writeDefaults:false}))

4)在store里面写watch也是能够观察到的

5)bug?

有个很奇怪的点,当pinia和useStorage绑定的时候,如果我想直接通过useStorage访问存储,会返回一个proxy或者refImpl,而且转格式也转不回来。
就只能通过pinia来读取了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值