1.安装pinia
 npm i pinia -S
2.在main.js中注册
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import './assets/index.css'

const store = createPinia()

const app = createApp(App)

app.use(store).use(router).mount('#app')

3.新建一个store文件,下面新建一个index.js文件,写入如下内容
import { defineStore } from 'pinia'
import axios from 'axios'
//这里是对pinia进行一个取名,state需要时一个函数的形式
export default defineStore('main', {
  state: () => {
    return {
      count: 10,
      name: '何志伟'
    }
  },
})
4.读取pinia里面的内容,并且渲染,在相应的页面中引入pinia,并使用。
<template>
  <div class="container">
    <h1>商品数量:{{ store.count }} </h1>
    <h4>名称:{{ store.name }}</h4>
    <button @click="handleAdd">pinia的count给我+</button>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import useMainStore from '@/store'
//引入pinia,并使用
import { storeToRefs } from 'pinia';
const store = useMainStore()

//这里是不通过解构,直接对pinia中的count值进行增加
const handleAdd = () => {
  store.count++
}


//这里是通过解构,对pinia的进行增加,但是解构他的值的增加却不是响应式,需要通过storeToRefs完成响应式,还需要加上value才能实现响应
// 2.可以对pinia的值进行结构,然后通过他的storeToRefs完成响应式
let { count,sumPrice,timuList } = storeToRefs(store);
// 这里如果要实现相应,必须加上value
const add = () => {
  count.value++
}

</script>

<style lang="scss" scoped>
</style>

5.pinia进阶,$patch的使用
首先我们了解一下 p a t c h 的作用,当你需要对多个值进行修改的时候,这个时候我们会需要使用到 patch的作用,当你需要对多个值进行修改的时候,这个时候我们会需要使用到 patch的作用,当你需要对多个值进行修改的时候,这个时候我们会需要使用到patch,下面我们直接上例子。
5.1这是pinia的index.js文件,现在我们需要同时修改count的值,以及增加list里面的值,这个时候我们就会用到$patch。
import { defineStore } from 'pinia'
import axios from 'axios'
export default defineStore('main', {
  state: () => {
    return {
      count: 10,
      name: '老6',
      list: [{
        name: 'ipone',
        price: 5800,
        count:1
      }
    }
  }
})
这是对应的vue页面,这里我们可以看到,上面的count和下面的list都发生了改变
<template>
  <div class="container">
    <h1>商品数量:{{ store.count }} </h1>
    <h1>通过$patch进行修改</h1>
    <ul>
      <li v-for="(item, index) in store.list" :key="index">
      <span>名字:{{item.name}}</span> 
      <span>数量:{{item.count}}</span> 
      <span>价格:{{item.price}}</span> 
      </li>
    </ul>
    <button @click="patchClick">增加</button>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import useMainStore from '@/store'
import { storeToRefs } from 'pinia';
const store = useMainStore()
const patchClick = () => {
  // $patch可以对多个数据同时进行修改
  // 通过函数进行修改
  store.$patch((state) => {
    state.count += 10;
    state.list.push({
      name:'老6',
      price:30000,
      count:222
    })
  })
}
</script>
6.pinia中getter的使用
import { defineStore } from 'pinia'
import axios from 'axios'
export default defineStore('main', {
  state: () => {
    return {
      count: 10,
      name: '何志伟',
      list: [{
        name: 'ipone',
        price: 5800,
        count:1
      },
      {
        name: 'huawei',
        price: 5800,
        count:2
      }]
    }
  },
  //这里我们通过getter计算出list商品数量的价钱
  getters: {
    sumPrice: (state) => {
      // reduce   pre是旧的值 item是list的每一项
       return state.list.reduce((pre,item) => {
        return pre + (item.price * item.count)
       },0)
    }
  },
})
对应的vue页面如何接收并使用呢
<template>
  <div class="container">
    <h1>商品数量:{{ store.count }} </h1>
    <h4>名称:{{ store.name }}</h4>
    <button @click="handleAdd">pinia的count给我+</button>
    <hr>
    <h4>{{ count }}</h4>
    <button @click="add">结构后的值+1</button>
    <hr>
    <h1>通过$patch进行修改</h1>
    <ul>
      <li v-for="(item, index) in store.list" :key="index">
      <span>名字:{{item.name}}</span> 
      <span>数量:{{item.count}}</span> 
      <span>价格:{{item.price}}</span> 
      </li>
    </ul>
    <!-- 如果不进行结构,直接使用store.sumPrice进行渲染  -->
    <h3>总价:{{store.sumPrice}}</h3>
    <!-- 解构后直接使用 但是需要storeToRefs进行响应绑定 -->
    <h3>结构后显示总价:{{sumPrice}}</h3>
    <button @click="patchClick">增加</button>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import useMainStore from '@/store'
import { storeToRefs } from 'pinia';
const store = useMainStore()

const handleAdd = () => {
  store.count++
}


// 2.可以对pinia的值进行结构,然后通过他的storeToRefs完成响应式
let { count,sumPrice,timuList } = storeToRefs(store);
// 这里如果要实现相应,必须加上value
const add = () => {
  count.value++
}

const patchClick = () => {
  // $patch可以对多个数据同时进行修改
  // 通过函数进行修改
  store.$patch((state) => {
    state.count += 10;
    state.list.push({
      name:'老6',
      price:30000,
      count:222
    })
  })
}
</script>

<style lang="scss" scoped>
</style>

7.pinia中actions的使用。
在pinia中,actions可以使用同步任务,也可以使用异步任务。
下面我们模拟一个接口,对actions的执行异步进行模拟,也顺便对actions使用有所了解
7.1我们先在public目录下新建一个teach.json文件,写入如下内容
{
  "sites": [
  { "name":"菜鸟教程" , "url":"www.runoob.com" }, 
  { "name":"google" , "url":"www.google.com" }, 
  { "name":"微博" , "url":"www.weibo.com" }
  ]
}
7.2在pinia的index.js文件下,在state和getter同级下写入actions,并发送axios请求
import { defineStore } from 'pinia'
import axios from 'axios'
export default defineStore('main', {
  state: () => {
    return {
      count: 10,
      name: '何志伟',
      list: [{
        name: 'ipone',
        price: 5800,
        count:1
      },
      {
        name: 'huawei',
        price: 5800,
        count:2
      }],
      timuList:[]
    }
  },
  getters: {
    sumPrice: (state) => {
      // reduce是初始值 item是list的每一项
       return state.list.reduce((pre,item) => {
        return pre + (item.price * item.count)
       },0)
    }
  },
  // 同步和异步皆可
  actions: {
    async getTimu() {
     const {data:res} = await axios.get('/timu.json')
     console.log(res);
     console.log();
     //上面定义的数据,下面要使用,通过this获取
     this.timuList = res.sites
    }
  }
})
7.3在对应的vue界面使用并渲染,使用可以直接通过store.getTimu进行使用
<button @click="store.getTimu">actions获取异步数据</button>

也可以

<button @click="getItTimu">解构获取异步数据</button>
const getItTimu = () => {
  store.getTimu()
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐