vue-9:pinia

pinia

  1. pinia天生支持模块化

  2. 天生支持组合式api

pinia 和 vuex对比

pinia和Vuex都是Vue.js状态管理库

  1. API的不同:Pinia提供了类似于Vuex的API,但使用起来更加简单直观。例如,Pinia使用defineStore定义store,而Vuex使用new Vuex.Store定义store。
  2. 数据响应式的不同:Pinia使用Vue 3的响应式系统,而Vuex使用Vue 2的响应式系统。Vue 3的响应式系统更加高效和灵活。
  3. 插件的不同:Vuex具有很多第三方插件,可以很方便地扩展其功能。而Pinia还比较年轻,目前可用的插件相对较少。
  4. TypeScript的支持:Pinia对TypeScript的支持更好,可以更好地利用TypeScript的类型检查功能,而Vuex的类型推断相对较弱。 总的来说,Pinia提供了一个更加简单和直观的API,并且使用Vue 3的响应式系统,但它的生态系统相对较小。而Vuex则具有更加丰富的生态系统和插件,并且对Vue 2和TypeScript的支持更好。在选择使用哪一个状态管理库时,需要根据具体项目需求和开发团队的技术栈来进行选择。

具体使用哪个状态管理库应该根据项目需求和个人喜好来决定。

使用

main.js中导入pinia持久化插件,实例化pinia,开启pinia使用持久化存储插件

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

//导入pinia持久化插件
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; //pinia持久化

const app = createApp(App)

//实例化pinia
var pinia = createPinia()
pinia.use( piniaPluginPersistedstate );

app.use( pinia )

app.mount('#app')

这点就和vuex不一样了,pinia就像菠萝一样,一个个模块。不用进行模块化管理,自己就是独立模块,更加便于管理。

eg:        sc.js文件

// 导入vue中的ref:可以将基本数据类型和引用数据类型转换成 响应式数据
// 导入计算属性
import {ref, computed} from 'vue'
import {defineStore } from 'pinia'
// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。

// 定义一个模块
export const usescStore = defineStore('sc',()=>{
    // 定义响应式数据
    const sc = ref([])

    var add = (payload) => {
        sc.value.push(10,payload)
    }
    return{
        sc,
        add
    }
},{persist:true})

经典案例todolist逻辑:::

tl.js文件

// 组合式写法:导入vue中ref和computed计算属性
// ref可以将基本数据类型和引用数据类型转换成=>响应式数据
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

// 定义一个模块
export const usetlStore = defineStore('tl', () => {
    // 定义响应式数据
    const tasklist = ref([])
    // 定义计算方法
    const finishCount = computed(() => {
        return tasklist.value.filter(item => item.status == true).length
    })
    const unfinishCount = computed(() => {
        return tasklist.value.filter(item => item.status == false).length
    })

    // 添加一个任务
    var addTask = (payload) => {
        let obj = {
            id: tasklist.value.length + 1,
            name: payload,
            status: false,
        }
        tasklist.value.push(obj)
        // console.log(tasklist.value);
    }
    // 更改任务的状态
    var changeStatus = (payload) => {
        let task = tasklist.value.find(item => item.id == payload)
        if (task) {
            task.status = !task.status;
        }
    }
    // 删除任务
    var deleteTask = (payload) => {
        let i = tasklist.value.findIndex(item => item.id == payload)
        if (i != -1) {
            tasklist.value.splice(i, 1)
        }
    }
    //请求任务列表数据
    var request_tasklist = () => {
        // 用计时器模拟ajax请求
        setTimeout(() => {
            var arr = [
                { id: 1, name: 'vuejs', status: false },
                { id: 2, name: 'reactjs', status: false },
            ]
            tasklist.value = arr
        }, 1000)
    }



    return {
        tasklist,        
        finishCount,
        unfinishCount,
        addTask,
        request_tasklist,
        changeStatus,
        deleteTask,

    }
}, { persist: true })
// 开启可持续化存储

页面布局:

SearchCom.vue

<template>
  <div class="search-box">
    <input type="text" placeholder="输入任务名称" v-model="name"> <button @click="add">添加</button>
  </div>
  <!-- {
   
   { scStore.sc }} -->
</template>

<script>
import { ref } from 'vue'
import { usetlStore } from '@/stores/tl'
import { usescStore } from '@/stores/sc'
export default {
  setup() {
    // 获取模块实例
    let tlStore = usetlStore()
    let scStore = usescStore()
    let name = ref('')
    let add = () => {
      if (name.value) {
        // 调用模块中的方法,新增任务
        tlStore.addTask(name.value)
        // 点击清空输入框
        scStore.add(name.value)
        name.value = ''
      }

    }
    return {
      name,
      tlStore,
      scStore,
      add,
    }
  }
}
</script>

<style scope>
.search-box {
  margin: 10px;
  display: flex;
  align-items: center;
}

.search-box input {
  flex: 1;
  height: 40px;
  background-color: #f5f5f5;
  border-radius: 20px;
  padding-left: 20px;
  outline: none;
  border: none;
}

.search-box button {
  width: 60px;
  text-align: center;
  height: 40px;
  outline: none;
  appearance: none;
  border: none;
  background-color: transparent;
}
</style>

Summary.vue

<template>
  <div class="summary">
    <span>全部任务( {
   
   { tlStore.tasklist.length }} )</span>
    <span>已完成{
   
   { tlStore.finishCount }}</span>
    <span class="unfinish">未完成{
   
   { tlStore.unfinishCount }}</span>
  </div>
</template>

<script>
// 导入模块
import { usetlStore } from '@/stores/tl'
export default{
  setup(){
    // 获取模块实例
    var tlStore = usetlStore()
    return{
      tlStore
    }
  }
}
</script>

<style scoped>
.summary{
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.summary span{
    padding: 5px 20px;
    text-align: center;
    color: white;
    background-color: lightseagreen;
    border-radius: 5px;
    font-size: 14px;
}
.summary span.unfinish{
    background-color: red;
}
</style>

List.vue

<template>
    <div class="list">
        <div class="title">任务列表</div>
        <div :class="{task:true,unfinish:item.status}" v-for="(item,index) in tlStore.tasklist" :key="index">
            <div class="left">
                <input type="checkbox" :checked="item.status" @click="change(item.id)">
                <span>{
   
   { item.id }} </span>
                <span>{
   
   { item.name }} </span>
            </div>
            <span @click="del(item.id)">删除</span>
        </div>
    </div>
</template>

<script>
// 导入模块
import {usetlStore} from '@/stores/tl'
export default {
    setup() {
        // 获取模块实例
        var tlStore = usetlStore()
        // 定义方法
        var change = (id)=>{
            tlStore.changeStatus(id);
        }
        var del = (id)=>{
            tlStore.deleteTask(id)
        }


        return {
            tlStore,
            change,
            del
        }
    }
}
</script>

<style scoped>
.list .title {
    font-weight: bold;
    margin: 20px 0;
}

.list .task {
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: white;
    font-size: 14px;
    padding: 10px;
    margin: 10px 0;
    background-color: lightseagreen;
}

.list .task.unfinish {
    background-color: red;
}
</style>

猜你喜欢

转载自blog.csdn.net/qq_60839348/article/details/130675311