Example of using vue3 Pinia


foreword

Piniais Vuea repository for , which allows you to share state across components/pages. If you're familiar Composition API, you might think that you can already pass a simple export const state = reactive({}). This is true for a single-page application, but if it's server-side rendered, it exposes your application to security holes. But even in small single-page applications, you can Piniagain a lot from using :

  • dev-tools support
    1, track actions, a timeline of mutations
    2, Storeappear in the components that use them
    3, time traveland easier debugging

  • Hot Module Replacement
    1. Modify yours without reloading the page Store
    2. Keep any existing state while developing

  • PluginsPinia : Extend functionality with plugins

  • Proper TypeScript support or autocompletion for JS users

  • Server-side rendering support


1. Basic example

This is what usage looks like piniain APIterms of . You first create a Store:

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

export const useCounterStore = defineStore('counter', {
    
    
  state: () => {
    
    
    return {
    
     count: 0 }
  },
  // 也可以定义为
  // state: () => ({ count: 0 })
  actions: {
    
    
    increment() {
    
    
      this.count++
    },
  },
})

Then you use it in a component:

import {
    
     useCounterStore } from '@/stores/counter'

export default {
    
    
  setup() {
    
    
    const counter = useCounterStore()

    counter.count++
    // 带自动补全 ✨
    counter.$patch({
    
     count: counter.count + 1 })
    // 或使用 action 代替
    counter.increment()
  },
}

You can even use a function (similar to a component setup()) to define one for more advanced use cases Store:

export const useCounterStore = defineStore('counter', () => {
    
    
  const count = ref(0)
  function increment() {
    
    
    count.value++
  }

  return {
    
     count, increment }
})

If you're not familiar setup()with and Composition API, don't worry, Piniaa similar set is also supported map helpers like Vuex. You define storage the same way, but then use mapStores(), mapState()or mapActions():

const useCounterStore = defineStore('counter', {
    
    
  state: () => ({
    
     count: 0 }),
  getters: {
    
    
    double: (state) => state.count * 2,
  },
  actions: {
    
    
    increment() {
    
    
      this.count++
    }
  }
})

const useUserStore = defineStore('user', {
    
    
  // ...
})

export default {
    
    
  computed: {
    
    
    // other computed properties
    // ...
    // gives access to this.counterStore and this.userStore
    ...mapStores(useCounterStore, useUserStore)
    // gives read access to this.count and this.double
    ...mapState(useCounterStore, ['count', 'double']),
  },
  methods: {
    
    
    // gives access to this.increment()
    ...mapActions(useCounterStore, ['increment']),
  },
}

2. A more realistic example

Here's a more complete example of the API you'll Piniause with even JavaScripthaving types in . For some, this may be enough to get started without further reading, but we still recommend looking at the rest of the documentation, or even skipping this example, and coming back after reading all of the _core concepts_.

import {
    
     defineStore } from 'pinia'

export const todos = defineStore('todos', {
    
    
  state: () => ({
    
    
    /** @type {
    
    { text: string, id: number, isFinished: boolean }[]} */
    todos: [],
    /** @type {'all' | 'finished' | 'unfinished'} */
    filter: 'all',
    // type 会自动推断为 number
    nextId: 0,
  }),
  getters: {
    
    
    finishedTodos(state) {
    
    
      // 自动完成! ✨
      return state.todos.filter((todo) => todo.isFinished)
    },
    unfinishedTodos(state) {
    
    
      return state.todos.filter((todo) => !todo.isFinished)
    },
    /**
     * @returns {
    
    { text: string, id: number, isFinished: boolean }[]}
     */
    filteredTodos(state) {
    
    
      if (this.filter === 'finished') {
    
    
        // 自动调用其他 getter ✨
        return this.finishedTodos
      } else if (this.filter === 'unfinished') {
    
    
        return this.unfinishedTodos
      }
      return this.todos
    },
  },
  actions: {
    
    
    // 任何数量的参数,返回一个 Promise 或者不返回
    addTodo(text) {
    
    
      // 你可以直接改变状态
      this.todos.push({
    
     text, id: this.nextId++, isFinished: false })
    },
  },
})

3. Comparison with Vuex

PiniaIt was originally intended to explore Vuexwhat the next iteration of , incorporating Vuex 5many of the ideas discussed in the core team. Eventually, we realized that Piniaalready implemented Vuex 5most of what we wanted in and decided to implement it instead with new suggestions.

Provides a simpler one than Vuex, has fewer specifications, provides style , and most importantly, has solid type inference support when used with .PiniaAPIComposition-APIAPITypeScript

RFC#
Although Vuexpassed to RFCcollect as much feedback as possible from the community, Piniait did not. I test ideas based on my experience developing applications, reading other people's code, Piniaworking for clients who use , and answering questions on . DiscordThis allows me to provide an efficient solution for various situations and application sizes. I release frequently and APIkeep the library evolving while keeping its core intact.

1. Comparison with Vuex 3.x/4.x

| Vuex 3.x is Vuex's Vue 2 and Vuex 4.x is Vue 3

Pinia API is very different from Vuex ≤4, namely:

  • mutationsno longer exists. They are often considered very verbose. They initially brought devtoolsintegration, but that's no longer an issue.
  • There's no need to create custom complex wrappers to support that TypeScript, everything is typed, and is APIdesigned in such a way to leverage TStype inference as much as possible.
  • No more injecting, importing functions, calling functions, enjoying autocompletion!
  • No need to add dynamically Store, they are all dynamic by default and you won't even notice. Note that you can still manually Storeregister with at any time, but since it's automatic, you don't need to worry about it.
  • There is no nested structure of modules anymore. You can still Storeimplicitly nest by importing and using within another Store, but Piniaprovide a flat structure by design while still supporting Storeintersecting composability between . You can even have Storecircular dependencies for .
  • There is no namespace module. Given Storethe flat architecture of a 'namespace' Storeis inherent in the way it's defined, you could say that all Storeare namespaced.

Summarize

The above is what I want to talk about today. This article only briefly introduces Piniathe use of .

Supongo que te gusta

Origin blog.csdn.net/klylove/article/details/125826965
Recomendado
Clasificación