Vue3中的常见组件通信之`pinia`

news2024/12/25 9:20:22

Vue3中的常见组件通信之pinia

概述

​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refsparent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。

组件关系传递方式
父传子1. props
2. v-model
3. $refs
4. 默认插槽、具名插槽
子传父1. props
2. 自定义事件
3. v-model
4. $parent
5. 作用域插槽
祖传孙、孙传祖1. $attrs
2. provide、inject
兄弟间、任意组件间1. mitt
2. pinia

props和自定义事件详见:
Vue3中的常见组件通信之props和自定义事件

mitt用法详见:
Vue3中的常见组件通信之mitt

v-model用法详见:
Vue3中的常见组件通信之v-model

$attrs用法详见:
Vue3中的常见组件通信之$attrs

$refs$parent详见:
Vue3中的常见组件通信之$refs$parent

provide和inject详见:
Vue3中的常见组件通信之provide和inject

接下来是pinia。

8.pinia

pinia是一个集中式状态管理工具,是符合直觉的集中式状态管理工具。

8.1准备组件

首先准备3个组件,父组件代码如下:

<template>
    <div class="father">
        <Header/>
        <Content/>
    </div>
</template>

<script setup lang="ts" name="Index">
import Header from './Header.vue';
import Content from './Content.vue';

</script>

<style scoped>
    .father{
        height: 300px;
        width: 800px;
        background-color: rgb(169, 169, 169);
        margin: 5px;
        padding: 0;
    }
</style>

Header组件代码如下:

<template>
    <div class="header">
        <img class="thoto" :src="user.thoto" alt="头像">
        <span>{{ user.name }}</span>
    </div>
</template>

<script setup lang="ts" name="Header">
import {ref,reactive} from 'vue'

let user = reactive({
    id:'m0_63165331',
    name:'m0_63165331',
    thoto:'https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406111305778.jpg'
})
</script>

<style scoped>
    .header{
        height: 50px;
        background-color: #3b818c;
        border-bottom: 1px solid rgb(255, 255, 255);
        overflow: hidden;
        font-size: 0;
        text-align: center;
        line-height: 50px;
    }
    span{
        font-size: 16px;
        vertical-align: middle;
        color: #fff;
    }
    .thoto{
        height: 35px;
        border-radius: 50%;
        vertical-align: middle;
        margin-right: 5px;
    }
</style>

Content组件代码如下:

<template>
    <div class="outer">
        <div class="user">        
            <img class="thoto" :src="user.thoto" alt="头像">  
            <br>
            <div class="user-inf">
                <span>账号:{{ user.id }}</span> 
                <br>
                <span>昵称:{{ user.name }}</span>
                <br>
                <span>性别:{{ user.gender }}</span>
                <br>
                <span>排名:{{ user.rank }}</span> 
                <br>
                <span>粉丝:{{ user.fans }}</span>  
            </div>      
        </div>
        <div class="content">
            <textarea name="msg" >评论内容</textarea>
        </div>
    </div>
</template>

<script setup lang="ts" name="Content">
import {ref,reactive} from 'vue'

let user = reactive({
    id:'m0_63165331',
    name:'m0_63165331',
    gender:'男',
    rank:19102,
    fans:1040,
    thoto:'https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406111305778.jpg'
})
</script>

<style scoped>
    .outer{
        height: 250px;
        overflow: hidden;
    }
    .user{
        height: 240px;
        width: 150px;
        margin: 5px;
        background-color: #c6e6e8;
        text-align: center;
        float: left;
        border-radius: 5px;
        box-shadow: 0 0 5px black;
    }

    .user-inf{
        width: 150px;
        text-align: left;
        padding: 0 20px;
    }

    span{
        font-size: 16px;
        color: #000;
        font-size: 10px;
        font-family: 微软雅黑;
        font-weight: 600;        
    }

    .thoto{
        height: 50px;
        border-radius: 40%;
        margin: 10px;
    }

    .content{
        width:630px;
        height: 240px;
        /* background-color: #c7d2d4; */
        float: right;
        margin: 5px;        
    }
    textarea{
        width:630px;
        height: 240px;
        background-color: #c6e6e8;
        border: none;
        padding: 5px;
        border-radius: 5px;
        box-shadow: 0 0 5px black;
    }
</style>

呈现效果如下:

image-20240615100738260

8.2 搭建pinia环境

第一步先安装pinia

npm indtall pinia

第二步在src/main.ts中引入createPinia并创建pinia,然后再安装pinia插件,如下代码:

import {createApp} from 'vue'
import App from './App.vue'
//1.引入createPinia,用于创建pinia
import {createPinia} from 'pinia'

// 创建应用
const app = createApp(App)

// 2.创建pinia
const pinia = createPinia()

// 3.安装pinia插件
app.use(pinia)

// 挂载应用
app.mount('#app')

此时我们已经创建了pinia环境,在浏览器开发者工具中能看到pinia

image-20240615100028522

8.3存储和读取数据

pinia是一个轻量化的状态管理工具,一般把组件中共用的数据存储在store中,不适合把所有的数据都用pinia来管理。前面创建的例子中user数据是共用的,可以放入到store中。

Store是一个保存:状态业务逻辑 的实体,每个组件都可以读取写入它。

它有三个概念:stategetteraction,相当于组件中的: datacomputedmethods

在src文件夹下新建stoer文件夹,然后在文件夹下新建文件user.ts。这个文件用于存储user相关的数据、逻辑。

在user.ts文件中先//引入defineStore,用于创建store。

//引入defineStore,用于创建store
import {defineStore} from 'pinia'

store的变量名建议以use开头Srore结尾的大驼峰式命名。如下代码创建useUserStore,并暴露。defineStore接收两个参数,第一个参数是id值,官方建议与文件名保持一致,第二个参数有两种写法,第一种是选项式写法,参数是配置对象,第二种是组合式写法,是函数。

如下代码是选项式写法:它有一个state配置项,state必须写成函数,内部return一个对象,对象内部写具体的数据,如下:

export const useUserStore = defineStore('user',{
    //状态
    state() {
        return {
            user:{
                id:'m0_63165331',
                name:'m0_63165331',
                gender:'男',
                rank:19102,
                fans:1040,
                thoto:'https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406111305778.jpg'
            }
        }
    },
})

这样写完就拥有了一个用于存储user相关内容的仓库,接下来需要在组件中引入仓库,引入后可直接调用便可得到对应的store,如下代码:

// 引入对应的useXxxxxStore	
import { useUserStore } from '../store/user';
// 调用useXxxxxStore得到对应的store
const userStore = useUserStore()

那个这个userStore具体是什么,可以在控制台打印输出得到如下内容:

image-20240615135735531

从上面控制台打印的信息可以得到,userStore是个响应式对象,它身上有user对象,还有 s t a t e , state, statestate身上也有user对象,说明有两种方式可以拿到user对象的数据,如下:

console.log(userStore.user)
console.log(userStore.$state.user)

控制台结果如下:

image-20240615140625369

可以看到两种拿数据的方法得到的结果是完全一样的,所以我们使用简单的方式来拿数据,在页面中展示用如下代码:

<div class="user">        
    <img class="thoto" :src="userStore.user.thoto" alt="头像">  
    <br>
    <div class="user-inf">
        <span>账号:{{ userStore.user.id }}</span> 
        <br>
        <span>昵称:{{ userStore.user.name }}</span>
        <br>
        <span>性别:{{ userStore.user.gender }}</span>
        <br>
        <span>排名:{{ userStore.user.rank }}</span> 
        <br>
        <span>粉丝:{{ userStore.user.fans }}</span>  
    </div>      
</div>

运行后结果跟没有用pinia之前是完全一样的,不再附图。

8.4 修改数据

pinia修改数据有三种方式。

**第一种修改方式:**是符合直觉的方式,拿到数据后就直接修改,如下代码,先创建一个方法用来更改粉丝数量:

function addFans(){
    userStore.user.fans += 1
}

然后在组件中添加按钮并绑定事件:

<button @click="addFans">粉丝数量+1</button>

运行后效果如下:

**第二种修改方式:**是批量修改方式,用$path,它只需要把要修改的数据传递即可,如下代码:

function changeInf(){
    userStore.$patch( {
        user : {
            name:'一叶知秋',
            rank:5000,
            fans:10000,
        }
    })
}

添加按钮并绑定事件,如下:

<button @click="changeInf">更改数据</button>

运行效果如下:

**第三种修改方式:**借助pinia的action修改。在user.ts文件中的defineStore第二个参数中增加如下配置项:

//动作
actions:{
    changeRankAddFans(){
        if (this.user.fans<10000){
            this.user.fans += 1000
        };
        if (this.user.rank>10000){
            this.user.rank -= 1000
        }
    }
},

在组件中引入过userStore后可以直接调用,如下代码添加按钮并绑定事件:

<button @click="userStore.changeRankAddFans">粉丝数量+1000,排名往前1000</button>

运行后如下效果:

8.5 getters

pinia中的getters类似计算属性,如下代码所示,在user.ts中添加getters配置项:

getters:{
    changeRank(state){
        if (state.user.rank > 10000){
            return Math.floor(state.user.rank / 10000) + "万+"
        }else{
            return state.user.rank
        }
    }
}

在组件页面中调整显示内容如下:

<span>排名:{{ userStore.changeRank }}</span> 

运行后效果如下,排名超过1万时显示1万+,在1万名以内显示具体数字:

8.6 $subscribe

pinia中的$subscribe可以对pinia仓库中的数据进行监视,与watch类似,如下代码:

userStore.$subscribe(()=>{
    console.log('userStore中的数据发生变化了')
})

$subscribe是一个函数,需要调用,调用的同时要传入一个函数,可以用箭头函数。上面代码运行后,当数据发生变化的时候这句话就会打印,如下图示意:

$subscribe函数传入的函数中可以接收两个参数,第一个参数是数据变化的信息,第二个参数是变化后的数据。如下代码示意:

userStore.$subscribe((mutate,state)=>{
    console.log('userStore中的数据发生变化了')
    console.log(mutate)
    console.log(state)
})

8.7 store组合式写法

前面8.3小节提到过store有两种写法,一种是选项式,一种是组合式,前面演示的均为选项式,下面代码为组合式写法。

export const useUserStore = defineStore('user',()=>{
    let user = reactive({
        id:'m0_63165331',
        name:'m0_63165331',
        gender:'男',
        rank:19102,
        fans:1040,
        thoto:'https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406111305778.jpg'
    })
    
    function changeRankAddFans(){
        if (user.fans<10000){
            user.fans += 1000
        };
        if (user.rank>10000){
            user.rank -= 1000
        }
    }
    
    let changeRank = computed(()=>{
        if (user.rank > 10000){
            return Math.floor(user.rank / 10000) + "万+"
        }else{
            return user.rank
        }
    })

    return {user,changeRankAddFans,changeRank}
})

8.8 小结

pinia是符合直接的vue.js的状态管理工具。

Store是一个保存:状态业务逻辑 的实体,每个组件都可以读取写入它。

它有三个概念:stategetteraction,相当于组件中的: datacomputedmethods

它可以按照选项式风格来编写代码,也可以按照组合式风格来编写代码。

以下是完整代码:

src/main.ts中代码如下

import {createApp} from 'vue'
import App from './App.vue'

//引入createPinia,用于创建pinia
import {createPinia} from 'pinia'

// 创建应用
const app = createApp(App)

// 创建pinia
const pinia = createPinia()

// 安装pinia插件
app.use(pinia)

// 挂载应用
app.mount('#app')

src/store/user.ts中代码如下:

//引入defineStore,用于创建store
import {defineStore} from 'pinia'
import {reactive,computed} from 'vue'

//创建seUserStore并暴露
//选项式写法
// export const useUserStore = defineStore('user',{
//     //状态
//     state() {
//         return {
//             user:{
//                 id:'m0_63165331',
//                 name:'m0_63165331',
//                 gender:'男',
//                 rank:19102,
//                 fans:1040,
//                 thoto:'https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406111305778.jpg'
//             }
//         }
//     },
//     //动作
//     actions:{
//         changeRankAddFans(){
//             if (this.user.fans<10000){
//                 this.user.fans += 1000
//             };
//             if (this.user.rank>10000){
//                 this.user.rank -= 1000
//             }
//         }
//     },
//     //计算
//     getters:{
//         changeRank(state){
//             if (state.user.rank > 10000){
//                 return Math.floor(state.user.rank / 10000) + "万+"
//             }else{
//                 return state.user.rank
//             }
//         }
//     }

// })

//组合式写法
export const useUserStore = defineStore('user',()=>{
    let user = reactive({
        id:'m0_63165331',
        name:'m0_63165331',
        gender:'男',
        rank:19102,
        fans:1040,
        thoto:'https://xyyhxxx.oss-cn-beijing.aliyuncs.com/picGoImg/202406111305778.jpg'
    })
    
    function changeRankAddFans(){
        if (user.fans<10000){
            user.fans += 1000
        };
        if (user.rank>10000){
            user.rank -= 1000
        }
    }
    
    let changeRank = computed(()=>{
        if (user.rank > 10000){
            return Math.floor(user.rank / 10000) + "万+"
        }else{
            return user.rank
        }
    })

    return {user,changeRankAddFans,changeRank}
})

Father组件中代码:

<template>
    <div class="father">
        <Header/>
        <Content/>
    </div>
</template>

<script setup lang="ts" name="Index">
import Header from './Header.vue';
import Content from './Content.vue';

</script>

<style scoped>
    .father{
        height: 300px;
        width: 800px;
        background-color: rgb(169, 169, 169);
        margin: 5px;
        padding: 0;
    }
</style>

Header组件代码:

<template>
    <div class="header">
        <img class="thoto" :src="userStore.user.thoto" alt="头像">
        <span>{{ userStore.user.name }}</span>
    </div>
</template>

<script setup lang="ts" name="Header">
// 引入对应的useXxxxxStore	
import { useUserStore } from '../store/user';
// 调用useXxxxxStore得到对应的store
const userStore = useUserStore()


</script>

<style scoped>
    .header{
        height: 50px;
        background-color: #3b818c;
        border-bottom: 1px solid rgb(255, 255, 255);
        overflow: hidden;
        font-size: 0;
        text-align: center;
        line-height: 50px;
    }
    span{
        font-size: 16px;
        vertical-align: middle;
        color: #fff;
    }
    .thoto{
        height: 35px;
        border-radius: 50%;
        vertical-align: middle;
        margin-right: 5px;
    }
</style>

Content组件:

<template>
    <div class="outer">
        <div class="user">        
            <img class="thoto" :src="userStore.user.thoto" alt="头像">  
            <br>
            <div class="user-inf">
                <span>账号:{{ userStore.user.id }}</span> 
                <br>
                <span>昵称:{{ userStore.user.name }}</span>
                <br>
                <span>性别:{{ userStore.user.gender }}</span>
                <br>
                <span>排名:{{ userStore.changeRank }}</span> 
                <br>
                <span>粉丝:{{ userStore.user.fans }}</span>  
            </div>      
        </div>
        <div class="content">
            <textarea name="msg" >评论内容</textarea>
            <button @click="addFans">粉丝数量+1</button>
            <button @click="changeInf">更改数据</button>
            <button @click="userStore.changeRankAddFans">粉丝数量+1000,排名往前1000</button>
        </div>
    </div>
</template>

<script setup lang="ts" name="Content">
import {ref,reactive,toRefs} from 'vue'
// 引入对应的useXxxxxStore	
import { useUserStore } from '../../store/user';
// 调用useXxxxxStore得到对应的store
const userStore = useUserStore()

userStore.$subscribe((mutate,state)=>{
    console.log('userStore中的数据发生变化了')
    console.log(mutate)
    console.log(state)
})

//修改数据第一种方式
function addFans(){
    userStore.user.fans += 1
}

//修改数据第二种方式
function changeInf(){
    userStore.$patch( {
        user : {
            name:'一叶知秋',
            rank:5000,
            fans:10000,
        }
    })
}

</script>

<style scoped>
    .outer{
        height: 250px;
        overflow: hidden;
    }
    .user{
        height: 240px;
        width: 150px;
        margin: 5px;
        background-color: #c6e6e8;
        text-align: center;
        float: left;
        border-radius: 5px;
        box-shadow: 0 0 5px black;
    }

    .user-inf{
        width: 150px;
        text-align: left;
        padding: 0 20px;
    }

    span{
        font-size: 16px;
        color: #000;
        font-size: 10px;
        font-family: 微软雅黑;
        font-weight: 600;        
    }

    .thoto{
        height: 50px;
        border-radius: 40%;
        margin: 10px;
    }

    .content{
        width:630px;
        height: 240px;
        /* background-color: #c7d2d4; */
        float: right;
        margin: 5px;        
    }
    textarea{
        width:630px;
        height: 200px;
        background-color: #c6e6e8;
        border: none;
        padding: 5px;
        border-radius: 5px;
        box-shadow: 0 0 5px black;
    }
    button{
        background-color: #c6e6e8;
        height: 30px;
        margin-top: 5px;
        margin-right: 10px;
        border-radius: 5px;
        padding: 5px;
        box-shadow: 0 0 5px black;
        border: none;
        transition: box-shadow 0.3s;
    }
    button:hover{
        box-shadow: 0 0 8px rgb(132, 132, 132);
    }
    button:active{
        box-shadow: 0 0 10px rgb(255, 255, 255);
    }
</style>

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

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

相关文章

Aigtek功率放大器参数怎么选型的

功率放大器是电子系统中重要的组成部分&#xff0c;选型合适的功率放大器对系统的性能和可靠性至关重要。本文下面安泰电子将介绍如何选型功率放大器的关键步骤和考虑因素。 首先&#xff0c;确定应用需求。在选型功率放大器之前&#xff0c;确定应用需求是至关重要的第一步。了…

Mathtype与word字号对照+Mathtype与word字号对照

字体大小对照表如下 初号44pt 小初36pt 一号26pt 小一24pt 二号22pt 小二18pt 三号16pt 小三15pt 四号14pt 小四12pt 五号10.5pt 小五9pt 六号7.5pt 小六6.5pt 七号5.5pt 八号5pt 1 保存12pt文件 首选选择第一个公式&#xff0c;将其大小改为12pt 然后依次选择 “预置”—…

Canvas倒计时

Canvas倒计时 前言 用Canvas绘制一个倒计时组件&#xff0c;显示距离新年还有多长时间&#xff0c;精确到秒&#xff0c;该倒计时需要实时更新 基础知识点 JS Date() 创建一个新Date对象的唯一方法是通过new 操作符&#xff0c;例如&#xff1a;let now new Date(); 若将…

华为OD机试 - 文件缓存系统 - 双向链表(Java 2024 D卷 100分)

华为OD机试 2024D卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;D卷C卷A卷B卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测…

自动生成列表,颜色随机 ,定时执行函数,10秒停止执行函数,按钮执行函数

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>颜色列表Color List</title><style>…

介绍并改造一个作用于Anki笔记浏览器的插件

在Anki的笔记浏览器窗口中&#xff0c;作为主体部分的表格在对获取到的笔记进行排序时&#xff0c;最多只能有一个排序字段&#xff0c;在设定笔记的排序字段后&#xff0c;没法将表格中的笔记按其他字段进行排序。要满足这个需求&#xff0c;可以使用Advanced Browser插件&…

【ai】初识pytorch

初识PyTorch 大神的例子运行: 【ai】openai-quickstart 配置pycharm工程 简单例子初识一下Pytorch 好像直接点击下载比较慢? 大神的代码 在这个例子中,首先定义一个线性模型,该模型有一个输入特征和一个输出特征。然后定义一个损失函数和一个优化器,接着生成一些简单的线性…

Spring Cloud Config配置信息自动更新原理解析

我们知道Spring Cloud Config是Spring Cloud提供的配置中心实现工具&#xff0c;我们可以通过它把配置信息存放在Git等第三方配置仓库中。每当Spring Cloud Config客户端启动时&#xff0c;就会发送HTTP请求到服务器端获取配置信息&#xff0c;这点比较好理解。但事实上&#x…

一个示例学习C语言到汇编层面

给出以下代码 #include<stdio.h> int main() {int x 0, y 0, z 0;while (1) {x 0;y 1;do {printf("%d\n", x);z x y;x y;y z;} while (x < 255);}return 0; }我们把这个程序编写成32位程序&#xff0c;然后我们放入IDA中进行分析 .text:0080187…

矩阵乘法的直觉

矩阵乘法是什么意思&#xff1f; 一种常见的观点是矩阵乘法缩放/旋转/倾斜几何平面&#xff1a; NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜…

JavaScript妙笔生花:打造沉浸式中国象棋游戏体验

前言 随着信息技术的飞速发展&#xff0c;Web开发领域也出现了翻天覆地的变化。JavaScript作为前端开发中不可或缺的编程语言&#xff0c;其重要性不言而喻。而当我们谈论到利用JavaScript打造一款沉浸式的中国象棋游戏体验时&#xff0c;我们不仅仅是在开发一个游戏&#xff0…

Web应用安全测试-权限篡改

Web应用安全测试-权限篡改 任意用户密码修改/重置 漏洞描述&#xff1a; 可通过篡改用户名或ID、暴力破解验证码等方式修改/重置任意账户的密码。 测试方法&#xff1a; 密码修改的步骤一般是先校验用户原始密码是否正确&#xff0c;再让用户输入新密码。修改密码机制绕过方式…

【Ubuntu通用压力测试】Ubuntu16.04 CPU压力测试

​ 使用 stress 对CPU进行压力测试 我也是一个ubuntu初学者&#xff0c;分享是Linux的优良美德。写的不好请大佬不要喷&#xff0c;多谢支持。 sudo apt-get update 日常先更新再安装东西不容易出错 sudo apt-get upgrade -y 继续升级一波 sudo apt-get install -y linux-to…

微信分销商城小程序源码系统在线搭建 前后端分离 带完整的安装代码包以及搭建教程

系统概述 本微信分销商城小程序源码系统采用先进的前后端分离架构设计&#xff0c;前端使用Vue.js框架开发&#xff0c;后端则基于Spring Boot构建&#xff0c;确保了系统的高可维护性、扩展性和性能。系统集商品展示、在线交易、会员管理、分销推广、订单处理、数据统计等功能…

redis存储结构

概要 首先&#xff0c;redis是一种"键值对"&#xff08;key-value&#xff09;数据库&#xff0c;也就是说&#xff0c;redis中存储的用户数据都是以key-value的方式存在的&#xff0c;而这些键值对存储于哈希表&#xff0c;这也解释了为什么redis提供的set、lpush、…

vue标签组

先看样式 再看代码 <div v-else class"relative"><n-tabs ref"tabsInstRef" v-model:value"selectValue" class"min-w-3xl myTabs"><n-tab-panev-for"(tab) in songsTags" :key"tab.name" displ…

Java集合框架源码分析:ArrayList

文章目录 一、ArrayList特性二、ArrayList底层数据结构三、ArrayList继承关系1、Serializable标记性接口2、Cloneable标记性接口3、RandomAccess标记性接口4、AbstractList抽象接口 四、ArrayList源码分析1、构造方法2、添加方法3、删除方法4、修改方法5、获取方法6、转换方法7…

数据结构(DS)C语言版:学习笔记(4):线性表

参考教材&#xff1a;数据结构C语言版&#xff08;严蔚敏&#xff0c;吴伟民编著&#xff09; 工具&#xff1a;XMind、幕布、公式编译器 正在备考&#xff0c;结合自身空闲时间&#xff0c;不定时更新&#xff0c;会在里面加入一些真题帮助理解数据结构 目录 2.1线性…

青书学堂 看视频 耍课时

1. 获取课程节点id ( /nynzy/Student/Course/GetStudyRecordAndScore ) 接口地址 2. 把所有的nodeId 保存下来 保存到 old.txt 格式 课程id 与 nodeId 用 | 隔开 3. 然后创建 test.php 注意把 cookie 换成自己的 <?php$oldFilename ./old.txt; $newFilename ./new.…

idea插件开发之在项目右键添加菜单

写在前面 本文看下如何在右键列表中增加菜单。 正戏 首先创建一个Action&#xff0c;要显示的menu选择ProjectViewPopupMenu&#xff0c;如下&#xff1a; action public class CAction extends AnAction {Overridepublic void actionPerformed(AnActionEvent e) { // …