当前位置: 首页 > news >正文

Pinia的安装,使用,与情景教学

#本文基于Vue3和ts去实现Pinia的使用与安装,Pinia用法为组合式API,情景教学为一个基于全局的举报框的pinia逻辑#

1,下载pinia

这里推荐pnpm下载

pnpm add pinia

2,在main.ts中注册并挂载pinia

// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 导入 Pinia
import App from './App.vue'

const app = createApp(App)

// 创建 Pinia 实例
const pinia = createPinia()

// 挂载 Pinia
app.use(pinia)

app.mount('#app')

 3,创造一个Store

  1. 引入defineStore方法
  2. 使用 defineStore 定义 store,推荐store的命名方式为use+模块+Store
  3. 其他语法与vue3一致
  4. 最后别忘了return导出
export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  
  const doubleCount = computed(() => count.value * 2)
  
  const increment = () => {
    count.value++
  }

  return { count, doubleCount, increment }
})

4, 在组件中使用store

  1. 引入对应单例
  2. 引入storeToRefs保持响应式解构
  3. 剩下的像ref变量一样直接使用即可
<!-- Component.vue -->
<script setup lang="ts">
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia' // 保持响应式解构

const counterStore = useCounterStore()

// 直接解构会失去响应式,需要用 storeToRefs
const { count, doubleCount } = storeToRefs(counterStore)
const { increment } = counterStore
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ doubleCount }}</p>
    <button @click="increment">+1</button>
    <button @click="counterStore.reset()">Reset</button>
  </div>
</template>

5,项目的目录结构建议

  1.  可以在src下单独开一个stores用来存放所有的仓库
  2.  可以创造index.ts来统一导出所有的store
// stores/index.ts示例
export * from './counter'
export * from './user'

情景教学 

        #你需要实现一个举报框,能在不同页面弹出,如评论区的举报,视频页的举报,帖子的举报。如果在每个帖子中引用,会导致剧烈的堆积。如果在大页面引用,被举报者的id等数据的传递又即为麻烦。是时候用pinia了#

1,创建reportStore.ts

// 举报框所用数据
import {defineStore} from 'pinia'
import {ref} from 'vue'

export const useReportStore = defineStore('report', () => {

})

2, 创建举报所需的所有状态

  1. 举报框的显示的bool变量
  2. 举报方相关信息
  3. 举报的描述文本
  4. 举报原因(源自多选框)
    // 控制举报对话框的显示状态
    const isReportDialogVisible = ref<boolean>(false)

    // 存储被举报被人的相关信息
    const reportTarget = ref<{
        id: string | number,
        type: 'post' | 'commment' | 'user' | string;
        title?: string;
    } | null>(null)

    // 举报描述文本
    const reportDescription = ref<string>('')
    // 举报原因
    const reportReasons = ref<string[]>([])

3,封装打开对话函数

  1. 这一步成功实现跨组件传递数据
  2. 携带举报ID等所有信息
     // 打开举报对话框
    const openReportDialog = (target:{
        id: string | number;
        type: 'post' | 'comment' | 'user' | string;
        title?: string
    }) => {
        reportTarget.value = target
        isReportDialogVisible.value = true
        reportDescription.value = '' // 清空之前的举报描述
        reportReasons.value = []  // 清空举报原因
    }

4,封装关闭函数与提交举报函数

需注意:提交函数返回一个数组对象,提供给父组件组做消息提醒,让父组件做最后的结果逻辑处理

    // 关闭举报对话框
    const closeReportDialog = () => {
        isReportDialogVisible.value = false
    }

       // 提交举报
    const submitReport = async (): Promise<{ success: boolean; message: string }> => {
        if (!reportReasons.value.length) {
            return {
                success: false,
                message: '请至少选择一个举报原因'
            }
        }
        if (!reportDescription.value.trim()) {
            return {
                success: false,
                message: '请填写举报描述'
            }
        }
        try {
            // 调用实际的API
            console.log('举报信息:', {
                targetId: reportTarget.value?.id,
                targetType: reportTarget.value?.type,
                description: reportDescription.value,
                type: reportReasons.value
            })

            // 举报成功后关闭对话框并清除信息
            closeReportDialog()
            return {
                success: true,
                message: '举报已提交'
            }
        } catch(error) {
            return {
                success: false,
                message: '举报提交失败,请稍后再试'
            }
        }
    }

5,全部返回

    return {
        submitReport,
        closeReportDialog,
        openReportDialog,
        reportDescription,
        reportTarget,
        isReportDialogVisible,
        reportReasons
    }

 父组件中

1,引入reportStore,创造调用并解构

  • 引入storeToRefs
  • 解构得到举报物名字,类型,举报原因,显示控制,彻底实现数据传递
  • 推荐把方法也解构出来,我这里没实现
  • 解构后按照正常变量使用就行(记得script中还是要用.value)
import { useReportStore } from '@/stores/reportStore'
import { storeToRefs } from 'pinia'
const reportStore = useReportStore()
const { isReportDialogVisible, reportDescription, reportTarget, reportReasons } = storeToRefs(reportStore)
const getTargetName = computed(() => reportTarget.value.title || `ID ${reportTarget.value.id}` || '未知内容' )

2,提交函数的实现

  • 因为store中已实现了提交函数,关闭函数的逻辑,父组件的提交函数仅需实现善后工作,对用户的操作进行反馈
  • 拿取store中提交函数返回的消息进行反馈 
  • 作者这里使用ElMessage和ElLoading实现用户反馈,需要提前引入ElementUI组件库
const onSubmit = async () => {
    const { success, message } =  await reportStore.submitReport()
    
    if (success){
        const loading = ElLoading.service({
            lock: true,
            text: '正在提交举报中...',
            background: 'rgba(0,0,0,0.7)',
        })
        setTimeout(() => {
            loading.close()
            ElMessage({
                message: `收藏成功`,
                type: 'success',
                plain: true,
                showClose: true
            })
            ElMessage.success(message)
        }, 500)
    }else{
        ElMessage.warning(`${message}`)
    }
}

相关文章:

  • Excel 使用技巧:excel 合并不同列内容; excel 将公式转化为文本
  • 《嫦娥的月球物联网》
  • Day 4 系统总线(2)
  • ubuntu开发mcu环境
  • 基于kubernetes技术实现蓝绿部署(企业实战)
  • Java音频和录音合成 实战demo
  • Linux 部署 rocketmq centos7
  • 读一本书,骑行万里路:与维乐 Angel Rise+骑行看世界
  • ai画图flux depth景深控制空间位置生图
  • 软件工程之软件测试(单元测试、集成测试、系统测试)
  • 06.AI搭建preparationの(transformers02)bertmodel实现bert-base-chinese的编码
  • 论文阅读笔记——PointVLA: Injecting the 3D World into Vision-Language-Action Models
  • DevEco Studio编辑器的使用-代码code Linter检查
  • 【博客】使用GithubAction自动同步obisidian和hexo仓库
  • QTableView开发入门
  • @DeclareParents 注解实现接口功能增强:Spring中通过接口引入实现功能增强的完整示例
  • 保存预测图像时出现的文件名错误
  • Python----机器学习(KNN:决策边界,决策边界计算,交叉验证步骤)
  • ansible介绍以及安装
  • C++练习
  • 做网站的属于什么行业/搜索引擎优化排名关键字广告
  • 云服务器做网站难吗/软件培训机构有哪些?哪个比较好
  • 想做个网站报价蔬菜价格怎么做/重庆网站关键词排名
  • 可信网站认证/百度手机助手下载2021新版
  • 网络舆情监测员/重庆搜索引擎seo
  • 做网站建设哪家效益快/网址导航该如何推广