Vue3框架:一套武功秘籍即可上手 Vue3 项目开发需求:setup(原生 + 语法糖) && Vue3组合式 API 新特性 + Pinia状态管理工具 && Pinia持久化本地存储

本文详细介绍了Vue3框架的优势、与Vue2的区别,以及如何创建项目、setup的语法糖、reactive和ref函数、computed计算属性、watch的使用、生命周期函数、组件间的通信、Pinia库的介绍和基本使用,包括定义选项和store。
摘要由CSDN通过智能技术生成

LiuJinTao:2024年4月10日

Vue3 框架

一、Vue3的优势

在这里插入图片描述

二、、Vue3 和 Vue2 的区别

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

三、创建 Vue3 项目 (create-vue)

1. 改变创建项目的方式

在这里插入图片描述

2. 创建项目的前提条件

在这里插入图片描述

  • 创建完毕后,运行项目后看到下图,那么恭喜你,成功创建了最新的Vue3项目

在这里插入图片描述

四、setup原始写法

1. 执行时机

在这里插入图片描述

2. 代码书写特点

在这里插入图片描述

  • 这样书写代码每次都得return,太麻烦了,解决方案如下。

五、setup 语法糖

在这里插入图片描述

  • 注意: 这里语法糖就是底层帮我们进行了return。

语法糖底层原理
在这里插入图片描述

六、setup 小结

在这里插入图片描述

七、组合式 API - reactive 和 ref 函数

1. reactive 函数

在这里插入图片描述

<script setup>
  import { reactive } from 'vue'
  const state = reactive({
    count: 100
  })
  const HandleAddCount  = () => {
    state.count++
  }
  const HandleRemoveCount = () => {
    state.count = 0
  }

</script>

<template>
  <div>
    <div>{{ state.count }}</div>
    <button @click="HandleAddCount">+1</button>
    <button @click="HandleRemoveCount">重置</button>
  </div>
</template>

<style scoped>

</style>

2. ref 函数
  • 推荐使用 ref

在这里插入图片描述
ref()​用法
在组合式 API 中,推荐使用 ref() 函数来声明响应式状态:

import { ref } from 'vue'

const count = ref(0)

ref() 接收参数,并将其包裹在一个带有 .value 属性的 ref 对象中返回:

const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1
参考:为 refs 标注类型 

要在组件模板中访问 ref,请从组件的 setup() 函数中声明并返回它们:

js
import { ref } from 'vue'

export default {
  // `setup` 是一个特殊的钩子,专门用于组合式 API。
  setup() {
    const count = ref(0)

    // 将 ref 暴露给模板
    return {
      count
    }
  }
}
<div>{{ count }}</div>

注意,在模板中使用 ref 时,我们不需要附加 .value。为了方便起见,当在模板中使用时,ref 会自动解包 (有一些注意事项)。

你也可以直接在事件监听器中改变一个 ref:

<button @click="count++">
  {{ count }}
</button>

对于更复杂的逻辑,我们可以在同一作用域内声明更改 ref 的函数,并将它们作为方法与状态一起公开:

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)

    function increment() {
      // 在 JavaScript 中需要 .value
      count.value++
    }

    // 不要忘记同时暴露 increment 函数
    return {
      count,
      increment
    }
  }
}

然后,暴露的方法可以被用作事件监听器:

<button @click="increment">
  {{ count }}
</button>

这里是 Codepen 上的例子,没有使用任何构建工具。

3. 小结

在这里插入图片描述

八、computed计算属性函数

在这里插入图片描述

<script setup>
  import { ref, computed } from 'vue'

  const list = ref([1, 2, 3, 4, 5, 6, 7, 8, 9])
  const computedList = computed(()=> {
    return list.value.filter( item => item > 2 ) // item 表示每一个数组元素,然后通过回调函数return item > 2 的元素
  })
</script>

在这里插入图片描述

九、 组合式 API - watch

在这里插入图片描述

1. 单个监视

在这里插入图片描述


<script setup>
import { ref, watch } from 'vue'
  const count = ref(0)
  const name = ref('zhangsan')

  const changeCount = () => {
    count.value++
  }

  const changeName = () => {
    name.value = 'lisi'
  }

  //  监听单个数据 - > 语法: watch(ref对象, 回调函数)
  watch(count, (newValue, oldValue) => {
    console.log('newValue', newValue, 'oldValue', oldValue)
  })
  watch(name, (newValue, oldValue) => {
    console.log('新名字', newValue, '旧名字', oldValue)
  })
</script>


<template>
  <div>
      <div>{{ count }}</div>
      <button @click="changeCount">修改 count </button>
      <div>{{ name }}</div>
      <button @click="changeName">修改 name</button>
  </div>
</template> 
2. 多个监视

在这里插入图片描述


<script setup>
import { ref, watch } from 'vue'
  const count = ref(0)
  const name = ref('zhangsan')

  const changeCount = () => {
    count.value++
  }

  const changeName = () => {
    name.value = 'lisi'
  }

  //  监听单个数据 - > 语法: watch(ref对象, 回调函数)
  watch(count, (newValue, oldValue) => {
    console.log('newValue', newValue, 'oldValue', oldValue)
  })
  watch(name, (newValue, oldValue) => {
    console.log('新名字', newValue, '旧名字', oldValue)
  })
  //  监听多个数据 - > 语法: watch([ref对象数据], 回调函数)
  watch([count, name], (newValue, oldValue) => {
    console.log('新值', newValue, '旧值', oldValue)
  })
</script>


<template>
  <div>
      <div>{{ count }}</div>
      <button @click="changeCount">修改 count </button>
      <div>{{ name }}</div>
      <button @click="changeName">修改 name</button>
  </div>
</template> 

十、watch - 参数

  • 浅层监视
    在这里插入图片描述
    开启后,可以说是页面加载就进行监听了,然后后续在执行回调函数。

  • 深层监视: 监视复杂数据类型的地址,表面的数据我们监视并不会触发

  • deep 深度监视, 由于 watch 默认是进行的 浅层监视,所以我们监视的复杂数据类型是无法进行对内容进行深度监视。所以我们这里就需要开启深度监视。

const info  = ref({
	name: '张三',
	age: 23
}, {
	deep: true  // 开启深度监视
})

十一、watch - 精确监听

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

十二、 watch 总结

在这里插入图片描述

十三、组合式 API - 生命周期函数

在这里插入图片描述


<script setup>
import { onMounted } from 'vue';

  // 生命周期函数
  const getList = () => {
    setTimeout(() => {
      console.log('请求数据列表!')
    }, 2000)
  }
  getList()

  onMounted(() => {
    console.log('onMounted生命周期函数执行逻辑 - 1')
  })

  onMounted(() => {
    console.log('onMounted生命周期函数执行逻辑 - 2')
  })

  
</script>
  • 组合式API 中,还支持重复 调用生命周期函数。

十四、组合式 API- 组件通信

1. 父传子

在这里插入图片描述

2. 编译器宏defindProps 底层原理

在这里插入图片描述

3. 子传父

在这里插入图片描述

十五、组件通信总结

在这里插入图片描述

十六、模板引用

在这里插入图片描述

在这里插入图片描述

  • 但需要注意的是,我们获取了组件对象,自然是需要拿到组件内部的属性数据的。但是需要注意的是,需要在组件中进行配置 编译宏 进行处理。避免引用失败。方法如下:
    在这里插入图片描述

在这里插入图片描述

十七、组合式 API - provide 和 inject

在这里插入图片描述

1. 跨层传递 - 普通数据

在这里插入图片描述

2 跨层传递 - 响应式数据

在这里插入图片描述

3. 跨层传递 - 方法

在这里插入图片描述

  • 因此就可以如下处理数据:在这里插入图片描述

十八、Vue3 新特性 defineOptions

在这里插入图片描述

  • 用法:
  • 在这里插入图片描述

十九、Vue3 新特性 - defindModel

在这里插入图片描述

二十、Pinia

1. 什么是 Pinia

Pinia官网:Pinia
在这里插入图片描述

2. 手动添加 Pinia

在这里插入图片描述
安装
用你喜欢的包管理器安装 pinia:

yarn add pinia
或者使用 npm
npm install pinia

TIP

如果你的应用使用的 Vue 版本低于 2.7,你还需要安装组合式 API 包:@vue/composition-api。如果你使用的是 Nuxt,你应该参考这篇指南。

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

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

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')

如果你使用的是 Vue 2,你还需要安装一个插件,并在应用的根部注入创建的 pinia:

import { createPinia, PiniaVuePlugin } from 'pinia'

Vue.use(PiniaVuePlugin)
const pinia = createPinia()

new Vue({
  el: '#app',
  // 其他配置...
  // ...
  // 请注意,同一个`pinia'实例
  // 可以在同一个页面的多个 Vue 应用中使用。 
  pinia,
})

这样才能提供 devtools 的支持。在 Vue 3 中,一些功能仍然不被支持,如 time traveling 和编辑,这是因为 vue-devtools 还没有相关的 API,但 devtools 也有很多针对 Vue 3 的专属功能,而且就开发者的体验来说,Vue 3 整体上要好得多。在 Vue 2 中,Pinia 使用的是 Vuex 的现有接口 (因此不能与 Vuex 一起使用) 。

3. Pinia 的基本使用

在这里插入图片描述

1. 创建仓库store
// Pinia 仓库
/**
 * 定义 store仓库语法:
 *          - defineStore(仓库的名称, () => {数据逻辑....})
 * 
 */

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

export const userCounterStore = defineStore('counter', () => {
    // 声明仓库数据
    const count = ref(100)

    // 仓库处理函数actions(就相当于普通函数)
    const handleAdd = () => count.value++
    const handleSub = () => count.value--

    // 计算属性
    const number = computed(() => count.value * 2)

    // 声明仓库数据
    const message = ref('Pinia 仓库')




    // return 仓库数据,外部调用
    return {
        count,
        handleAdd,
        handleSub,
        number,
        message,
    }
})
2. 组件中使用
<script setup>
  import Son1Com from "./components/Son1Com.vue";
  import Son2Com from "./components/Son2Com.vue";

  // 导入仓库暴露出来的对象引用
  import { userCounterStore } from '@/store/counter'

  const counterStore = userCounterStore()

  // const count = ref(0)
</script>

<template>
  <div>
    <h3>我是 APP 根组件 - {{ counterStore.count }} </h3> <span>{{ counterStore.message }}</span>
    
    <Son1Com></Son1Com>
    <Son2Com></Son2Com>
  </div>
</template>

<style scoped>

</style>





console.log('--------------------------------------')
<script setup>
  // 导入仓库方法
 import { userCounterStore } from '@/store/counter' 
  // 通过方法创建对象
 const counterStore = userCounterStore()
</script>
<template>
    <div>
        <div>我是 Son1Com - {{ counterStore.count }} --- {{ counterStore.number }}</div>
        <button @click="counterStore.handleAdd">+</button>
    </div>

</template>

<style scoped>

</style>
    


console.log('--------------------------------------')


<script setup>
    // 1. 导入仓库方法
    import { userCounterStore } from '@/store/counter'
    // 2. 使用方法创建对象
    const counterStore = userCounterStore()

</script>
<template>
    <div>我是 Son2Com - {{ counterStore.count }}</div>
    <button @click="counterStore.handleSub">-</button>
</template>

<style scoped>

</style>
    



这样就能够实现数据同步共享了。

4. action 异步实现

在这里插入图片描述

  • 在项目中安装一下 axios 库
yarn add axios
  • 创建仓库进行代码编写
import { defineStore } from 'pinia'
import { ref } from 'vue'
import axios from 'axios'

export const useChannelStore = defineStore( 'channel', () => {
    // 仓库数据
    const channelList = ref([])

    // action 操作数据的方法 (支持异步)
    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
    }
})
5. store 解构的响应式问题

在这里插入图片描述

  • 我们通过实例调用数据也行。当我们数据太多了,就可以使用解构的方法进行处理数据。但是需要注意响应式的问题。(方法可以直接解构,因为我们只是调用方法,没有其他修改等操作)。
6. Pinia 持久化存储

【官网地址】: Pinia插件官网
在这里插入图片描述
快速开始

  • 概述
    本插件兼容 pinia^2.0.0,在使用之前请确保你已经 安装 Pinia。 pinia-plugin-persistedstate 丰富的功能可以使 Pinia Store 的持久化更易配置:

与 vuex-persistedstate 相似的 API
所有 Store 均可单独配置
自定义 storage 和数据序列化
恢复持久化数据前后的 hook
每个 Store 具有丰富的配置
兼容 Vue 2 和 3
无任何外部依赖

  • 安装
    包管理器安装依赖:

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,
  },
)

现在,你的整个 Store 将使用默认持久化配置保存。
在这里插入图片描述

  • 将上面创建的两个仓库进行持久化,我们本地就能进行存储数据了。
7. 配置 本地存储的 key 名字

配置
该插件的默认配置如下:

使用 localStorage 进行存储
store.$id 作为 storage 默认的 key
使用 JSON.stringify/JSON.parse 进行序列化/反序列化
整个 state 默认将被持久化
如何你不想使用默认的配置,那么你可以将一个对象传递给 Store 的 persist 属性来配置持久化。

import { defineStore } from 'pinia'

export const useStore = defineStore('main', {
  state: () => ({
    someState: '你好 pinia',
  }),
  persist: {
    // 在这里进行自定义配置
  },
})

key
类型:string
默认值:store.$id
Key 用于引用 storage 中的数据

例如

import { defineStore } from 'pinia'

export const useStore = defineStore('store', {
  state: () => ({
    someState: '你好 pinia',
  }),
  persist: {
    key: 'my-custom-key',
  },
})

这个 Store 将被持久化存储在 localStorage 中的 my-custom-key key 中。

8. 指定仓库中某些数据进行持久化

paths

类型:string[]
默认值:undefined
用于指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state。

例如

import { defineStore } from 'pinia'

export const useStore = defineStore('store', {
  state: () => ({
    save: {
      me: 'saved',
      notMe: 'not-saved',
    },
    saveMeToo: 'saved',
  }),
  persist: {
    paths: ['save.me', 'saveMeToo'],
  },
})

该 store 中, 只有 save.me 和 saveMeToo 被持久化,而 save.notMe 不会被持久化。

  • Pinia 的使用:总而言之,参考官网文档进行使用配置即可。

二十一、Pinia 总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脱发使我稳重

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值