Pinia+Router学习笔记(四)

简介: 本节记录Pinia中Action和Getters相关知识点

Actions:
Actions是pinia和Vuex封装函数逻辑的对象,作用是可以让我们在组件中直接调用,简化了状态管理的过程。Action可以写成同步的,也可以写成异步,其中的函数还可以相互调用

import { defineStore } from 'pinia'
import { Names } from './store-name'

type User = {
    name: string
    message: string
}

export const useTestStore = defineStore(Names.TEST, {
    state: () => {
        return {
      // 这里采用了给对象属性限制类型的写法
            user: <User>{
                name: '飞机',
                message: '666',
            },
        }
    },
    // computed一些值
    getters: {},
    // 相当于methods,可以做同步、异步操作、提交state等
    actions: {
    // 最简单的Action,直接在组件中调用即可
        setCurrent() {
            this.user.message = 'message被改变了'
        },
    },
})
<template>
    <div>user:{{ Test.user }}</div>
    <hr />
    <div>name:{{ Test.name }}</div>
    <button @click="change">change</button>
</template>

<script setup lang="ts">
import { useTestStore } from './Store'
import { storeToRefs } from 'pinia'

const Test = useTestStore()
  // 直接来一个Test.setCurrent调用
const change = () => {
    Test.setCurrent()
}
</script>

<style scoped></style>

一个异步调用的例子:将异步方法使用Promise封装在defineStore外,通过async……await方法等待Promise响应数据返回

import { defineStore } from 'pinia'
import { Names } from './store-name'

type User = {
  name: string
  message: string
}

const login = (): Promise<string> => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('模拟异步I/O请求,等待两秒钟执行')
    }, 2000)
  })
}

export const useTestStore = defineStore(Names.TEST, {
  state: () => {
    return {
      user: <User>{
        name: '飞机',
        message: '666',
      },
      name: '开枪',
    }
  },
  // computed一些值
  getters: {},
  // 相当于methods,可以做同步、异步操作、提交state等
  actions: {
    async setCurrent() {
      let result = await login()
      this.user.message = result
    },
  },
})
<template>
    <div>user:{{ Test.user }}</div>
    <hr />
    <div>name:{{ Test.name }}</div>
    <button @click="change">change</button>
</template>

<script setup lang="ts">
import { useTestStore } from './Store'
import { storeToRefs } from 'pinia'

const Test = useTestStore()
const change = () => {
    Test.setCurrent()
}
</script>

<style scoped></style>

除此之外,Action中的方法也可以通过this互相调用,以下给出一个示例

import { defineStore } from 'pinia'
import { Names } from './store-name'

type User = {
    name: string
    message: string
}

const login = (): Promise<string> => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('模拟异步I/O请求,等待两秒钟执行')
        }, 2000)
    })
}

export const useTestStore = defineStore(Names.TEST, {
    state: () => {
        return {
            user: <User>{
                name: '飞机',
                message: '666',
            },
            name: '开枪',
        }
    },
    // computed一些值
    getters: {},
    // 相当于methods,可以做同步、异步操作、提交state等
    actions: {
        setMessage() {
            this.name = '挡枪'
        },
        async setCurrent() {
            this.setMessage()
            let result = await login()
            this.user.message = result
        },
    },
})

getters:
getters相当于计算属性,可以将state中的值做一些“加工”后返回,需要注意的是getters和computed一样都是直接访问,不能调用的(get访问器?)

import { defineStore } from 'pinia'
import { Names } from './store-name'

type User = {
    name: string
    message: string
}

const login = (): Promise<string> => {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('模拟异步I/O请求,等待两秒钟执行')
        }, 2000)
    })
}

export const useTestStore = defineStore(Names.TEST, {
    state: () => {
        return {
            user: <User>{
                name: '飞机',
                message: '666',
            },
            name: '开枪',
        }
    },
    // computed一些值
    getters: {
        newName(): string {
            return `${this.name}通过计算属性获得`
        },
        // 箭头函数没有this,需要额外传入一个参数state来获取或修改值
        getUserName: (state): string => {
            return `${state.user.name}通过计算属性获得`
        },
    },
    // 相当于methods,可以做同步、异步操作、提交state等
    actions: {
    // setMessage中有getters里的属性
        setMessage() {
            this.name = this.newName
            this.user.name = this.getUserName
        },
        async setCurrent() {
            let result = await login()
            this.user.message = result
            this.setMessage()
        },
    },
})

请注意,getters实际上有两种写法(如上图所示),一种是普通函数的写法,还有一种是箭头函数。普通函数中如果要访问state可以直接来一个this.state中的属性名,缺点是必须标明函数的返回类型。而箭头函数由于没有this(this为undefined),需要在参数中额外传入一个state,通过state.属性名的方式进行修改。这里我们更推荐箭头函数的写法

<template>
  <div>user:{{ Test.user }}</div>
  <hr />
  <div>name:{{ Test.name }}</div>
  <hr>
    <div>UserName:{{ Test.user.name }}</div>
    <button @click="change">change</button>
  </template>

<script setup lang="ts">
  import { useTestStore } from './Store'
  import { storeToRefs } from 'pinia'

  const Test = useTestStore()
  const change = () => {
    Test.setCurrent()
  }
</script>

<style scoped></style>
相关文章
|
6月前
|
JavaScript
vue.router和vue.route
vue.router和vue.route
|
3月前
|
前端开发 JavaScript UED
什么是 React Router?
【8月更文挑战第31天】
28 0
|
6月前
|
JavaScript
|
缓存 JavaScript
Vue Router 学习 new Router
Vue Router 学习 new Router
143 0
|
6月前
|
缓存 移动开发 JavaScript
【学习笔记】Vue Router
【学习笔记】Vue Router
58 0
|
6月前
|
存储 资源调度 前端开发
React Router v6 完全指南(上)
React Router v6 完全指南(上)
342 0
|
移动开发 JavaScript 前端开发
React-Router
React-Router
67 0
|
JavaScript
Pinia+Router学习笔记(二)
本节记录修改State中值的五种方式
93 0
Pinia+Router学习笔记(三)
本节记录解构Store过程中的相关操作及注意事项
92 0
|
存储
Pinia+Router学习笔记(六)
从本节开始进入Router学习,先介绍下Vue-Router的基本配置
82 0