【Vue】3-3、Vue 3.3 新特性 Pinia

news2024/11/20 7:06:27

一、Vue 3.3 新特性

1、defineOptions

<script setup> 之前,如果要定义 propsemits 可以轻而易举地添加一个与 setup 平级的属性

但是用了 <script setup> 后,就没法这么干了,setup 属性已经没有了,自然没法添加与其平级的属性

为了解决这一问题,引入 definePropsdefineEmits 这两个宏。但这只解决了 propsemits 两个属性

若要定义组件的 name 或其他自定义的属性,还是得回到最原始的用法 —— 再添加一个普通的 <script> 标签

这样就会存在两个<script> 标签,让人无法接受

所以在 Vue3.3 中新引入了 defineOptions 宏。顾名思义,主要用来定义 Options API 的选项。

可以用 defineOptions 定义任意的选项,propsemitsexposeslots 除外(因为这些可以使用 defineXXX 实现)

<script setup>
defineOptions({
      name: 'LoginIndex'
})
</script>

2、defineModel

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

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

需要先定义 props,再定义 emits,有许多重复的代码。若需要修改此值,还需要手动调用 emit 函数

从 Vue 3.4 开始,推荐的实现方式是使用 defineModel() 宏:

<!-- Child.vue -->
<script setup>
const model = defineModel()

function update() {
  model.value++
}
</script>

<template>
  <div>parent bound v-model is: {{ model }}</div>
</template>
<!-- Parent.vue -->
<Child v-model="count" />

defineModel() 返回的值是一个 ref。它可以像其他 ref 一样被访问以及修改,不过它能起到在父组件和当前变量之间的双向绑定的作用:

  • 它的 .value 和父组件的 v-model 的值同步;

  • 当它被子组件变更了,会触发父组件绑定的值一起更新。

这意味着你也可以用 v-model 把这个 ref 绑定到一个原生 input 元素上,在提供相同的 v-model 用法的同时轻松包装原生 input 元素:

<script setup>
const model = defineModel()
</script>

<template>
  <input v-model="model" />
</template>

二、Pinia 

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

  • 提供更加简单的 API(去掉了 mutation)

  • 提供符合组合式风格的 API(和 Vue3 新语法统一)

  • 去掉了 modules 的概念,每一个 store 都是一个独立地模块

  • 配置 TypeScript 更加友好,提供可靠的类型推断

1、手动添加 Pinia 到 Vue 项目

在实际开发项目的时候,关于 Pinia 的配置,可以在项目创建时自动添加(以下方式为手动添加)

  • 使用 Vite 创建一个空的 Vue3 项目

npm create vue@latest
  • 按照官方文档安装 Pinia 到项目中

Pinia | The intuitive store for Vue.js

npm install pinia

Tip:

如果你的应用使用的 Vue 版本低于 2.7,你还需要安装组合式 API 包:@vue/composition-api

如果你使用的是 Nuxt,你应该参考这篇指南。

如果你正在使用 Vue CLI,你可以试试这个非官方插件。  

创建一个 pinia 实例 (根 store) 并将其传递给应用:  

// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

2、Pinia 基本语法

  • 准备一个 store(单独一个 js 文件)

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

export const useCounterStore = defineStore('counter', ()=>{
    // 声明数据 state - count
    const count = ref(100)
    // 声明操作数据的方法 action (普通函数)
    const addCount = () => count.value++
    const subCount = () => count.value--

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

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

    return{
        count,
        double,
        msg,
        addCount,
        subCount
    }
})
  • 在需要 store 中数据的组件中导入并使用

// App.vue
<script setup>
import Son1 from '@/components/Son1_Com.vue'
import Son2 from '@/components/Son2_Com.vue'
import { useCounterStore } from '@/store/counter.js'

const counterStore = useCounterStore()
console.log(counterStore)
</script>

<template>
  <div>
    <h1>我是根组件
      - {{ counterStore.count }}
      - {{ counterStore.msg }}
    </h1>
    <Son1></Son1>
    <Son2></Son2>
  </div>
</template>
// Son1_Com.vue
<script setup>
import { useCounterStore } from '@/store/counter.js'

const counterStore = useCounterStore()
</script>

<template>
      <div>
            我是Son1.vue - {{ counterStore.count }} - {{ counterStore.double }}
            <button @click="counterStore.addCount">+</button><br>
            - {{ counterStore.msg }}
      </div>
</template>
// Son2_Com.vue
<script setup>
import { useCounterStore } from '@/store/counter.js'

const counterStore = useCounterStore()
</script>

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

3、action 异步写法

编写方式:异步 action 函数的写法和组件中获取异步数据的写法完全一致

接口地址:http://geek.itheima.net/v1_0/channels

需求:在 Pinia 中获取频道列表数据并把数据渲染 APP 组件的模板中

import { ref } from 'vue'
import { defineStore } from 'pinia'
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)
    }

    return{
        channelList,
        getList
    }
})
<script setup>
import { useChannelStore } from '@/store/channel.js'
const channelStore = useChannelStore()
</script>

<template>
    <button @click="channelStore.getList">获取频道</button>
    <ul>
      <li v-for="item in channelStore.channelList" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

4、storeToRefs 方法

store 是一个用 reactive 包装的对象,这意味着不需要在 getters 后面写 .value,就像 setup 中的 props 一样,如果你写了,我们也不能解构它

<script setup>
const store = useCounterStore()
// ❌ 这将不起作用,因为它破坏了响应性
// 这就和直接解构 `props` 一样
const { name, doubleCount } = store
name // 将始终是 "Eduardo"
doubleCount // 将始终是 0
setTimeout(() => {
  store.increment()
}, 1000)
// ✅ 这样写是响应式的
// 💡 当然你也可以直接使用 `store.doubleCount`
const doubleValue = computed(() => store.doubleCount)
</script>

为了从 store 中提取属性时保持其响应性,你需要使用 storeToRefs()。它将为每一个响应式属性创建引用。当你只使用 store 的状态而不调用任何 action 时,它会非常有用。请注意,你可以直接从 store 中解构 action,因为它们也被绑定到 store 上:  

<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` 和 `doubleCount` 是响应式的 ref
// 同时通过插件添加的属性也会被提取为 ref
// 并且会跳过所有的 action 或非响应式 (不是 ref 或 reactive) 的属性
const { name, doubleCount } = storeToRefs(store)
// 作为 action 的 increment 可以直接解构
const { increment } = store
</script>

5、Pinia 持久化

官网文档:Home | pinia-plugin-persistedstate

  • 安装插件

npm i pinia-plugin-persistedstate
  • main.js 使用

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',
  () => {
    const someState = ref('你好 pinia')
    return { someState }
  },
  {
    persist: true,
  },
)

三、趣味小知识​

为什么取名 Pinia?【官方解释】 

Pinia (发音为 /piːnjʌ/,类似英文中的 “peenya”) 是最接近有效包名 piña (西班牙语中的 pineapple,即“菠萝”) 的词。 菠萝花实际上是一组各自独立的花朵,它们结合在一起,由此形成一个多重的水果。 与 Store 类似,每一个都是独立诞生的,但最终它们都是相互联系的。 它(菠萝)也是一种原产于南美洲的美味热带水果。

一  叶  知  秋,奥  妙  玄  心

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

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

相关文章

Pyth 预言机: 它们如何影响Hover?

所有链上借贷市场都使用一种称为“oracle&#xff08;预言机&#xff09;”的服务&#xff0c;为dApp提供代币定价。Oracle是一个数据系统&#xff0c;将链下信息&#xff08;例如KuCoin上的BTC/USDT价格&#xff09;传递到链上合约。从那里&#xff0c;应用程序可以支付一小笔…

Matplotlib 绘图实践:从基础到高级技巧【第62篇—python:Matplotlib绘图】

文章目录 Matplotlib绘图模块基础入门大全1. 安装Matplotlib2. 绘制基本图形3. 自定义图形样式4. 多子图布局5. 高级绘图技巧6. 绘制实时动态图7. 图形注释与标记8. 颜色映射与散点图9. 绘制直方图10. 绘制饼图11. 绘制热力图 总结 Matplotlib绘图模块基础入门大全 Matplotlib…

RabbitMQ-1.介绍与安装

介绍与安装 1.RabbitMQ1.0.技术选型1.1.安装1.2.收发消息1.2.1.交换机1.2.2.队列1.2.3.绑定关系1.2.4.发送消息 1.2.数据隔离1.2.1.用户管理1.2.3.virtual host 1.RabbitMQ 1.0.技术选型 消息Broker&#xff0c;目前常见的实现方案就是消息队列&#xff08;MessageQueue&…

深度神经网络中的BNN和DNN:基于存内计算的原理、实现与能量效率

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言引言内存计算体系结构深度神经网络&#xff08;DNN&#xff09;随机梯度的优…

搭建自己的私服 maven 仓库

申明&#xff1a;本文章所使用docker-compose配置文件纯属学习运用&#xff0c;非商用如有雷同请联系本人协调处理。 一、配置docker-compose.yml文件 # 指定docker-compose的版本 version: 3 services: nexus: container_name: nexus_container image: sonatype/nex…

扩展鸿蒙ArkUI日期组件

鸿蒙ArkUI日期组件使用的是DatePickerDialog.show基础上扩展的表单式输入组件&#xff0c;方便在输入日期方式快速使用及复用。 /*** 日期*/ Component export default struct DiygwDate{//绑定的值Link Watch(onValue) value:string;// 隐藏值State valueField: string valu…

【机器学习】某闯关类手游用户流失预测

Final Project: 某闯关类手游用户流失预测 1 案例简介 手游在当下的日常娱乐中占据着主导性地位&#xff0c;成为人们生活中放松身心的一种有效途径。近年来&#xff0c;各种类型的手游&#xff0c;尤其是闯关类的休闲手游&#xff0c;由于其对碎片化时间的利用取得了非常广泛…

Sui上TVL突破5亿美元,位列DeFi榜单前十名和最活跃链前五名

2023年Sui上DeFi协议迅速增长&#xff0c;2024年这一势头仍在继续&#xff0c;根据DeFiLlama报告Sui上TVL近期超过5亿美元。在不到一年的时间里就达到这个金额&#xff0c;得益于Sui的突破性指标&#xff0c;比如其峰值TPS接近6,000。 Sui TVL突破5亿美元&#xff0c;登上DeFi…

使用VASPKIT生成非整数倍扩胞结构

在计算某些任务时需要根据原胞进行非对称或者根号倍扩胞&#xff0c;使用vaspkit可以构建一个扩胞倍数矩阵&#xff0c;这样可以获得特定方向非整数倍的扩胞结构。 这里使用的命令为vaspkit的400模块 注意400的命令会让你连续输入三行&#xff0c;每行都需要三个数值&#xff0…

Android 数据恢复电脑版免费下载使用方法 [2024 更新]

“我一直在寻找一款可以下载的适用于 PC 的优秀 Android 数据恢复软件。有很多&#xff0c;但大部分都需要我付费。你能推荐一个好的让我免费下载吗&#xff1f;” 奇客数据恢复安卓版是恢复已删除或丢失的 Android 数据的最安全的工具。免费下载下面的奇客数据恢复安卓版来尝试…

开始使用 Cortex-M 微控制器:ARM Cortex-M 架构介绍

ARM Cortex-M 架构是一种专为微控制器设计的处理器架构&#xff0c;致力于提供低功耗、高性能和成本效益的解决方案。本文将介绍ARM Cortex-M 架构的特点、核心部件以及常见的应用场景&#xff0c;并提供示例代码来演示使用Cortex-M 微控制器。 ✅作者简介&#xff1a;热爱科研…

js中this对象的理解(深度解析)

文章目录 一、定义二、绑定规则默认绑定隐式绑定new绑定显示修改 三、箭头函数四、优先级隐式绑定 VS 显式绑定new绑定 VS 隐式绑定new绑定 VS 显式绑定 参考文献 一、定义 函数的 this 关键字在 JavaScript 中的表现略有不同&#xff0c;此外&#xff0c;在严格模式和非严格模…

板块零 IDEA编译器基础:第二节 创建JAVA WEB项目与IDEA基本设置 来自【汤米尼克的JAVAEE全套教程专栏】

板块零 IDEA编译器基础&#xff1a;第二节 创建JAVA WEB项目与IDEA基本设置 一、创建JAVA WEB项目&#xff08;1&#xff09;普通项目升级成WEB项目&#xff08;2&#xff09;创建JAVA包 二、IDEA 开荒基本设置&#xff08;1&#xff09;设置字体字号自动缩放 &#xff08;2&am…

如何对视频进行翻译

下载视频和翻译软件 视频和翻译软件点击下载就行了&#xff0c;下载之后解压&#xff0c;然后把两个exe点一下。接下来如果资金充裕或者要求比较高的可以使用各个api&#xff0c;网站里有视频介绍了。 经济适用视频翻译 原理简析 首先这个软件对视频的翻译的流程大致如下&a…

普通编程,机器学习与深度学习

普通编程&#xff1a;基于人手动设置规则&#xff0c;由输入产生输出经典机器学习&#xff1a;人手工指定需要的特征&#xff0c;通过一些数学原理对特征与输出的匹配模式进行学习&#xff0c;也就是更新相应的参数&#xff0c;从而使数学表达式能够更好的根据给定的特征得到准…

(二)hadoop搭建

1. 下载 访问https://hadoop.apache.org/releases.html查看hadoop最新下载地址 wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.4/hadoop-3.3.4.tar.gz 2.解压 tar zxvf hadoop-3.3.4.tar.gz mv hadoop-3.3.4 /usr/local 3.配置环境变量&#xff08;新建.sh文件&…

IDEA创建SpringBoot+Mybatis-Plus项目

IDEA创建SpringBootMybatis-Plus项目 一、配置Maven apache-maven-3.6.3的下载与安装&#xff08;详细教程&#xff09; 二、创建SpringBoot项目 在菜单栏选择File->new->project->Spring Initializr&#xff0c;然后修改Server URL为start.aliyun.com&#xff0c…

TOP100-二叉数

1.94. 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xf…

提升你的PHP开发效率:探索JetBrains PhpStorm 2022的全新特性

在当今快速发展的软件开发领域&#xff0c;选择一个强大且高效的开发工具对于提升开发效率、保证代码质量至关重要。对于PHP开发者来说&#xff0c;JetBrains PhpStorm一直是市场上最受欢迎的IDE之一。随着JetBrains PhpStorm 2022的发布&#xff0c;这款工具带来了一系列创新功…

springboot 集成 nacos (demo 版)

环境要求&#xff1a;本地安装 nacos&#xff08;windows版本&#xff09;&#xff0c;jdk 是 8&#xff0c;安装完还得在 nacos 上面配置一个 yaml 类型的配置文件&#xff0c;方便项目演示读取。 提示&#xff1a;如标题所示&#xff0c;本文只介绍如何从零到一的去集成 naco…