当前位置: 首页 > news >正文

Vue3父子组件传属性和方法调用Demo

Vue3父子组件传属性和方法调用Demo
  • 说明
  • 目录
  • 父组件给子组件传值和方法
    • 父组件给子组件传值-使用defineProps接受父组件属性值
    • 父组件给子组件传值-使用defineModel接受父组件v-model值
      • 当子组件只需要接收父组件一个v-model值时,写法1如下:
      • 子组件接收单个v-model写法2如下:
      • 当子组件需要接收父组件多个v-model值时,写法如下:
    • 父组件给子组件传方法
  • 子组件调用父组件方法-使用defineEmits调用父组件方法
  • 子组件暴露属性和方法给父组件调用-使用defineExpose暴露子组件属性和方法

说明

这里记录下自己学习Vue3父子组件怎么传值和方法怎么互相调用,防止后面继续踩坑且方便以后直接使用。这里承接自己的博客Vue3+vite优化基础架构(3)— 优化vue-i18n国际化配置这篇博客,在该博客项目的基础上学习Vue3父子组件传值及使用。

官方文档:https://cn.vuejs.org/api/sfc-script-setup.html#defineprops-defineemits

目录

在这里插入图片描述
这里父组件是test-management1文件夹下的index.vue,子组件是test-management1文件夹下的components文件夹的test-child.vue。

父组件给子组件传值和方法

父组件给子组件传属性值,有2种方式:

  1. 第一种方式是在子组件里面使用defineProps来接受父组件那边传过来的属性值。
  2. 第二种方式是在子组件里面使用defineModel来接受父组件那边传过来的v-model值。

父组件给子组件传值-使用defineProps接受父组件属性值

父组件代码如下:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传参,参数为name,age,isOpenEmail,content,score这5个--><TestChild:name="testName":age="testAge":isOpenEmail="testIsOpenEmail":content="testContent":score="testScore"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义name值const testName=ref('张三')//定义age值const testAge=ref(18)//定义isOpenEmail开通邮箱值const testIsOpenEmail=ref(false)//定义content值const testContent=ref(['测试值1','测试值2','测试值3'])//定义score值const testScore=ref({curriculum:"语文",score:60})
</script><style scoped></style>

子组件代码如下:

<template><!--显示父组件传过来的参数值--><div><!--在页面模版里面如果要使用父组件里面穿过来的参数,有2种写法,都能在页面显示出来:--><!--第一种全写:{{props.name}}--><div>name名字为:{{props.name}}</div><!--第二种简写:{{name}},这种简写有个问题,如果你在js中定义了一个相同名的参数,它会优先读取定义的那个参数,不会去读父组件传过来的参数--><div>name名字为:{{name}}</div><div>age年龄为:{{props.age}}</div><div>isOpenEmail是否开通邮箱为:{{props.isOpenEmail}}</div><div>content内容为:{{props.content[0]}}</div><div>score分数为:{{props.score.score}}</div></div>
</template><script setup>import {onMounted} from 'vue'//const name="haha"//页面初始化时执行onMounted(() => {console.info("从父组件那边传过来的值为:")console.info("name:",props.name)console.info("age:",props.age)console.info("isOpenEmail:",props.isOpenEmail)console.info("content:",props.content)console.info("score:",props.score)})//使用defineProps接收父组件穿传过来的参数const props = defineProps({//从父组件那边接收一个String类型的参数,参数名叫name(名字)name: {required:false,//是否必须传该name参数,不写默认为false,true为必须传该参数,false为可以不传该name参数type: String,//参数类型为String字符串default: ''//默认值为空值},//从父组件那边接收一个Number类型的参数,参数名叫age(年龄)age: {type: Number,//参数类型为Number整型default: 0//默认值为0},//从父组件那边接收一个Boolean类型的参数,参数名叫isOpenEmail(是否开通邮箱)isOpenEmail: {type: Boolean,//参数类型为Boolean布尔类型default: false//默认值为false},//从父组件那边接收一个content类型的参数,参数名叫content(内容)content: {type: Array,//参数类型为Array数组类型default: []//默认值为空数组},//从父组件那边接收一个Object类型的参数,参数名叫score(分数)score: {type: Object,//参数类型为Object对象类型default: {}//默认值为空对象}})
</script><style scoped></style>

谷歌浏览器效果显示
在这里插入图片描述
注意事项
1.在页面模版中如果直接使用简写{{name}}这种写法,如果在js中又重新定义了一个name属性,那么会优先使用定义的这个name值,不会使用父组件那边传值过来的name属性值。如下:
在这里插入图片描述
在这里插入图片描述

2.如果子组件接收的参数有required属性而且为true,如果父组件不传该属性的话,那么控制台会出现警告。如下:
在这里插入图片描述
在这里插入图片描述
浏览器结果如下:
在这里插入图片描述

父组件给子组件传值-使用defineModel接受父组件v-model值

当子组件只需要接收父组件一个v-model值时,写法1如下:

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传参,使用v-model形式进行双向绑定--><TestChildv-model="testName"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义name值const testName=ref('张三')</script><style scoped></style>

子组件代码:

<template><!--显示父组件传过来的参数值--><div><el-input v-model="modelValue"></el-input></div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {})//直接使用解构写法来接收父组件那边通过v-model传过来的值,必须使用modelValue来接收属性值const [modelValue]=defineModel()console.info("子组件接收父组件的name值为:",modelValue.value)
</script><style scoped></style>

谷歌浏览器结果如下:
在这里插入图片描述

子组件接收单个v-model写法2如下:
<template><!--显示父组件传过来的参数值--><div><el-input v-model="name"></el-input></div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {console.info("子组件接收父组件的v-model值为:",name.value)})//直接使用defineModel接受父组件通过v-model传过来的值//子组件这边定义一个name属性来接收父组件那边传过来的v-model的值,简写形式如下const name=defineModel()//完整写法/*const name = defineModel({type: String,//字段类型default: ''//默认空值})*///等同于上面的default: ''写法/*const name = defineModel({type: String,//字段类型default: () => {//扩展:将默认属性作为一个方法使用,可以执行一段自定义逻辑,这里直接返回了一个空值,等同于上面写法return ''}})*/</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述

当子组件需要接收父组件多个v-model值时,写法如下:

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传参,使用v-model形式进行双向绑定--><!--绑定多个v-model时,v-model冒号后面为参数名称,后面为参数值--><!--向子组件传参属性为testName,testAge,testIsOpenEmail,testContent,testScore这5个参数--><TestChildv-model:testName="name"v-model:testAge="age"v-model:testIsOpenEmail="isOpenEmail"v-model:testContent="content"v-model:testScore="score"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义name值const name=ref('张三')//定义age值const age=ref(18)//定义isOpenEmail开通邮箱值const isOpenEmail=ref(false)//定义content值const content=ref(['测试值1','测试值2','测试值3'])//定义score值const score=ref({curriculum:"语文",score:60})</script><style scoped></style>

子组件代码:

<template><!--显示父组件传过来的参数值--><div><!--使用父组件那边传过来的name值--><el-input v-model="name"></el-input></div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {console.info("子组件接收父组件的v-model值为:")console.info("name:",name.value)console.info("age:",age.value)console.info("isOpenEmail:",isOpenEmail.value)console.info("content:",content.value)console.info("score:",score.value)})//直接使用defineModel接受父组件通过v-model传过来的值//子组件这边自定义一个name属性来接收父组件那边传过来的v-model(testName)的值,简写形式如下const name=defineModel('testName')//完整写法/*const name = defineModel('testName',{type: String,//字符串类型default: ''//默认值为空})*///子组件这边自定义一个age属性来接收父组件那边传过来的v-model(testAge)的值const age = defineModel('testAge',{type: Number,//整型类型default: 0//默认值为0})//子组件这边自定义一个isOpenEmail属性来接收父组件那边传过来的v-model(testIsOpenEmail)的值const isOpenEmail = defineModel('testIsOpenEmail',{type: Boolean,//布尔类型default: false//默认值为false})//子组件这边自定义一个content属性来接收父组件那边传过来的v-model(testContent)的值const content = defineModel('testContent',{type: Array,//数组类型default: []//默认值为空数组})//子组件这边自定义一个score属性来接收父组件那边传过来的v-model(testScore)的值const score = defineModel('testScore',{type: Object,//对象类型default: {}//默认值为空对象})
</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述

父组件给子组件传方法

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--父组件向子组件传递一个方法,方法名为print--><TestChild:print="testPrint"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//定义print方法const testPrint = () => {console.info("我是父组件的testPrint方法。")}
</script><style scoped></style>

子组件代码:

<template><!--显示父组件传过来的参数值--><div>子组件</div>
</template><script setup>import {onMounted} from 'vue'//页面初始化时执行onMounted(() => {//调用父组件那边传过来的方法props.print()})//使用defineProps接受父组件穿传过来的参数const props = defineProps({//从父组件那边接收一个方法,参数名叫printprint: {type: Function,//参数类型为Function方法类型default: () =>{}//默认一个空方法}})</script><style scoped></style>

谷歌浏览器结果如下:
在这里插入图片描述

子组件调用父组件方法-使用defineEmits调用父组件方法

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--自定义一个testChange方法--><TestChild@testChange="change"/></div>
</template><script setup name="test-management1">import {ref} from "vue"//引入子组件import TestChild from './components/test-child.vue'//父组件定义一个change方法const change = (val) => {console.info("我是父组件的change方法,参数值为:",val)}</script><style scoped></style>

子组件代码:

<template><!--子组件--><div>我是子组件<!--不使用js的话,模版页面直接调用父方法并传递参数写法如下:-->
<!--    <el-button @click="$emit('testChange','2222')"></el-button>--></div>
</template><script setup>//使用defineEmits接收父组件自定义的testChange方法const emit=defineEmits(['testChange'])//子组件调用父组件中的testChange方法,并给该方法传递了一个参数值为2222emit('testChange', '2222')
</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述

子组件暴露属性和方法给父组件调用-使用defineExpose暴露子组件属性和方法

子组件代码:

<template><!--子组件--><div><div>name名字为:{{name}}</div><div>age年龄为:{{age}}</div><div>isOpenEmail是否开通邮箱为:{{isOpenEmail}}</div><div>content内容为:{{content}}</div><div>score分数为:{{score}}</div></div>
</template><script setup>import {ref} from "vue"//定义name值const name=ref('张三')//定义age值const age=ref(18)//定义isOpenEmail开通邮箱值const isOpenEmail=ref(false)//定义content值const content=ref(['测试值1','测试值2','测试值3'])//定义score值const score=ref({curriculum:"语文",score:60})//测试方法const test = (val) => {console.info("我是子组件的test方法,参数值是=",val)}//使用defineExpose暴露属性和方法,暴露了name,age,isOpenEmail,content,score这5个属性值和1个test方法给父组件调用defineExpose({name,age,isOpenEmail,content,score,test})
</script><style scoped></style>

父组件代码:

<template><div>测试管理1页面</div><div><!--在父组件里面使用子组件TestChild--><!--如果子组件里面暴露了属性和方法,子组件必须要加ref才能在父组件中调用子组件里面的属性和方法--><TestChild ref="testChildRef"/></div>
</template><script setup name="test-management1">import {ref,onMounted} from "vue"//引入子组件import TestChild from './components/test-child.vue'//页面初始化加载onMounted(() => {//调用子组件里面的暴露的属性和方法,要用ref去调用console.info("父组件中调用子组件中属性值:")console.info("name值:",testChildRef.value.name)console.info("age值:",testChildRef.value.age)console.info("isOpenEmail值:",testChildRef.value.isOpenEmail)console.info("content值:",testChildRef.value.content)console.info("score值:",testChildRef.value.score)console.info("父组件中调用子组件中方法:")testChildRef.value.test('111')})//子组件ref名称const testChildRef=ref()</script><style scoped></style>

浏览器结果如下:
在这里插入图片描述
注意事项
如果父组件中调用了子组件未暴露的属性或者方法或者不存在的属性和方法,那么浏览器控制台会报错,如下:
在这里插入图片描述
在这里插入图片描述
父子组件的传值和方法互相调用就学习到这里了,后面要是遇到新的方式在扩展。

相关文章:

Vue3父子组件传属性和方法调用Demo

Vue3父子组件传属性和方法调用Demo 说明目录父组件给子组件传值和方法 父组件给子组件传值-使用defineProps接受父组件属性值父组件给子组件传值-使用defineModel接受父组件v-model值 当子组件只需要接收父组件一个v-model值时,写法1如下:子组件接收单个v-model写法2如下:当子…...

aac怎么转为mp3?操作起来很简单的几种aac转mp3的方法

aac怎么转为mp3&#xff1f;aac格式的优势主要体现在音质和压缩效率&#xff0c;尤其是在较低比特率下&#xff0c;能够实现更清晰的音质&#xff0c;这也是为何许多现代设备和应用偏爱aac格式的原因之一。特别是在手机、平板以及智能音响等设备中&#xff0c;aac文件几乎可以无…...

结合mybatis-plus实现Function获取java实体类的属性名

1、工具类 package com.yh.tunnel.util;import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.google.common.base.CaseFormat; import com.yh.tunnel.domain.Plan;import java.lang.invoke.SerializedLambda; import java.lang.reflect.Field; import…...

vue 响应式数据原理

发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 Vue 的响应式数据原理是其核心功能之一&#xff0c;它使得 Vue 应用能够自动响应数据的变化&#xff0c;并在数据变化时自动更新…...

android 计算CRC

<?php /** * 将一个字符按比特位进行反转 eg: 65 (01000001) --> 130(10000010) * param $char * return $char */ function reverseChar($char) { $byte ord($char); $tmp 0; for ($i 0; $i < 8; $i) { if ($byte & (1 << $i)…...

Linux tinyproxy 使用教程

简介 Tinyproxy 是一款轻量级 HTTP 代理服务器&#xff0c;使用最少的资源&#xff0c;非常适合硬件有限的系统。尽管体积小&#xff0c;但它可以处理大量流量&#xff0c;而不会出现明显的性能问题。旨在处理简单的代理任务。它通常用于路由网络流量以保护隐私、缓存或访问受…...

局部规划器设计思路

本文参考知乎文章:如何设计局部规划器 0 引言 局部规划器设计通用方法:生成路径——>寻找最优路径——>后处理优化 1 路径生成 四个问题: ① 如果全局路径中突然出现动态障碍物 ② 如果全局路径非常靠近障碍物 ③ 如果全局路径不容易跟踪(B样条平滑) ④ 如果全局…...

数字图像处理技术期末复习

1. 已知图像的分辨率和深度&#xff0c;怎么求图像的存储空间&#xff08;位&#xff0c;字节&#xff0c;KB&#xff09;&#xff1f; 题目&#xff1a; 已知图像的分辨率和深度&#xff0c;怎么求图像的存储空间&#xff08;位&#xff0c;字节&#xff0c;KB&#xff09;&a…...

UITableView显示数据,增加数据,删除数据及移动数据行

UITableView和html中的table有点类似的&#xff0c;也有header和footer和body&#xff0c;row。下面给出一个demo // // TableViewTestViewController.m // iosstudy2024 // // Created by figo on 2024/12/9. //#import "TableViewTestViewController.h"interfa…...

金智塔科技喜获CCF中国数字金融大会 GraphRAG竞赛二等奖

12月7日&#xff0c;CCF 首届中国数字金融大会GraphRAG竞赛在上海落下帷幕&#xff0c;金智塔科技&#xff08;团队名称&#xff1a;塔塔向前冲&#xff09;从众多参赛队伍中脱颖而出&#xff0c;喜获二等奖。 CCF 首届中国数字金融大会由中国计算机学会主办&#xff0c;中国计…...

方案解读:数字化扩展中如何提升多云应用安全能力?

越来越多企业选择上云&#xff0c;拥抱数字化转型。数据显示&#xff0c;在过去一年中&#xff0c;将应用托管至六种不同环境中的企业比例已经翻倍&#xff0c;达到令人震惊的38%。与此同时&#xff0c;应用和流经其的关键数据已成为日益复杂的网络攻击的首选目标&#xff0c;且…...

“年轻科技旗舰”爱玛A7 Plus正式发布,全国售价4999元

12月18日&#xff0c;备受行业瞩目的“A7上场 一路超神”爱玛旗舰新品发布会在爱玛台州智造工厂盛大举行。 作为年末“压轴产品”的“两轮豪华轿跑”爱玛A7Plus重磅上场&#xff0c;以“快、稳、帅、炫、智、爽”六大超神技惊艳四座&#xff0c;不仅践行了爱玛科技的精品战略&…...

oracle开窗函数笔记、over()笔记

文章目录 开窗函数、组函数、分析函数概念聚合函数和分析函数的区别partition by后面也可以跟多个字段 开窗函数一定要加 聚合函数、或分析函数吗&#xff0c;否则会报错lag()和lead()的用法lag和lead实战开窗函数可以和其他函数一起使用吗? TODO开窗函数中的count(1)是什么意…...

【HarmonyOS】HarmonyOS 和 Flutter混合开发 (一)之鸿蒙Flutter环境安装

【HarmonyOS】HarmonyOS 和 Flutter混合开发 &#xff08;一&#xff09;之鸿蒙Flutter环境安装 一、前言 flutter作为开源适配框架方案&#xff0c;已经在Android&#xff0c;IOS&#xff0c;Web&#xff0c;Window四大平台进行了适配&#xff0c;一套代码&#xff0c;可以同…...

海外招聘丨卢森堡大学—人工智能和机器学习中的 PI 用于图像分析

雇主简介 卢森堡大学立志成为欧洲最受推崇的大学之一&#xff0c;具有鲜明的国际化、多语言和跨学科特色。 她促进研究和教学的相互影响&#xff0c;与国家息息相关&#xff0c;因其在特定领域的研究和教学而闻名于世&#xff0c;并成为当代欧洲高等教育的创新典范。 她的核…...

LeetCode hot100-85

https://leetcode.cn/problems/coin-change/?envTypestudy-plan-v2&envIdtop-100-liked 322. 零钱兑换 已解答 中等 相关标签 相关企业 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。计算并返回可以凑…...

linux 内核数据包处理中的一些坑和建议

1、获取IP头部 iph ip_hdr(skb); struct sk_buff { ...... sk_buff_data_t transport_header; /* Transport layer header */ sk_buff_data_t network_header; /* Network layer header */ sk_buff_data_t mac_header; /* Link layer header */ ...... } 1&#xff0…...

C++ 的衰退复制(decay-copy)

目录 1.什么是衰退复制&#xff08;decay-copy&#xff09; 1.1.推导规则 1.2.LWG issue 929 1.3.想象中的 decay_copy 2.decay-copy 与 auto 2.1.为什么引入衰退复制 2.2. 成为 C 23 的语言特性 3.应用场景 4.总结 1.什么是衰退复制&#xff08;decay-copy&#xff0…...

vue-cli 5接入模块联邦 module federation

vue-cli 5接入模块联邦 module federation 模块联邦概念实现思路配置遇到的问题: 模块联邦概念 模块联邦由webpack 5最先推出的,让应用加载远程的代码模块来实现不同的Web应用共享代码片段.模块联邦分为两个角色,一个是生产者,一个是消费者.生产者暴露代码供消费者消费 (用一个…...

【Rust自学】3.6. 控制流:循环

3.6.0. 写在正文之前 欢迎来到Rust自学的第三章&#xff0c;一共有6个小节&#xff0c;分别是: 变量与可变性数据类型&#xff1a;标量类型数据类型&#xff1a;复合类型函数和注释控制流&#xff1a;if else控制流&#xff1a;循环&#xff08;本文&#xff09; 通过第二章…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...