vue-9: pinia

beans

  1. pinia inherently supports modularity

  2. Composable APIs are natively supported

Comparison between pinia and vuex

Both pinia and Vuex are Vue.js state management libraries

  1. API difference: Pinia provides an API similar to Vuex, but it is simpler and more intuitive to use. For example, Pinia uses defineStorea definition store, while Vuex uses new Vuex.Storea definition store.
  2. The difference in data responsiveness: Pinia uses Vue 3's responsive system, while Vuex uses Vue 2's responsive system. Vue 3's responsive system is more efficient and flexible.
  3. Different plug-ins: Vuex has many third-party plug-ins, which can easily extend its functions. While Pinia is still relatively young, relatively few plugins are currently available.
  4. TypeScript support: Pinia has better support for TypeScript and can take better advantage of TypeScript's type checking capabilities, while Vuex's type inference is relatively weak. Overall, Pinia offers a simpler and more intuitive API and uses Vue 3's reactivity system, but its ecosystem is relatively small. Vuex, on the other hand, has a richer ecosystem and plugins, and better support for Vue 2 and TypeScript. When choosing which state management library to use, you need to choose according to the specific project requirements and the technology stack of the development team.

Which state management library to use should be decided based on project requirements and personal preferences.

use

Import the pinia persistent plug-in in main.js , instantiate pinia, and enable pinia to use the persistent storage plug-in

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')

This is different from vuex, pinia is like a pineapple, each module. There is no need for modular management, and it is an independent module, which is easier to manage.

eg:         sc.js file

// 导入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})

Classic case todolist logic:::

tl.js file

// 组合式写法:导入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 })
// 开启可持续化存储

Page Layout:

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>

Guess you like

Origin blog.csdn.net/qq_60839348/article/details/130675311