Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimana untuk bermula dengan pengurusan negeri baharu Vue, Pinia, baca artikel ini!

Bagaimana untuk bermula dengan pengurusan negeri baharu Vue, Pinia, baca artikel ini!

青灯夜游
青灯夜游ke hadapan
2022-03-18 11:14:312392semak imbas

Pinia ialah perpustakaan pengurusan negeri baharu yang dibangunkan oleh Vue, jadi bagaimanakah orang baru bermula dengan Pinia? Artikel berikut akan memperkenalkan anda kepada Pinia dan memperkenalkan ciri terasnya dan penggunaan mudah saya harap ia akan membantu anda!

Bagaimana untuk bermula dengan pengurusan negeri baharu Vue, Pinia, baca artikel ini!

Vuex ialah perpustakaan pengurusan negeri Vue lama yang semua orang kenali

Pinia ialah perpustakaan baharu yang dibangunkan khusus untuk Vue oleh ahli Vue. js team Perpustakaan pengurusan negeri, dan telah dimasukkan ke dalam github

rasmi Mengapa kita perlu membangunkan Pinia lain apabila terdapat Vuex?

Mari ambil gambar dahulu dan lihat cadangan untuk Vuex5 pada masa itu , yang sepatutnya kelihatan seperti Vuex5 generasi akan datang. [Cadangan berkaitan: tutorial video vuejs]

Bagaimana untuk bermula dengan pengurusan negeri baharu Vue, Pinia, baca artikel ini!

Pinia mematuhi sepenuhnya perkara fungsi yang disebut dalam cadangan Vuex5nya pada masa itu, jadi boleh dikatakan bahawa Pinia Tidak keterlaluan untuk mengatakan bahawa ia adalah Vuex5, kerana pengarangnya adalah pembangun rasmi dan telah diambil alih secara rasmi Walau bagaimanapun, Vuex dan Pinia masih merupakan dua gudang bebas pada masa ini masa depan, tetapi mereka pasti disyorkan oleh rasmi Perkara yang paling penting ialah Pinia

Kerana menggunakan Vuex dalam Vue3 memerlukan penggunaan Vuex4, yang hanya boleh digunakan sebagai pilihan peralihan dan mempunyai kekurangan yang besar, selepas kelahiran daripada Componsition API, Pinia pengurusan negeri baharu telah direka bentuk

Pinia dan Vuex

Vuex: State, Gettes, Mutations(segerak) , Actions(tak segerak)

Pinia: State, Gettes, Actions (kedua-dua segerak dan tak segerak disokong)

Versi terkini Vuex ialah 4.x

  • Vuex4 For Vue3
  • Vuex3 for Vue2

Pinia versi terkini ialah 2.x

  • , yang menyokong kedua-dua Vue2 dan Vue3

Buat masa ini, Pinia jauh lebih baik daripada Vuex dan menyelesaikan banyak masalah Vuex, jadi saya sangat mengesyorkan menggunakan Pinia secara langsung, terutamanya untuk projek TypeScript

Ciri teras Pinia

  • Pinia tidak mempunyai Mutations
  • Actions menyokong segerak dan tak segerak
  • Tiada struktur modul bersarang
    • Pinia menyediakan struktur rata mengikut reka bentuk, yang bermaksud setiap kedai adalah bebas antara satu sama lain, tiada sesiapa pun milik sesiapa, iaitu rata, dengan pemisahan kod yang lebih baik dan tiada ruang nama. Sudah tentu anda juga boleh menyimpan stor secara tersirat dengan mengimport modul lain dalam satu modul, malah mempunyai kebergantungan bulat stor
  • Sokongan TypeScript yang lebih baik
    • Tidak perlu untuk membuat pembungkus kompleks tersuai untuk menyokong TypeScript Semuanya ditaip, dan API direka bentuk untuk menggunakan inferens jenis TS di mana mungkin
  • Tiada suntikan diperlukan, fungsi import, hubungi mereka, nikmati penyiapan automatik. , menjadikan pembangunan kami lebih mudah
  • Tidak perlu menambah kedai secara manual, modulnya didaftarkan secara automatik secara lalai apabila ia dibuat
  • Kedua-dua Vue2 dan Vue3 menyokongnya
    • Kecuali untuk pemasangan awal dan konfigurasi SSR, API yang digunakan oleh kedua-duanya adalah sama
  • Menyokong Vue DevTools
    • tindakan penjejakan, Garis masa mutasi
    • Anda boleh melihat modul itu sendiri dalam komponen yang menggunakan modul
    • Sokong perjalanan masa untuk penyahpepijatan yang lebih mudah
    • Dalam Vue2, Pinia akan menggunakan antara muka Vuex All, jadi ia tidak boleh digunakan bersama
    • Tetapi sokongan alat penyahpepijatan untuk Vue3 tidak cukup sempurna, contohnya, tiada fungsi perjalanan masa
  • Kemas kini panas modul
    • Modul boleh diubah suai tanpa memuatkan semula halaman
    • Sebarang status sedia ada akan dikekalkan semasa kemas kini hangat
  • Menyokong penggunaan pemalam untuk melanjutkan fungsi Pinia
  • Sokong pemaparan sebelah pelayan

Pinia menggunakan

mengambil Vue3 TypeScript sebagai contoh

pemasangan

npm install pinia

main.ts permulaan konfigurasi

import { createPinia } from 'pinia'createApp(App).use(createPinia()).mount('#app')

Buat user.ts dalam direktori kedai Sebagai contoh, kami mula-mula menentukan dan mengeksport modul bernama user

import { defineStore } from 'pinia'
export const userStore = defineStore('user', {
    state: () => {
        return { 
            count: 1,
            arr: []
        }
    },
    getters: { ... },
    actions: { ... }
})

defineStore untuk menerima dua parameter.

Parameter pertama ialah nama modul, yang mesti unik, berbilang modul tidak boleh mempunyai nama yang sama. pilihan di dalam adalah serupa dengan Vuex

  • 其中 state 用来存储全局状态,它必须是箭头函数,为了在服务端渲染的时候避免交叉请求导致的数据状态污染所以只能是函数,而必须用箭头函数则为了更好的 TS 类型推导
  • getters 就是用来封装计算属性,它有缓存的功能
  • actions 就是用来封装业务逻辑,修改 state

访问 state

比如我们要在页面中访问 state 里的属性 count

由于 defineStore 会返回一个函数,所以要先调用拿到数据对象,然后就可以在模板中直接使用了

<template>
    <div>{{ user_store.count }}</div>
</template>
<script setup>
import { userStore } from &#39;../store&#39;
const user_store = userStore()
// 解构
// const { count } = userStore()
</script>

比如像注释中的解构出来使用,是完全没有问题的,只是注意了,这样拿到的数据不是响应式的,如果要解构还保持响应式就要用到一个方法 storeToRefs(),示例如下

<template>
    <div>{{ count }}</div>
</template>
<script setup>
import { storeToRefs } from &#39;pinia&#39;
import { userStore } from &#39;../store&#39;
const { count } = storeToRefs(userStore)
</script>

原因就是 Pinia 其实是把 state 数据都做了 reactive 处理,和 Vue3 的 reactive 同理,解构出来的也不是响应式,所以需要再做 ref 响应式代理

getters

这个和 Vuex 的 getters 一样,也有缓存功能。如下在页面中多次使用,第一次会调用 getters,数据没有改变的情况下之后会读取缓存

<template>
    <div>{{ myCount }}</div>
    <div>{{ myCount }}</div>
    <div>{{ myCount }}</div>
</template>

注意两种方法的区别,写在注释里了

getters: {
    // 方法一,接收一个可选参数 state
    myCount(state){
        console.log(&#39;调用了&#39;) // 页面中使用了三次,这里只会执行一次,然后缓存起来了
        return state.count + 1
    },
    // 方法二,不传参数,使用 this
    // 但是必须指定函数返回值的类型,否则类型推导不出来
    myCount(): number{
        return this.count + 1
    }
}

更新和 actions

更新 state 里的数据有四种方法,我们先看三种简单的更新,说明都写在注释里了

<template>
    <div>{{ user_store.count }}</div>
    <button @click="handleClick">按钮</button>
</template>
<script setup>
import { userStore } from &#39;../store&#39;
const user_store = userStore()
const handleClick = () => {
    // 方法一
    user_store.count++
    
    // 方法二,需要修改多个数据,建议用 $patch 批量更新,传入一个对象
    user_store.$patch({
        count: user_store.count1++,
        // arr: user_store.arr.push(1) // 错误
        arr: [ ...user_store.arr, 1 ] // 可以,但是还得把整个数组都拿出来解构,就没必要
    })
    
    // 使用 $patch 性能更优,因为多个数据更新只会更新一次视图
    
    // 方法三,还是$patch,传入函数,第一个参数就是 state
    user_store.$patch( state => {
        state.count++
        state.arr.push(1)
    })
}
</script>

第四种方法就是当逻辑比较多或者请求的时候,我们就可以封装到示例中 store/user.ts 里的 actions 里

可以传参数,也可以通过 this.xx 可以直接获取到 state 里的数据,需要注意的是不能用箭头函数定义 actions,不然就会绑定外部的 this 了

actions: {
    changeState(num: number){ // 不能用箭头函数
        this.count += num
    }
}

调用

const handleClick = () => {
    user_store.changeState(1)
}

支持 VueDevtools

打开开发者工具的 Vue Devtools 就会发现 Pinia,而且可以手动修改数据调试,非常方便

Bagaimana untuk bermula dengan pengurusan negeri baharu Vue, Pinia, baca artikel ini!

模拟调用接口

示例:

我们先定义示例接口 api/user.ts

// 接口数据类型
export interface userListType{
    id: number
    name: string
    age: number
}
// 模拟请求接口返回的数据
const userList = [
    { id: 1, name: &#39;张三&#39;, age: 18 },
    { id: 2, name: &#39;李四&#39;, age: 19 },
]
// 封装模拟异步效果的定时器
async function wait(delay: number){
    return new Promise((resolve) => setTimeout(resolve, delay))
}
// 接口
export const getUserList = async () => {
    await wait(100) // 延迟100毫秒返回
    return userList
}

然后在 store/user.ts 里的 actions 封装调用接口

import { defineStore } from &#39;pinia&#39;
import { getUserList, userListType } from &#39;../api/user&#39;
export const userStore = defineStore(&#39;user&#39;, {
    state: () => {
        return {
            // 用户列表
            list: [] as userListType // 类型转换成 userListType
        }
    },
    actions: { 
        async loadUserList(){
            const list = await getUserList()
            this.list = list
        }
    }
})

页面中调用 actions 发起请求

<template>
    <ul>
        <li v-for="item in user_store.list"> ... </li>
    </ul>
</template>
<script setup>
import { userStore } from &#39;../store&#39;
const user_store = userStore()
user_store.loadUserList() // 加载所有数据
</script>

跨模块修改数据

在一个模块的 actions 里需要修改另一个模块的 state 数据

示例:比如在 chat 模块里修改 user 模块里某个用户的名称

// chat.ts
import { defineStore } from &#39;pinia&#39;
import { userStore } from &#39;./user&#39;
export const chatStore = defineStore(&#39;chat&#39;, {
    actions: { 
        someMethod(userItem){
            userItem.name = &#39;新的名字&#39;
            const user_store = userStore()
            user_store.updateUserName(userItem)
        }
    }
})

user 模块里

// user.ts
import { defineStore } from &#39;pinia&#39;
export const userStore = defineStore(&#39;user&#39;, {
    state: () => {
        return {
            list: []
        }
    },
    actions: { 
        updateUserName(userItem){
            const user = this.list.find(item => item.id === userItem.id)
            if(user){
                user.name = userItem.name
            }
        }
    }
})

(学习视频分享:vuejs教程web前端

Atas ialah kandungan terperinci Bagaimana untuk bermula dengan pengurusan negeri baharu Vue, Pinia, baca artikel ini!. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam