vue3 基础+进阶(三、项目篇:状态管理库、路由以及一些基本配置)

目录

第三章 状态管理库:Pinia

3.1 创建空Vue项目并安装Pinia

3.1.1 创建空Vue项目

3.1.2 安装Pinia以及持久化工具

3.2 使用pinia

3.1.1 使用案例

3.1.2 规范问题

3.1.3 简化:结构赋值 

第四章 Vue3的Router路由理解(与vue2类比)

4.1 安装

4.2 路由配置与使用

4.2.1 创建路由组件文件

4.2.2 创建路由配置文件

4.2.3 配置路由信息

4.2.4 使用路由

4.3 query 传参的方法

4.3.1 query参数传递 

4.3.2 query参数获取

4.4 params 传参的方法

4.4.1 params参数传递

4.4.2 params参数获取 

第五章 项目准备工作

5.1 jsconfig.json配置别名路径

5.2 elementPlus引入 

5.3 axios安装并简单封装

5.3.1 axios安装

5.3.2 简单封装


vue3基础+进阶(二、vue3常用组合式api基本使用)-CSDN博客

(由于前段时间比较忙,小编将vue项目实战两个重要模块未及时更新,现在为大家添加上,并添加了项目实战时需要准备的点)

第三章 状态管理库:Pinia

  • 什么是Pinia:Pinia是 Vue的专属的最新状态管理库,是Vuex状态管理工具的替代品
  • 优点:
  1. 提供更加简单的API(去掉了mutation )
  2. 提供符合组合式风格的API(和Vue3新语法统一)
  3. 去掉了modules的概念,每一个store 都是一个独立的模块
  4. 搭配TypeScript一起使用提供可靠的类型推断

3.1 创建空Vue项目并安装Pinia

3.1.1 创建空Vue项目

vue3基础+进阶(一、Vue3项目创建并相比vue2熟悉项目结构)_❆VE❆的博客-CSDN博客

3.1.2 安装Pinia以及持久化工具

Pinia官网:Pinia | Pinia

npm i pinia // 使用npm安装pinia

 不管是vuex还是pinia作为状态管理库,我们都知道它们管理的数据都非持久化的,怎么才能做到呢持久化呢?

  • 常用的方法有:localStorage.setItem(key,value)、localStorage.getItem(key)、localStorage.removeItem()
  • 提出一种新的组件库:pinia-plugin-persistedstate,它使 Pinia Store 的持久化更易配置。

pinia-plugin-persistedstate官网:快速开始 | pinia-plugin-persistedstate

npm i pinia-plugin-persistedstate

3.2 使用pinia

3.1.1 使用案例

  • main.js文件导入下载的pinia相关插件
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 从pinia导入createPinia方法
// 持久化插件 pinia-plugin-persistedstate
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

import App from './App.vue'

const app = createApp(App)
// 将插件添加到pinia实例上,注册持久化插件,使用该插件相当于本地存储,setLocalStore
const pinia = createPinia()
// 当成插件使用
pinia.use(piniaPluginPersistedstate)

app.use(pinia)
app.mount('#app')
  • 创建文件夹stores,实现state、action、getters(这里我们使用组合式api的方法写,统一我 们页面的script的写法)-- 小编用一个项目的store购物车模板跟大家理解state、action、getters的实现
  • 分析:
  1. 根据pinia官网:在pinia中,store 是用 defineStore() 定义,里面有三个参数,第一个参数是store 小仓库的唯一id,第二个参数小编使用的是组合式API的steup函数,该函数定义了一些响应式属性和方法,并且return返回一个带有我们想暴露出去的属性和方法的对象,第三个参数可选,如果配置了pinia-plugin-persistedstate插件,配置{persist: true}将该store小仓库模板持久化。
  2. state 是 store 的数据 (data),通常 ref() 设置
  3. actions 同步异步函数,通常是 ()=>{} 函数的形式
  4. getters 则是计算state数据的,所有使用使用计算属性 computed() 即可实现
// 封装购物车模块
import { defineStore } from "pinia" // pinia里的defineStore函数
import { computed, ref } from "vue" // 获取vue3的组合式api
import { useUserStore } from "./userStore" // 这是小编的另一个仓库暴露的函数
import { insertCartAPI, findNewCartListAPI, delCartAPI } from "@/apis/cart" // api文件

export const useCartStore = defineStore('cart', () => { // 暴露函数
    const userStore = useUserStore() // 另一个仓库的函数数据以及方法赋值
    const isLogin = computed(() => userStore.userInfo.token) // 通过token判断是否登录
    // 1、定义state - cartList
    const cartList = ref([])
    // 获取最新购物车列表
    const updateNewList = async () => {
        const res = await findNewCartListAPI()
        cartList.value = res.result
    }
    // 2、定义action - addCart
    const addCart = async (goods) => { // goods为传的参数:商品对象
        const {skuId, count} = goods

        // 用户已登录 + 未登录
        if (isLogin.value) {
            // 登录之后加入购物车逻辑  调用购物车接口添加购物车操作
            // 先加入购物车
            await insertCartAPI({skuId, count})
            // 然后获取最新的购物车接口
            // 最后赋值
            updateNewList()
        } else {
            // 用户未登录 商品加入购物放在本地
            // 添加购物车操作
            // 已添加过 - count + goods.count
            // 没有添加过 - 直接push
            // 思路:通过匹配传递过来的商品对象中的skuId能不能在cartList中找到,找到了就添加过了
            const item = cartList.value.find((item) => goods.skuId === item.skuId)
            if (item) {
                // 找到了
                item.count += goods.count
            } else {
                // 没有找到
                cartList.value.push(goods)
            }
        }
    }

    // 删除购物车
    const delCart = async (skuId) => {
        if (isLogin.value) {
            // 调用接口实现接口购物车中的删除功能
            await delCartAPI([skuId])
            // 然后获取最新的购物车接口
            // 最后赋值
            updateNewList()
        } else {
            // 思路: 
            // 1、找到删除项的下标值, - splice
            // 2、使用数组的过滤方法 - filter
            const idx = cartList.value.findIndex(item => skuId === item.skuId)
            cartList.value.splice(idx, 1)
        }
    }
    // 清除购物车
    const clearCart = () => {
        cartList.value = []
    }

    // 复选功能
    const singleCheck = (skuId, selected) => {
        // 通过skuId找到要修改的那一项 然后把它的selected修改为传过来的selected值
        const item = cartList.value.find((item) => item.skuId === skuId)
        item.selected = selected
    }
    // 全选功能
    const allCheck = (selected) => {
        // 把cartList中的每一项的selected都设置成当前全选框的状态
        cartList.value.forEach(item => item.selected = selected) 
    }

    // 计算属性 getter
    // 1、总的数量 所有项的count之和
    const allCount = computed(() => {
        return cartList.value.reduce((a, c) => a + c.count, 0)
    })
    // 2、总价 所有项的count * price之和
    const allprice = computed(() => {
        return cartList.value.reduce((a, c) => a + c.count * c.price, 0)
    })
    // 3、已选择数量
    const selectedCount = computed(() => cartList.value.filter(item => item.selected).reduce((a, c) => a + c.count, 0))
    // 4、已选择商品价格合计
    const selectePrice = computed(() => cartList.value.filter(item => item.selected).reduce((a, c) => a + c.count * c.price, 0))

    // 是否全选
    const isAll = computed(()=>{
       return cartList.value.every((item) => item.selected)
    })

    return { // 返回所有的数据以及方法
        cartList,
        addCart,
        delCart,
        singleCheck,
        allCheck,
        clearCart,
        updateNewList,
        allCount,
        allprice,
        selectedCount,
        selectePrice,
        isAll
    }
},
{ // store中的数据state持久化
    persist: true,
})
  • 定义之后页面中获取store仓库,调用里面的数据、获取里面的方法

-- 导入store的属性和方法,并赋值

<script setup>
import { useCartStore } from "@/stores/cartStore"

const cartStore = useCartStore()
</script>

-- 使用store的state属性

// html中直接就能使用store里的cartList值
<li v-for="i in cartStore.cartList" :key="i.id"></li>

-- 使用store的getter方法 --> computed

// html页面中直接使用store里已经通过computed处理好的getter方法
<div class="batch">
    共 {{ cartStore.allCount }} 件商品,已选择 {{ cartStore.selectedCount }} 件,商品合计:    
    <span class="red">¥ {{ cartStore.selectePrice.toFixed(2) }} </span>
</div>

-- 使用store的actions方法 --> 函数

<script setup>
import { useCartStore } from "@/stores/cartStore"

const cartStore = useCartStore()

// 调用cartStore里的action方法allCheck
const allCheck = (selected) => {
    cartStore.allCheck(selected)
}
</script>

<template>
  <div class="xtx-cart-page">
    <el-checkbox :model-value="cartStore.isAll" @change="allCheck"/>
  </div>
</template>

3.1.2 规范问题

  • 命名规则:
  1. 对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
  2. 页面上引用store值时,赋值把'use'去掉,例如:const cartStore = useCartStore()
  • 使用规则:引用时,state与getter的属性,能在html页面直接使用,但是针对于action方法则需要放在script中(原因:规范,同时方便我们与vue类比,便于入门)

3.1.3 简化:结构赋值 

注意:如果直接基于store进行解构赋值,响应式数据(state和getter)会丢失响应式特性,所以我们将使用storeToRefs辅助保持响应式。但是actions方法还是需要直接结构赋值

想要玩好vue3,数据一定要保持住响应式,不然在某些操作上就不会实现我们想要的效果 

<script setup>
import { storeToRefs } from 'pinia'
import { useCartStore } from "@/stores/cartStore"

const cartStore = useCartStore()

// 使用它storeToRefs包裹之后解构保持响应式
// 利用storeToRefs解构state与getter
const { count } = storeToRefs(cartStore)

// 解构方法
const { increment } = cartStore
</script>

第四章 Vue3的Router路由理解(与vue2类比)

4.1 安装

  • 方法一:在使用cli安装vue时手动选择安装router。
  • 方法二:使用npm命令安装,以vue3为例,vue3需要4.0以上版本vue-router
npm install vue-router@4

4.2 路由配置与使用

4.2.1 创建路由组件文件

  • 通常创建 view目录,然后在view目录下创建多个目录,再在目录下创建index.vue文件表示一级路由

4.2.2 创建路由配置文件

  • 新建 router目录,然后在 router目录下通常是新建两个文件:index.js和 routes.js文件 

        -- index.js:创建路由

        -- routes.js:配置路由路径、名字、组件…

1、一个文件如何配置

// 注意小编这里为了写文章就都放到了index.js文件中了
import { createRouter, createWebHashHistory} from "vue-router";
 
const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),
  routes: [ // routes里的配置通常放到routes.js中
    {
      path: "/",
      name: "Home",
      component: () => import("@/views/Home/index.vue"),
    },
  ],
});
 
export default router;

 2、两个文件如何配置

        -- routes.js配置如下: 

const routes = [
    {
      path: "/",
      name: "Home",
      component: () => import("@/views/Home/index.vue"),
    },
    ……
];
 
export default routes

        -- index.js配置如下: 

import {createRouter, createWebHistory} from 'vue-router'
import routes from './routes'
 
const router = createRouter({
    history: createWebHashHistory(import.meta.env.BASE_URL),
    routes
})
 
export default router

4.2.3 配置路由信息

  •  在 main.js中配置路由
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
 
//注意use要在mount之前
createApp(App).use(router).mount('#app')

// --------------即---------------

const app = createApp(App)

app.use(router)

app.mount('#app')

4.2.4 使用路由

  • 使用路由的原则:哪里随着路径的变化而变化,路由就放在哪里
  • 一级路由通常在app中

        -- App.vue中

<template>
  <!-- 一级路由出口组件 -->
  <router-view></router-view>
</template>

4.3 query 传参的方法

4.3.1 query参数传递 

  • 方法描述代码中展示:
<script setup>
import HeaderCart from './HeaderCart.vue';
import { useCategoryStore } from '@/stores/categoryStore'
import { useRouter } from 'vue-router';

const router = useRouter()

// 使用pinia中的数据
const categoryStore = useCategoryStore()

// -- 编程式导航 (): query参数可以使用path也可以使用name
// 方法: push / replace
const to = () => {
  router.push({path: '/category', query: {id: '1005000'}})
}

</script>

<ul class="app-header-nav">
  <li class="home" v-for="item in categoryStore.categoryList" :key="item.id">
    // 声明式导航:两种方法字之一——符串形式,使用?与&连接
    <RouterLink active-class = "active" :to="`/category?id=${item.id}`">{{item.name}}</RouterLink>
  </li>
</ul>
<ul class="app-header-nav">
  <li class="home" v-for="item in categoryStore.categoryList" :key="item.id">
    // 声明式导航:两种方法之一——对象的形式形式,参数:name、path、query
    <RouterLink active-class = "active" :to="{path: '/category', query: {'id': item.id}}">{{item.name}}</RouterLink>
  </li>
</ul>
// 编程式导航
<button @click="to">跳转</button>
{
  path:'category',
  component: () => import('@/views/Category/index.vue')
},

 

4.3.2 query参数获取

// 封装分类数据业务相关代码
import { getTopCategoryAPI } from "@/apis/category";
import { onMounted, ref } from "vue";
import { onBeforeRouteUpdate, useRoute } from "vue-router";


export function useCategory() {
  const categoryData = ref({});
  // 利用vue-router中的函数useRoute()/useRouter()获取当前页路由的参数
  const route = useRoute();
  console.log('route', route)
  const getCategory = async (id = route.query.id) => {
    const res = await getTopCategoryAPI(id);
    categoryData.value = res.result;
  };
  onMounted(() => {
    getCategory();
  });

  // 目标:路由参数变化的时候 可以把分类数据接口重新发送
  // onBeforeRouteUpdate(() => {
  //   console.log('路由变化了')
  //   // 直接这么使用存在的问题:没有使用最新的路由参数请求最新的分类数据
  //   getCategory()
  // })

  // to 到哪个路由 from 从哪个路由来 next 放行
  onBeforeRouteUpdate((to) => {
    getCategory(to.params.id);
  });

  return {
    categoryData
  }
}

 

4.4 params 传参的方法

4.4.1 params参数传递

<script setup>
  import HeaderCart from './HeaderCart.vue';
  import { useCategoryStore } from '@/stores/categoryStore'
  import { useRouter } from 'vue-router';
 
  const router = useRouter()

  // 使用pinia中的数据
  const categoryStore = useCategoryStore()

  // -- 编程式导航 (): query参数使用name,不要会用path
  // 方法: push / replace
  const to = () => {
    router.push({name: 'category', params: {id: '1005000', a: 1}})
  }

</script>


<ul class="app-header-nav">
  <li class="home" v-for="item in categoryStore.categoryList" :key="item.id">
    // 声明式导航: 字符串写法:注意需要与路由配置时的参数对应一致
    <RouterLink active-class = "active" :to="`/category/${item.id}/${1}`">{{item.name}}</RouterLink>
  </li>
</ul>
<ul>
  <li class="home" v-for="item in categoryStore.categoryList" :key="item.id">
    // 声明式导航: 对象写法:注意需要与路由配置时的参数对应一致,注意需要使用name,不要使用path
    <RouterLink active-class = "active" :to="{name: 'category', params: {id: item.id, a: 1}}">{{item.name}}</RouterLink>
  </li>
</ul>
<button @click="to">跳转</button>
{
    name: 'category',
    // 路径参数对应一致
    path:'category/:id/:a',
    component: Category
},

4.4.2 params参数获取 

  • 与query参数获取一样

VueUse | VueUse

第五章 项目准备工作

5.1 jsconfig.json配置别名路径

(注意这些配置项不要写错) 

{
  "compilerOptions" : {
    "baseUrl" : "./",
    "paths" : {
      "@/*":["src/*"]
    }
  }
}

5.2 elementPlus引入 

安装 | Element Plus

5.3 axios安装并简单封装

5.3.1 axios安装

npm i axios/yarn add axios

5.3.2 简单封装

// axios基础的封装
import axios from 'axios'
import 'element-plus/es/components/message/style/css'
import { ElMessage } from "element-plus" // 引用了element-plus组件
import { useUserStore } from '@/stores/userStore' // pinia仓库
import router from '@/router' // 配置的路由

// 创建axios实例
const httpInstance = axios.create({
    baseURL: '基本路径',
    timeout: 5000 // 请求超时
})

// axios请求拦截器
httpInstance.interceptors.request.use(config => {
    // 1、从pinia获取token数据
    const userStore = useUserStore()
    // 2、按照后端的要求拼接token数据
    const token = userStore.userInfo.token
    if (token) {
      config.headers.Authorization = `Bearer ${token}` // 向请求头配置token
    }
    return config
}, e => Promise.reject(e))

// axios响应式拦截器
httpInstance.interceptors.response.use(res => res.data, e => {
  const userStore = useUserStore()
  // 统一错误提示
  ElMessage({
    type: 'warning',
    message: e.response.data.message
  })
  // 401 token失效处理---这里返回的是401状态码
  // 1、清楚本地用户数据
  // 2、跳转到登录页
  if (e.response.status === 401) {
    userStore.clearUserInfo()
    router.push('/login')
  }
  return Promise.reject(e)
})

export default httpInstance

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

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

相关文章

威尔仕2023年的统计数据

威尔仕健身房更新了2023年的统计数据&#xff0c;大家可以猜一猜我是哪一个称号&#xff1f;虽然小伙伴们的健身时长各有不同&#xff0c;有时候在课程中我也会分享自己健身的案例&#xff0c;看似一个简单的增强环路&#xff0c;旁边会有很多的调节环路来限制增强环路的增长&a…

CMA认证和CNAS认可哪个更专业?如何获取CMA、CNAS软件测试报告?

企事业单位或个人在选择软件检测机构时&#xff0c;首先需要考虑的就是该检测机构有无资质认证&#xff0c;这将关系到获取的检测报告的专业性&#xff0c;那么检测行业的CMA认证和CNAS认可哪个更专业呢?软件企业又该如何获取CMA、CNAS软件测试报告? 一、CMA认证是什么?  …

电源管理芯片常见故障有哪些?如何处理这些故障?

电源管理芯片常见故障 电源管理芯片是电子设备的关键器件&#xff0c;负责电能的转换、配电、检测和其他电源管理。在使用过程中&#xff0c;电源芯片也会出现一些故障&#xff0c;常见的故障有&#xff1a; 1. 电源芯片损坏 长时间的使用可能会导致电源管理芯片损坏&#xff0…

Profinet转Modbus使设备互联更简单

在工业自动化领域&#xff0c;为了使设备互联更加简单&#xff0c;可以将Modbus和Profinet相互转换。这样一来&#xff0c;设备之间的互联就变得更加方便和高效。通过Modbus转Profinet网关&#xff08;XD-MDPN100/200&#xff09;&#xff0c;设备之间的通信变得更加灵活和可靠…

斐讯N1盒子刷YYF固件如何清理内存,恢复出厂设置

斐讯N1盒子刷YYF固件&#xff0c;使用一段时间后内存不足。 这时候怎么有效清理内存&#xff1f; 1.不要使用系统自带的恢复出厂设置功能。这个恢复出厂设置后并不能清空内存。 2.使用yyf固件自己的恢复出厂设置功能。

线性代数-第五课,第六课,第七课,第八课

第五课 判断某向量是否可由某向量组线性表示 把向量组组成一个行列式&#xff0c;计算行列式的秩 把所有向量放在一起构成一个行列式&#xff0c;计算行列式的秩 如果两个行列式的秩相等&#xff0c;表示可以线性表示&#xff0c;写答案的格式如下 线性表示&#xff1a;bk…

SAFe大规模敏捷企业级实训

课程简介 SAFe – Scaled Agile Framework是目前全球运用最广泛的大规模敏捷框架&#xff0c;也是成长最快、最被认可、最有价值的规模化敏捷框架&#xff0c;目前全球SAFe认证专业人士已达80万人&#xff0c;福布斯100强的70%都在实施SAFe。本课程是一个2天的 SAFe权威培训课…

HarmonyOS 应用开发学习笔记 ets自定义组件及其引用 @Component自定义组件

Component注解的作用是用来构建自定义组件 Component组件官方文档 自定义组件具有以下特点&#xff1a; 可组合&#xff1a;允许开发者组合使用系统组件、及其属性和方法。 可重用&#xff1a;自定义组件可以被其他组件重用&#xff0c;并作为不同的实例在不同的父组件或容器…

软文推广三大注意事项,媒介盒子分享

软文推广是目前许多企业进行品牌宣传的方式&#xff0c;但是大部分企业在做推广时因为事先不了解踩了不少坑&#xff0c;导致钱也花了人力也投入了&#xff0c;但是成果却不尽人意&#xff0c;今天媒介盒子就来和大家分享软文推广三大注意事项&#xff0c;帮助企业少走弯路&…

Docker实战03|Cgroups

在上一文《Docker实战02&#xff5c;Namespace》中主要介绍了Linux Namespace的基本原理以及实现。相信读完以后可以更加深入的了解Docker关于Namespace的底层实现原理了。 本文继续针对Cgroups技术展开讲解并利用Go语言进行实践。 本系列所有代码均已经开源。关公众号回复「…

数字人可以怎么赋能新消费场景?

近日&#xff0c;在成都交子大道数实共生元宇宙街区&#xff0c;上演了“灯光秀数字人”共舞&#xff0c;用户在线下灯光秀实景中&#xff0c;通过AR技术可以看到数字人“霓裳”在双塔下翩翩起舞&#xff0c;带来精彩演唱&#xff0c;带给用户沉浸式科幻体验&#xff0c;以数字…

git 管理vivado工程, tcl 恢复vivado工程

使用Git进行Vivado版本控制 english youtube 如果不是上边目录结果 , 参考上边目录结构 ,重新建一个工程; 在目录work下产生proj.tcl 修改proj.tcl 主要删除bd wrapper相关的部分; # Import local files from the original project set files [list \[file normalize…

艾思控AQMD6008BLS-TE无刷电机驱动使用笔记(配合STM32)

一、介绍 本驱动器使用的电机电流精确检测技术、有感无刷电机自测速、有感无刷电机转动位置检测、再生电流恒电流制动&#xff08;或称刹车&#xff09;技术和强大的PID调节技术可地控制电机平稳正反转、换向及制动&#xff0c;输出电流实时调控防止过流&#xff0c;精准控制电…

答应我,大学生一定要试试这个啊

我要看看&#xff01;还有谁不知道这个工具的一定要试试啊&#xff01;只需要输入需求&#xff0c;一键生成&#xff0c;几秒就给我写出来一篇&#xff0c;不满意可以重新写&#xff0c;关键每次内容都不一样&#xff0c;完全不用担心会撞啊&#xff01; 写个论文&#xff0c;…

一文解释Linux的内存分页管理

内存是计算机的主存储器。内存为进程开辟出进程空间&#xff0c;让进程在其中保存数据。我将从内存的物理特性出发&#xff0c;深入到内存管理的细节&#xff0c;特别是了解虚拟内存和内存分页的概念。 内存 简单地说&#xff0c;内存就是一个数据货架。内存有一个最小的存储…

vue下载阿里OSS上的图片与视频,纯前端实现,以及纯JS下载图片案例

vue下载阿里OSS上的图片与视频&#xff0c;以及纯JS下载图片案例 1. 简介与日常使用2. Vue下载阿里OSS上的图片与视频3. 调用&#xff08;单个与批量下载均可使用&#xff09;4. 纯JS下载图片案例&#xff0c;Vue里面也可以用 1. 简介与日常使用 参考这篇文章即可&#xff1a;…

pandas.DataFrame() 数据自动写入Excel

DataFrame 表格数据格式 &#xff1b; to_excel 写入Excel数据&#xff1b; read_excel 阅读 Excel数据函数 import pandas as pd#df2 pd.DataFrame({neme: [zhangsan, lisi, 3]}) df1 pd.DataFrame({One: [1, 2, 3],name: [zhangsan, lisi, 3]})#One是列明&#xff0c;123是…

PHP 基础编程 2

文章目录 时间函数dategetdatetime 使用数组实现登录注册和修改密码简单数组增加元素方法修改元素方法删除元素方法 具体实现方法数组序列化数组写入文件判断元素是否在关联数组中&#xff08;登录功能实现&#xff09;实现注册功能实现修改admin用户密码功能 时间函数 时区&am…

ChatGPT论文指南|ChatGPT助力论文论点提炼详细流程!【建议收藏】

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 公众号原文▼▼▼▼&#xff1a; ChatGPT论文指南|ChatGPT助力论文论点提炼详细流程&#xff01;【建议收藏】 上一篇文章中我们了解到如何使用ChatGPT查阅选题相关文献&#xff0c;并进…

离线Vscode 安装完成后 添加到右键菜单

复制下面代码&#xff0c;修改文件后缀名为&#xff1a;reg Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\*\shell\VSCode] "Open with Code" "Icon""D:\\_Porgram_IT\\VsCode\\Code.exe"[HKEY_CLASSES_ROOT\*\shell\VSCode\comman…