Vue3.3新特新和Vue3-Pinia

news2024/11/20 7:20:57

文章目录

    • 1.Vue3.3新特性 - defineOptions
    • Vue3.3新特性 - defineModel
    • 3.Pinia快速入门
    • 4.手动添加Pinia到Vue项目
    • 5.Vue3 - Pinia的基本语法
    • 6.action的异步实现
    • 7.Vue3-Pinia-storeToRefs方法
    • 8.Pinia持久化插件
      • 安装
      • 用法

1.Vue3.3新特性 - defineOptions

背景说明
<script setup>之前,如果要定义 props, emits 可以轻而易举地添加一个与setup平级的属性,但是用了script setup后,就没法这么干了,setup属性已经没有了,自然无法添加与其平级的属性

为了解决这一问题,引入了defineProps 与 defineEmits这两个宏。但这只解决了props与emits这两个属性。如果我们要定义组件的name或其他自定义的属性,还是得回到最原始的用法 – 再添加一个普通的<script>标签。这样就会存在两个<script>标签。让人无法接受。

在这里插入图片描述

一定要另建一个script给组件起一个名字

所以在Vue3.3中新引入了defineOptions宏.顾名思义,主要是用来定义 Option API 的选项. 可以用defineOptions 定义任意的选项, props,emits,expose,slots除外(应为这些可以使用defineXXX来做到)

<script setup>
defineOptions({
	name: 'Foo',
	inheritAttrs: false,
	// ...更多自定义属性
})
<script>

Vue3.3新特性 - defineModel

Vue3中的V-model 和 defineModel

在Vue3中,自定义组件上使用v-model,相当于传递一个modelValue属性, 同时触发 updata:modelValue 事件

<Child v-model="isVisible">
// 相当于
<Child :modelValue="isVisible" @updata:modelValue="isVisible=$event">

我们需要先定义 props, 再定义 emits. 其中有许多重复的代码. 如果需要修改此值, 还需要手动调用 emit 函数

ps:页面中有一个小的输入框,想要实现的效果是:封装一个输入框组件,并且v-model跟现在的数据做一个绑定

App.vue

<script setup>
import MyInput from '@/components/my-input.vue'
import { ref } from 'vue'
const txt = ref('123456')
</script>

<template>
<div>
	<MyInput v- model="txt"></MyInput>
	{{ txt }}
</div>
</template>

my-input.vue

<script setup>
defineProps({
	modelValue: String
})
const emit = defineEmits(['updata:modelValue'])
</script>

<template>
<div>
	<input	
		type="text"
		:value="modelValue"
		@input="e => emit('updata:modelValue', e.target.value)"
	>
</div>
</template>

新写法

<script setup>
const modelValue = defineModel()
modelValue.value++
</script>
<script setup>
import { defineModel } from 'vue'
const modelValue = defineModel()
</script>

<template>
<div>
	<input	
		type="text"
		:value="modelValue"
		@input="e => modelValue = e.target.value
	>
</div>
</template>

然后往vite.config.js中加配置
在这里插入图片描述

3.Pinia快速入门

什么是Pinia

Pinia 是 Vue 的最新状态管理工具, 是Vuex的 替代品

在这里插入图片描述

  1. 提供了更加简单的API(去掉了mutation)
  2. 提供符合组合式风格的API(和Vue3新语法统一)
  3. 弃掉了modules的概念, 每一个store都是一个独立的模块
  4. 配合 TypeScript 更加友好,提供可靠的类型推断

在这里插入图片描述

4.手动添加Pinia到Vue项目

在实际开发项目的时候,关于Pinia的配置,可以在创建项目时自动添加

  1. 使用Vite创建一个空的项目Vue3项目:npm create vue@latest
  2. 按照官方文档 安装 pinia 到项目中(官网:cn.vuejs.org)
  3. vue3官网中有个生态系统,其中有pinia
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
main.js

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia() // 创建Pinia实例
const app = createApp(App) // 创建根实例
app.use(pinia).mount('#app') //这个可以拆分成下面的这两个
app.use(pinia)// pinia插件的安装配置
app.mount('#app')// 视图的挂载

5.Vue3 - Pinia的基本语法

定义Store

在深入研究核心概念之前,我们得知道 Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字:

import { defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {
  // 其他配置...
})

这个名字 ,也被用作 id ,是必须传入的, Pinia 将用它来连接 store 和 devtools。为了养成习惯性的用法,将返回的函数命名为 use… 是一个符合组合式函数风格的约定。

defineStore() 的第二个参数可接受两类值:Setup 函数或 Option 对象。

Option Store
与 Vue 的选项式 API 类似,我们也可以传入一个带有 state、actions 与 getters 属性的 Option 对象

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

你可以认为 state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods)。
为方便上手使用,Option Store 应尽可能直观简单。

Setup Store

也存在另一种定义 store 的可用语法。与 Vue 组合式 API 的 setup 函数 相似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。

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

  return { count, doubleCount, increment }
})

在 Setup Store 中:

  • ref() 就是 state 属性
  • computed() 就是 getters
  • function() 就是 actions

Setup store 比 Option Store 带来了更多的灵活性,因为你可以在一个 store 内创建侦听器,并自由地使用任何组合式函数。不过,请记住,使用组合式函数会让 SSR 变得更加复杂。

新建store/counter.js

import { defineStore } from 'pinia'
import { ref } from 'vue'

// 定义store
// defineStore(仓库唯一的标识, () => { ... })
export const useCounterStore = defineStore('counter', () => {
    // 声明数据 state - count
    const count = ref(0)
    // 声明操作数据的方法 action
	const addCount = () => count.value++
	const subCount = () => count.value--

    // 声明基于数据派生的计算属性 getters
	const double = computed(() => count.value * 2)    

    // 声明数据 state - msg
    const msg = ref('hello pinia')

    return {
        count,
		addCount,
		subCount,

        msg
    }
})

Son1Count.vue

<script setup>
import { useCounterStore } from '@/store/counte
const counterStore = useCounterStore()
</script>

<template>
	<div>
		我是Son1.vue - {{ counterStore.count }} - {{ counterStore.double }}
		<button @click="counterStore.addCount">+</button>
	</div>
</template>

<style scoped>

</style>

Son2Count.vue

<script setup>
import { useCounterStore } from '@/store/counte
const counterStore = useCounterStore()
</script>

<template>
	<div>
		我是Son1.vue - {{ counterStore.count }}
		<button @click="counterStore.subCount">-</button>
	</div>
</template>

<style scoped>

</style>

在这里插入图片描述

6.action的异步实现

在action里面不需要考虑同步还是异步,它都可以写,函数里面既可以直接修改数据,也可以先发个请求,拿到数据回来之后再去修改上面的数据

编写方式: 异步action函数的写法和组件中获取异步数据的写法完全一致
接口地址: http://geek.itheima.net/v1_0/channels
需求: 在Pinia中获取频道列表数据并把数据渲染App组件的模板中

在这里插入图片描述
channel.js

import { defineStore } from 'pinia'
import { ref } from 'vue'
import axios from 'axios'

export const useChannelStore = defineStore('channel', () => {
    // 声明数据
    const channelList = ref([])
    //声明操作数据的方法
    const getList = async () => {
    //支持异步
    const { data: { data }} = await axios.get('http://geek.itheima.net/v1_0/channels')
    channelList.value = data.channels
    console.log(data.channels)

    }

    // 声明getters相关
    return {
    channelList,
    getList
    }
})
<script setup>
import Son1Com from '@/components/Son1Com.vue'
import Son2Com from '@/components/Son2Com.vue'
import { useCounterStore } from '@/store/counter'
import { useChannelStore } from './store/channel'👈
const counterStore = useCounterStore ()
const channelStore = useChannelStore ()👈
console.log(counterStore)
</script>

<template>
    <div>
      <h3>
        App.vue根组件
        - {{ counterStore.count }}
        - {{ counterStore.msg }}
      </h3>
      <Son1Com></Son1Com>
      <Son2Com></Son2Com>
      <hr>
      <button @click="channelStore.getList">获取频道数据</button>👈
      <ul>
        <li v-for="item in channelStore.channelList" :key="item.id">{{ item.name }}</li>👈
      </ul>
    </div>
</template>

<style scoped>

</style>

7.Vue3-Pinia-storeToRefs方法

第六点中,如果直接进行解构,不进行处理,数据会丢失响应式,所以可以用到storeToRefs
在这里插入图片描述
在这里插入图片描述

8.Pinia持久化插件

官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

1.安装插件 pinia-plugin-persistedstate

npm i pinia-plugin-persistedstate

2.main.js 使用

import persist from 'pinia-plugin-persistedstate'

app.use(createPinia().use(persist))

3.store仓库中,persist:true开启

安装

npm

npm i pinia-plugin-persistedstate

将插件添加到 pinia 实例上

import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

用法

创建 Store 时,将 persist 选项设置为 true。

  • 选项式语法
import { defineStore } from 'pinia'

export const useStore = defineStore('main', {
  state: () => {
    return {
      someState: '你好 pinia',
    }
  },
  persist: true,
})               
  • 组合式语法
import { defineStore } from 'pinia'

export const useStore = defineStore(
  'main',
  () => {
    const someState = ref('你好 pinia')
    return { someState }
  },
  {
    persist: true,
  },
)

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1442571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目02《游戏-11-开发》Unity3D

基于 项目02《游戏-10-开发》Unity3D &#xff0c; 任务&#xff1a;飞行坐骑 首先创建脚本&#xff0c; 绑定脚本&#xff0c; using UnityEngine; public class Dragon : MonoBehaviour{ [SerializeField] private float speed 10f; public Transfo…

redis-sentinel(哨兵模式)

目录 1、哨兵简介:Redis Sentinel 2、作用 3、工作模式 4、主观下线和客观下线 5、配置哨兵模式 希望能够帮助到大家&#xff01;&#xff01;&#xff01; 1、哨兵简介:Redis Sentinel Sentinel(哨兵)是用于监控redis集群中Master状态的工具&#xff0c;其已经被集成在re…

【Makefile语法 01】程序编译与执行

目录 一、编译原理概述 二、编译过程分析 三、编译动静态库 四、执行过程分析 一、编译原理概述 make&#xff1a; 一个GCC工具程序&#xff0c;它会读 makefile 脚本来确定程序中的哪个部分需要编译和连接&#xff0c;然后发布必要的命令。它读出的脚本&#xff08;叫做 …

blender几何节点中样条线参数中的系数(factor)是个什么概念?

一根样条线&#xff0c;通常由两个及以上的控制点构成。 每个控制点的系数&#xff0c;其实相当于该点处位于整个样条线的比值。 如图&#xff0c;一根样条线有十一个控制点。相当于把它分成了十段&#xff0c;那每一段可以看到x、y都是0&#xff0c;唯独z每次增加0.1&#xff…

单片机项目调试中的技巧和常见问题解决

单片机是嵌入式系统中的重要组成部分&#xff0c;在各种电子设备中发挥着重要的作用。在单片机项目开发过程中&#xff0c;调试是至关重要的一环&#xff0c;同时也会遇到一些常见问题。本文将介绍一些单片机项目调试的技巧以及常见问题的解决方法&#xff0c;希望能够对单片机…

跟着cherno手搓游戏引擎【22】CameraController、Resize

前置&#xff1a; YOTO.h: #pragma once//用于YOTO APP#include "YOTO/Application.h" #include"YOTO/Layer.h" #include "YOTO/Log.h"#include"YOTO/Core/Timestep.h"#include"YOTO/Input.h" #include"YOTO/KeyCod…

【开源】JAVA+Vue+SpringBoot实现班级考勤管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统基础支持模块2.2 班级学生教师支持模块2.3 考勤签到管理2.4 学生请假管理 三、系统设计3.1 功能设计3.1.1 系统基础支持模块3.1.2 班级学生教师档案模块3.1.3 考勤签到管理模块3.1.4 学生请假管理模块 3.2 数据库设…

深入理解java之多线程(一)

前言&#xff1a; 本章节我们将开始学习多线程&#xff0c;多线程是一个很重要的知识点&#xff0c;他在我们实际开发中应用广泛并且基础&#xff0c;可以说掌握多线程编写程序是每一个程序员都应当必备的技能&#xff0c;很多小伙伴也会吐槽多线程比较难&#xff0c;但因为其实…

春晚刘谦第二个魔术原理讲解

目录 1. 先说一下步骤&#xff1a;2. 原理讲解&#xff1a;2.1 第一步分析2.1 第二步分析2.1 第三步分析2.1 第四步分析2.1 第五步分析2.1 第六步分析2.1 第七步分析2.1 第八步分析2.1 第七步重新分析 小结&#xff1a; 首先&#xff0c;先叠个甲。我本人很喜欢刘谦老师&#x…

H12-821_23

23.网络管理员在某台路由器上查看BGP部居信息,邻居信息如图所示,关于该信息下列说法中正确的是? A.该路由器未从对等体接收到BGP路由前缀 B.本地路由器的Router ID为1.1.1.1 C.与对等体3.3.3 3接收、发送的报文数量分别为10、20个 D.与对等体3.3.3.3之间的邻居关系为IBGP对等体…

使用Arcgis裁剪

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、掩膜提取二、随意裁剪三、裁剪 前言 因为从网站下载的是全球气候数据&#xff0c;而我们需要截取成中国部分&#xff0c;需要用到Arcgis的裁剪工具 一、掩…

批归一化(Batch Normalization,简称BN)层的作用!!

批归一化&#xff08;Batch Normalization&#xff0c;简称BN&#xff09;层在卷积神经网络中的作用主要有以下几点&#xff1a; 规范化数据&#xff1a;批归一化可以对每一批数据进行归一化处理&#xff0c;使其均值接近0&#xff0c;方差接近1。这有助于解决内部协变量偏移&…

龙年定制红包封面赠送第三波

你好啊&#xff0c;今天是大年三十&#xff0c;外面已是爆竹声声&#xff0c;年味十足。祝你&#xff0c;我亲爱的读者&#xff0c;甲辰龙年新春快乐&#xff0c;万事如意&#xff01; 最近一直有读者提出&#xff0c;希望我能再发一波红包封面。 尤其是「经典」版本的&#xf…

刚买就下跌,如何快速回本?试试补仓回本计算器,股票量化分析工具QTYX-V2.7.7...

前言 祝大家除夕夜快乐&#xff0c;阖家欢乐&#xff0c;万事如意&#xff01;本周大A连续三个大阳线&#xff0c;终于在节前企稳了一把&#xff01; 虽然前两周市场哀鸿遍野地下跌&#xff0c;但是星球群不少大佬在这三天的反弹中账户不但回本而且盈利不少&#xff01;一番交流…

【2023年终总结】感恩南洋经历,2024收拾再启程

新年祝福 值此2024农历新年到来之际&#xff0c;祝一直支持“IT进阶之旅”的各位小伙伴们新的一年伴随着新的开始&#xff0c;新的旅程&#xff0c;新的突破&#xff0c;新的收获&#xff0c;新的期待..... 写在前面 2023&#xff0c;“IT进阶之旅”一直处于“停更”状态&#…

问题:3【单选题】实现职业理想的一般步骤是()。 #媒体#媒体

问题&#xff1a;3【单选题】实现职业理想的一般步骤是()。 A、创业-立业-择业 B、择业-创业-立业 C、择业-立业-创业 D、立业-择业-创业 参考答案如图所示

Android SystemConfig相关

SystemConfig在哪里初始化 它声明在PackageManagerService类的静态方法main()中。在该方法中间定义Injector类对象时&#xff0c;作为它的构造参数。它是调用的SystemConfig.getInstance()实现初始化&#xff0c;之后能通过Injector类对象的getSystemConfig()得到SystemConfig类…

【动态规划】【C++算法】LeetCoce996正方形数组的数目

作者推荐 【动态规划】【前缀和】【C算法】LCP 57. 打地鼠 本文涉及知识点 动态规划汇总 LeetCoce996正方形数组的数目 给定一个非负整数数组 A&#xff0c;如果该数组每对相邻元素之和是一个完全平方数&#xff0c;则称这一数组为正方形数组。 返回 A 的正方形排列的数目…

从Socket中解析Http协议实现通信

在网络协议中&#xff0c;Socket是连接应用层和运输层的中间层&#xff0c;主要作用为了通信。Http协议是应用层上的封装协议。我们可以通过Http协议的规范解析Socket中数据&#xff0c;完成Http通信。 首先&#xff0c;我们先回顾一下Http协议的规范。主要复习一下&#xff0c…

电脑数据误删如何恢复?9 个Windows 数据恢复方案

无论您是由于软件或硬件故障、网络犯罪还是意外删除而丢失数据&#xff0c;数据丢失都会带来压力和令人不快。 如今的企业通常将其重要数据存储在云或硬盘上。但在执行其中任何一项操作之前&#xff0c;您很有可能会丢失数据。 数据丢失的主要原因是意外删除&#xff0c;任何…