Pinia:Vue 2 和 Vue 3 中更好用的状态管理框架

前言

还在用Vuex? 在Vue应用程序的开发过程中,高效且易于维护的状态管理一直是开发者关注的核心问题之一。随着Vue 3的发布,状态管理领域迎来了一位新星——Pinia,它不仅为Vue 3量身打造,同时也向下兼容Vue 2,以其简洁的API设计、强大的功能特性,逐渐成为Vue社区中备受推崇的状态管理框架。本文将深入探讨Pinia的魅力所在,并阐述为何它是Vue 2/Vue 3应用中更优的选择。

Pinia简介

Pinia是由Vue.js的核心维护者之一尤雨溪参与设计的下一代状态管理库,旨在提供一种更直观、更灵活的方式来管理Vue应用的状态。不同于传统的Vuex,Pinia从底层开始构建,充分利用Vue 3的新特性,特别是Composition API,使得状态管理变得更加自然和高效。

官网地址:Pinia | The intuitive store for Vue.js

Pinia凭借其现代化的设计理念、与Vue 3的深度融合、以及对Vue 2的良好兼容性,成为了Vue应用状态管理的新标准。无论你是Vue 2的忠实用户,还是Vue 3的探索者,Pinia都值得作为首选状态管理框架纳入你的开发工具箱。它不仅能够简化状态管理的复杂度,提升开发效率,还能在未来Vue生态的发展中为你提供坚实的支持。

为什么选择Pinia?

1. 简洁的API设计

直观的Store结构:Pinia通过defineStore函数创建store,每个store都是一个独立的模块,无需复杂的配置即可上手。

Action代替Mutation:Pinia合并了Mutation和Action的概念,直接在Action中修改状态,无论是同步还是异步操作,都更加直观和灵活。

2. Vue 3完美集成

Composition API友好:Pinia与Vue 3的Composition API无缝对接,使得状态管理逻辑可以轻松复用和组合。

响应式优化:得益于Vue 3的改进,Pinia在状态更新和响应式方面表现更佳,提升应用性能。

3. 强大的工具支持

类型安全:Pinia提供了良好的TypeScript支持,使得状态管理更加健壮和易于维护。

DevTools:Pinia拥有自己的DevTools插件,方便开发者调试状态变化,提高开发效率。

4. 灵活性与模块化

轻量级模块化:每个store都是一个独立单元,易于组织和复用,无需像Vuex那样显式声明模块。
易于扩展:Pinia的设计允许开发者根据需要轻松添加自定义插件或功能。

5. Vue 2兼容性

尽管为Vue 3而生,Pinia通过集成@vue/composition-api,同样能在Vue 2项目中发挥效能,为Vue 2用户提供了一条平滑过渡至Vue 3的路径。

使用Pinia

在你的项目中安装 Pinia 非常简单。首先,确保已经安装了 Vue CLI 或 Vite,然后按照以下步骤安装 Pinia:

# 如果使用 npm
npm install pinia

# 如果使用 yarn
yarn add pinia

在 Vue 3 中使用 Pinia

以下是一个简单的使用示例:

  1. 创建 Pinia 实例并挂载到 Vue 应用
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

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

app.use(pinia)
app.mount('#app')
  1. 定义一个 Store
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  }
})
  1. 在组件中使用 Store
// components/Counter.vue
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { useCounterStore } from '../stores/counter'

export default {
  setup() {
    const store = useCounterStore()
    return {
      count: store.count,
      doubleCount: store.doubleCount,
      increment: store.increment
    }
  }
}
</script>

还有另一种可能的语法来定义存储。与 Vue Composition API 的setup 函数类似,可以传入一个定义响应式属性和方法的函数,并返回一个具有我们想要公开的属性和方法的对象。 

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

  return { count, name, doubleCount, increment }
})
  • ref()成为state属性
  • computed()成为getters
  • function()成为actions

注意,必须返回设置存储中的所有状态属性,以便 Pinia 将它们选为状态。换句话说,不能在存储中拥有私有状态属性。

从 Store 解构

为了从 store 中提取属性并保持其响应性,您需要使用storeToRefs()。它将为每个响应性属性创建 refs。

<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'

const store = useCounterStore()
// `name` and `doubleCount` are reactive refs
// This will also extract refs for properties added by plugins
// but skip any action or non reactive (non ref/reactive) property
const { name, doubleCount } = storeToRefs(store)
// the increment action can just be destructured
const { increment } = store
</script>

在使用 Pinia 时,特别是在 Vue 3 中,可以通过 storeToRefs() 来解构 store 中的响应性属性,并保持其响应性。这对于从 store 中直接获取状态属性并在组件中使用非常有用。此外,操作函数可以直接从 store 中解构,因为它们已经绑定到 store 本身。下面详细介绍如何用 storeToRefs() 以及操作函数的解构:

使用 storeToRefs 解构状态属性

storeToRefs 是一个方便的工具,用于将 store 的响应性状态属性转换为独立的 refs。这样解构后的属性仍然保持响应性。

示例

假设我们有一个简单的 Pinia store:

// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

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

  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

在组件中使用 storeToRefs

  1. 导入 storeToRefs 和 store
import { useCounterStore } from '../stores/counter'
import { storeToRefs } from 'pinia'
  1. 在 setup 函数中使用 storeToRefs 解构状态属性
<script setup>
import { useCounterStore } from '../stores/counter'
import { storeToRefs } from 'pinia'

// 获取 store 实例
const counterStore = useCounterStore()

// 使用 storeToRefs 解构状态属性
const { count, doubleCount } = storeToRefs(counterStore)

// 直接解构操作函数
const { increment } = counterStore
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

在上面的示例中,使用 storeToRefs 解构了 count 和 doubleCount,确保它们仍然是响应的。此外,直接从 store 中解构了 increment 操作函数并使用它。

注意事项

  • 保持响应性storeToRefs 确保从 store 解构出来的属性保持响应性。如果你仅使用普通的对象解构赋值,将无法保持响应性。
  • 操作函数绑定:操作函数可以直接从 store 中解构,因为它们已经绑定到 store,这意味着调用它们时会自动处理内部的响应性。

 以下是完整的组件代码:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { useCounterStore } from '../stores/counter'
import { storeToRefs } from 'pinia'

// 获取 store 实例
const counterStore = useCounterStore()

// 使用 storeToRefs 解构状态属性
const { count, doubleCount } = storeToRefs(counterStore)

// 直接解构操作函数
const { increment } = counterStore
</script>

Composition 和 Options API如何选择

Vue 的 Composition API 和 Options API

在 Vue 3 中使用 Pinia 进行状态管理时,有两种主要方式来定义 stores:Options API Stores 和 Setup Stores。它们各有优缺点,适用于不同的场景。本文将介绍这两种方式,并给出选择的建议。

Options API Stores

Options API Stores 是一种传统的方式,通过定义 stategetters 和 actions 对象来管理状态。这种方式类似于 Vuex 的 API,适合那些习惯或熟悉 Options API 的开发者。

优点

  1. 结构清晰:逻辑和数据分离开,结构清晰易维护。
  2. 熟悉度高:与 Vuex 的风格相似,Vuex 用户容易上手。
  3. 良好的 IDE 支持:由于属性定义在对象内,可以享受良好的 TypeScript 支持和 IDE 的自动补全。

缺点

  1. 代码较冗长:对于复杂的逻辑,代码可能略显冗长。
示例
// stores/counter.js
import { defineStore } from 'pinia'

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

Setup Stores

Setup Stores 使用 Vue 3 的 Composition API 来管理状态。这种方式充分利用了 Composition API 的灵活性,可以将逻辑和状态更加紧密地结合在一起。

优点

  1. 逻辑复用:通过 Composition API,可以轻松实现逻辑复用。
  2. 灵活性高:可以利用 Composition API 的全部功能,如 refreactive 和 computed 等。
  3. 更少的模板代码:由于直接使用 Composition API,代码更加简洁。

缺点

  1. 学习成本:对于不熟悉 Composition API 的开发者,需要一定的学习成本。
  2. TypeScript 支持复杂:由于 Setup Stores 依赖于 Composition API,TypeScript 的类型推断和自动补全可能需要更多的手动配置。
示例
// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

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

  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
})

如何选择?

选择 Options API Stores 的场景

  1. 习惯 Vuex 风格:如果你或者你的团队成员习惯了 Vuex 的风格,Options API Stores 会更加适合。
  2. 项目复杂度较低:对于简单的项目,Options API Stores 的结构更加清晰直观。
  3. 注重 TypeScript 支持:如果你的项目 heavily 依赖于 TypeScript,Options API Stores 提供了更好的 IDE 自动补全和类型推断支持。

选择 Setup Stores 的场景

  1. 熟悉 Composition API:如果你或者你的团队已经熟悉了 Composition API,Setup Stores 可以充分利用其灵活性。
  2. 需要逻辑复用:如果你的项目中需要在多个组件之间复用逻辑,Setup Stores 通过 Composition API 可以很容易地实现。
  3. 项目复杂度较高:对于复杂的大型项目,Setup Stores 可以保持代码更加简洁和模块化。

混合使用

值得注意的是,Pinia 允许你在同一个项目中混合使用 Options API Stores 和 Setup Stores。这意味着你可以根据具体场景选择最适合的方式。例如,可以在简单的模块中使用 Options API Stores,而在需要复杂逻辑复用的模块中使用 Setup Stores。

在 Vue 2 中使用 Pinia

Pinia 也支持在 Vue 2 中使用,以下是一个基本的示例:

  1. 在 Vue 2 项目中安装 @vue/composition-api
npm install @vue/composition-api
  1. 在项目入口文件中配置 Pinia
// main.js
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'
import { createPinia, PiniaVuePlugin } from 'pinia'
import App from './App.vue'

Vue.use(VueCompositionAPI)
Vue.use(PiniaVuePlugin)

const pinia = createPinia()

new Vue({
  pinia,
  render: h => h(App)
}).$mount('#app')
  1. 定义并使用 Store 定义和使用 Store 的方式与在 Vue 3 中基本一致。
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  }
})
// components/Counter.vue
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { useCounterStore } from '../stores/counter'
import { defineComponent } from '@vue/composition-api'

export default defineComponent({
  setup() {
    const store = useCounterStore()
    return {
      count: store.count,
      doubleCount: store.doubleCount,
      increment: store.increment
    }
  }
})
</script>

reactive和ref区别

在 Vue 3 的 Composition API 中,reactive 和 ref 是两个用于创建响应式数据的方法。它们在创建、使用和工作方式上有一些重要的区别。下面详细介绍这两者的区别:

ref 简介

ref 用于创建一个单一的响应式变量。如果你有一个简单的原始数据(如字符串、数值、布尔值等)或对象,并希望它成为响应式的,可以使用 ref

特点
  1. 单一响应式值ref 通常用于创建一个响应式的原始数据或对象。
  2. 访问值:通过 .value 属性来访问或修改 ref 包裹的数据。
  3. 模板中自动展开:在模板中直接使用 ref,无需 .value,Vue 会自动处理。
示例
import { ref } from 'vue'

export default {
  setup() {
    // 创建一个响应式的数值
    const count = ref(0)

    // 使用 .value 访问和修改值
    count.value++

    return {
      count
    }
  }
}

在模板中:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="count++">Increment</button>
  </div>
</template>

reactive 简介

reactive 用于创建一个响应式对象或数组。它将整个对象或数组转换为响应式的,使其内部的所有属性都变为响应式。

特点
  1. 响应式对象或数组reactive 通常用于创建一个复杂的响应式对象或数组。
  2. 直接访问属性:无需 .value,可以直接访问和修改内部的属性。
  3. 适合复杂结构:更适合具有多个属性或嵌套结构的对象。
示例
import { reactive } from 'vue'

export default {
  setup() {
    // 创建一个响应式对象
    const state = reactive({
      count: 0,
      name: 'Vue'
    })

    // 直接访问和修改属性
    state.count++
    state.name = 'Vue 3'

    return {
      state
    }
  }
}

在模板中:

<template>
  <div>
    <p>Count: {{ state.count }}</p>
    <p>Name: {{ state.name }}</p>
    <button @click="state.count++">Increment</button>
  </div>
</template>

ref vs reactive

  • 使用目的

    • ref:适用于创建单一的原始数据或对象的响应式引用。
    • reactive:适用于创建整个对象或数组的响应式状态。
  • 访问和修改

    • ref:通过 .value 访问和修改数据。
    • reactive:直接访问和修改对象或数组的属性。
  • 适用场景

    • ref:适用于简单的数据结构或单一的变量。
    • reactive:适用于复杂的数据结构,包含多个属性和嵌套对象。

实际应用中的选择

  • 简单变量:如果你只是需要一个简单的响应式变量,比如数值、布尔值或字符串,那么 ref 是一个更合适的选择。
  • 复杂对象:如果你的状态包含多个属性或嵌套结构,那么 reactive 更加适用。

组合使用

在实际开发中,有时需要将 ref 和 reactive 组合使用。例如,你可以在一个 reactive 对象中包含多个 ref,或者在一个 ref 中嵌套 reactive 对象处理更复杂的情况。

结合示例

import { ref, reactive } from 'vue'

export default {
  setup() {
    const user = reactive({
      name: 'John',
      age: ref(30) // 使用 ref 创建单独的响应式属性
    })

    const incrementAge = () => {
      user.age.value++
    }

    return {
      user,
      incrementAge
    }
  }
}

在模板中:

<template>
  <div>
    <p>Name: {{ user.name }}</p>
    <p>Age: {{ user.age }}</p>
    <button @click="incrementAge">Increment Age</button>
  </div>
</template>

总结起来,ref 和 reactive 是 Vue 3 中强大的工具,能够帮助你创建和管理响应式状态。通过了解它们的区别和使用场景,你可以更好地在项目中应用它们,使状态管理更加清晰和高效。

组合式api和选项式api的选择

Introduction | Vue.js

在 Vue 3 中,组合式 API(Composition API)和选项式 API(Options API)各有优缺点,适用于不同的场景和需求。选择使用哪个 API 主要取决于团队的熟悉程度、项目的复杂性以及个人偏好。以下是对两种 API 的详细比较和推荐建议。

选项式 API(Options API)

特点
  1. 结构清晰: 选项式 API 将数据、方法、计算属性等明确定义在不同的选项中,如 datamethodscomputed 等。
  2. 易学易用: 对于初学者来说,选项式 API 更加直观,易于理解和上手。
  3. 直观的生命周期钩子: 选项式 API 中的生命周期钩子非常明确,如 createdmounted 等。
示例
export default {
  data() {
    return {
      count: 0
    }
  },
  computed: {
    doubleCount() {
      return this.count * 2;
    }
  },
  methods: {
    increment() {
      this.count++;
    }
  },
  mounted() {
    console.log('Component has been mounted');
  }
}

组合式 API(Composition API)

特点
  1. 更好的逻辑复用: 通过组合式 API 的 setup 函数可以灵活地复用逻辑,不同组件可以共享相同的逻辑。
  2. 更强的灵活性: 组合式 API 允许在一个函数中组织相关逻辑和状态,使得代码更容易维护和理解,尤其是大型项目。
  3. TypeScript 支持更佳: 由于组合式 API 更接近函数式编程风格,TypeScript 的类型推断和自动补全更自然,代码也更易于类型定义和检查。
  4. 更精细的生命周期控制: 通过组合式 API,你可以在 setup 函数中更精细地控制组件的生命周期。
示例
import { ref, computed, onMounted } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const doubleCount = computed(() => count.value * 2);

    function increment() {
      count.value++;
    }

    onMounted(() => {
      console.log('Component has been mounted');
    });

    return {
      count,
      doubleCount,
      increment
    };
  }
}

如何选择?

选择选项式 API 的场景
  1. 初学者或简单项目: 对于刚开始学习 Vue 的开发者或简单的小型项目,选项式 API 更加直观易懂,入门门槛低。
  2. 维护现有代码: 如果你需要维护一个已经使用选项式 API 编写的大型老项目,继续使用选项式 API 可能更为合适。
选择组合式 API 的场景
  1. 大型项目或复杂应用: 组合式 API 更适合于大型项目或复杂的应用,因为它可以更好地组织和复用代码。
  2. 需要重用逻辑: 如果你的项目中需要在多个组件间复用逻辑,组合式 API 更加灵活和高效。
  3. TypeScript 项目: 如果你的项目广泛使用 TypeScript,组合式 API 提供了更友好的类型支持和自动补全。

混合使用

值得注意的是,Vue 3 同时支持选项式 API 和组合式 API,你可以在同一个项目中混合使用这两种方式。这意味着你可以逐渐迁移,或者在不同的组件中选择最适合的方式。

最佳实践及推荐

总体来说,如果你在开始一个新的 Vue 3 项目,并且希望利用 Vue 3 的全部新特性,组合式 API 通常是更好的选择。它提供了更强的灵活性和更好的逻辑复用,同时也更适合复杂的应用和大型项目。

然而,如果你或者你的团队对选项式 API 更加熟悉,并且当前项目的复杂度不高,那么选项式 API 依然是一个非常好的选择,能够满足需求并且快速上手。

使用组合式 API 还是选项式 API,取决于你的具体需求和偏好。对于新的项目和复杂的应用,推荐使用组合式 API,以充分利用 Vue 3 的新功能和灵活性。对于简单项目或已经在使用选项式 API 的现有项目,选项式 API 依然是一个很好的选择。无论选择哪种方式,都需要根据项目的实际情况进行决策。

总结 

总得来说,Pinia 就是 Vuex 的替代版,可以更好的兼容 Vue2,Vue3以及TypeScript。在Vuex的基础上去掉了 Mutation,只保留了 state, getter和action。Pinia拥有更简洁的语法, 扁平化的代码编排,符合Vue3 的 Composition api。

其他资源

 vue3中使用pinia代替vuex_vue3使用vuex还是pinia-CSDN博客

使用 Vue 3.0,你可能不再需要Vuex了-CSDN博客 

Pinia:全新的Vue状态管理库,Vuex的代替者_pinia dispatch-CSDN博客

Vue 状态管理:从Vuex到Pinia,Vue 3官方推荐的状态管理库深度解析-CSDN博客

cool-admin-vue: cool-admin一个很酷的后台权限管理框架,模块化、插件化、CRUD极速开发,永久开源免费,基于midway2.0、typeorm、mysql、jwt、element-ui、vuex、vue-router、vue等构件

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django学习第四天

启动项目命令 python manage.py runserver 分页功能封装到类中去 封装的类的代码 """ 自定义的分页组件,以后如果想要使用这个分页组件&#xff0c;你需要做&#xff1a; def pretty_list(request):# 靓号列表data_dict {}search_data request.GET.get(q, &…

谷粒商城-个人笔记(集群部署篇二)

前言 ​学习视频&#xff1a;​Java项目《谷粒商城》架构师级Java项目实战&#xff0c;对标阿里P6-P7&#xff0c;全网最强​学习文档&#xff1a; 谷粒商城-个人笔记(基础篇一)谷粒商城-个人笔记(基础篇二)谷粒商城-个人笔记(基础篇三)谷粒商城-个人笔记(高级篇一)谷粒商城-个…

Excel为数据绘制拆线图,并将均值线叠加在图上,以及整个过程的区域录屏python脚本

Excel为数据绘制拆线图,并将均值线叠加在图上,以及整个过程的区域录屏python脚本 1.演示动画A.视频B.gif动画 2.跟踪鼠标区域的录屏脚本 Excel中有一组数据,希望画出曲线,并且能把均值线也绘制在图上,以下动画演示了整个过程,并且提供了区域录屏脚本,原理如下: 为节约空间,避免…

SpringBoot 启动流程一

SpringBoot启动流程一 我们首先创建一个新的springboot工程 我们不添加任何依赖 查看一下pom文件 我们创建一个文本文档 记录我们的工作流程 我们需要的是通过打断点实现 我们首先看一下启动响应类 package com.bigdata1421.start_up;import org.springframework.boot.Spr…

【Android面试八股文】Android性能优化面试题:怎样检测函数执行是否卡顿?

文章目录 卡顿一、可重现的卡顿二、不可重现的卡顿第一种方案: 基于 Looper 的监控方法第二种方案:基于 Choreographer 的监控方法第三种方案:字节码插桩方式第四种方案: 使用 JVMTI 监听函数进入与退出总结相关大厂的方案ArgusAPMBlockCanaryQQ空间卡慢组件Matrix微信广研参…

linux中与网络有关的命令

本文的命令总览 ifconfig命令 在 Linux 系统中&#xff0c;ifconfig 命令用于配置和显示网络接口的信息&#xff0c;包括 IP 地址、MAC 地址、网络状态等。同时我们也可以利用ifconfig 命令设置网络接口对应的ip地址&#xff0c;子网掩码等 当你使用 ifconfig 命令时&#xf…

DC/AC电源模块为现代电子设备提供稳定的能源

BOSHIDA DC/AC电源模块为现代电子设备提供稳定的能源 DC/AC电源模块是一种重要的电子设备&#xff0c;它为现代电子设备提供稳定的能源。在今天的高科技社会中&#xff0c;电子设备已经成为人们生活和工作的重要组成部分。从家用电器到计算机、手机、汽车和航天航空设备&…

微信小程序毕业设计-球馆预约系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

Spring AI 1.0.0 新变化,从 0.8.1 如何升级

Spring AI 1.0.0-M1 版本已经发布&#xff0c;距离 1.0.0 正式版又更近了一步。同时这也意味着&#xff0c;Spring AI 1.0.0 的 API 已经基本确定&#xff0c;不会发生大的改动。这里介绍一下&#xff0c;相对于上一个发布版本 0.8.1&#xff0c;Spring AI 1.0.0 的一些重要的变…

【C语言】—— 文件操作(上)

【C语言】—— 文件操作&#xff08;上&#xff09; 一、 为什么使用文件二、 什么是文件2.1、 程序文件2.2、 数据文件2.3、 文件名2.4、二进制文件与文本文件 三、 文件的打开和关闭3.1、流和标准流&#xff08;1&#xff09;流&#xff08;2&#xff09;标准流 3.2、文件指针…

@PostConstruct注解

1.简介 PostConstruct是java5的时候引入的注解&#xff0c;主要用于标记一个方法&#xff0c;表示该方法应在依赖注入完成后自动调用。通常在使用Java EE或者Spring框架时使用这个注解&#xff0c;以便在Bean初始化之后执行一些初始化工作&#xff0c; 可作为一些数据的常规化…

hadoop集群部署【二】YARN MapReduce 的部署

提前注意&#xff1a;请注意路径是否和我的相同&#xff0c;放置的位置不同&#xff0c;请修改标红处 HDFS部署 HDFS介绍及部署http://t.csdnimg.cn/Q3H3Y 部署说明 Hadoop HDFS分布式文件系统&#xff0c;我们会启动&#xff1a; NameNode进程作为管理节点 DataNode进程…

WRF学习——使用CMIP6数据驱动WRF/基于ncl与vdo的CMIP6数据处理

动力降尺度 国际耦合模式比较计划&#xff08;CMIP&#xff09;为研究不同情景下的气候变化提供了大量的模拟数据&#xff0c;而在实际研究中&#xff0c;全球气候模式输出的数据空间分辨率往往较低&#xff08;>100Km&#xff0c;缺乏区域气候特征&#xff0c;为了更好地研…

K8s 集群(kubeadm) CA 证书过期解决方案

Author&#xff1a;Arsen Date&#xff1a;2024/07/04 目录 一、现象描述二、解决方案三、集群验证 一、现象描述 之前有篇文章《K8s Token 过期解决方案&#xff08;Kubeadm&#xff09;》提到了默认生成的 Token 有效期只有 24 小时&#xff0c;过期后 Token 将不可用&#…

C# 类型转换之显式和隐式

文章目录 1、显式类型转换2. 隐式类型转换3. 示例4. 类型转换的注意事项5. 类型转换的应用示例总结 在C#编程中&#xff0c;类型转换是一个核心概念&#xff0c;它允许我们在程序中处理不同类型的数据。类型转换可以分为两大类&#xff1a;显式类型转换&#xff08;Explicit Ca…

18. JAVA 多线程锁介绍

1. 前言 本节内容主要是对 Java 多线程锁进行介绍&#xff0c;是对锁的一个全方位的概述&#xff0c;为我们对后续深入学习不同的锁的使用方法奠定一个良好的基础。本节内容的知识点如下&#xff1a; 乐观锁与悲观锁的概念&#xff0c;以及两种锁之间的区别&#xff0c;这是并…

文华财经T9多空波段趋势量化交易策略模型源码

// 定义变量 Vars Numeric STEP1,MVALUE1,SARVAL,C; Numeric SARLINE,COND,ZBMA1,ZBMA2; Begin CCLOSE; STEP13/11; MVALUE120/22; SARVALSAR(4, STEP1, MVALUE1); PlotLine("",IIF(SARVAL>0,SARVAL,InvalidNumeric),RED,Circledot); PlotLine("&q…

今晚19点,《语音和心理健康》开讲!

《2024GAS声学大讲堂—音频产业创新技术公益讲座》面向医疗健康的声音与音乐技术系列专题讲座 第五讲 将于 今晚 19点 开讲&#xff0c;本次邀请了 湖南大学 教授 张子兴 演讲&#xff0c;讲座主题&#xff1a;《语音和心理健康》。此次直播方式为腾讯会议、小鹅通和中国电子音…

初出茅庐的小李博客之C语言文件操作

C语言文件操作 在C语言中&#xff0c;文件操作主要是通过标准库函数来实现的。 今天有时间就来学习下一些常用的文件操作函数&#xff1a; C 语言提供了一个 FILE 数据结构&#xff0c;记录了操作一个文件所需要的信息。该结构定义在头文件stdio.h&#xff0c;所有文件操作函…

如何通过IP地址查询地理位置及运营商信息

在数字时代&#xff0c;IP地址&#xff08;Internet Protocol Address&#xff0c;互联网协议地址&#xff09;已经成为我们日常网络活动的重要组成部分。每台连接到互联网的设备都被分配了一个唯一的IP地址&#xff0c;它不仅可以识别设备&#xff0c;还可以揭示设备的地理位置…