初学vue3, 全是黑盒子,vue3知识点汇总

学习 Vue.js 应该像学习一门编程语言一样,首先要熟练掌握常用的知识,而对于不常用的内容可以简单了解一下。先对整个框架和语言有一个大致的轮廓,然后再逐步补充细节。千万不要像学习算法那样,一开始就钻牛角尖。

前序:

vueAPI的风格分为: 选项式和组合式,vue2中一般用选项式, 所以文章中讲到的api一般都是组合式

vue3官方推荐用基于 Vite 的构建项目,首先安装 node.js, 然后在终端输入
npm create vue@latest,根据提示构建项目。npm installnpm run dev 分别是下载依赖和运行项目

当然你也可以通过vue ui来构建项目

1、初识vue:

1.1、项目结构:

当我们新建一个vue项目时, 整个项目刚开始会有很多.vue, .js, .html .css文件,但真正有用的只有index.html, App.vue和一些配置文件

vue组件包含三个区域, 分别用来写html,js(ts),css 其中stylescoped可以让css样式的作用域限定到当前组件

<template>
</template><script>
</script><style scoped>
</style>

1.2、vue常用函数

createApp():是Vue 3中用来创建一个新的Vue应用实例的方法。它接受一个根组件作为参数,并返回一个应用实例。根组件就是export出去的name字符串

mount(): 是把createApp创建的应用实例挂载到一个容器上。 接受的参数容器可以是一个css的选择器

createApp(App).mount('#app') // App.vue文件中
<div id="app"></div>	//index.html中
我们刚创建的项目中会有上面的两个文件, 实际上就是创建了一个App实列, 通过id选择器把它挂载到一个div上

setup(): 是一个函数, 函数里面可以定义响应式变量、计算属性、方法, 然后把变量, 方法 return 出去, 就可以在该组件的template中使用。 (我们一个组件所用到的函数、变量都写在这里面)

我们每个组件的name、setup、components...都需要export出去。 其中name是这个组件的名字, 当其他组件要用到当前组件的时候就是要<name/>,

如下: 在setup函数中定义了nameclick方法给当前组件的html使用。 代码中的(@用来绑定事件, 包括html所有事件和自定义事件)

<template><h1>{{ age }}</h1> 		<!-- {{ }} 双大括号将 Vue 实例中的数据绑定到 HTML 元素中 --><button @click="handleClick">click</button>
</template><script lang="ts">
export default {name : "App",setup : () => {let age= 10;const handleClick = () => {age = 18;}return {name, handleClick}}
}
</script>

前面讲到setup里面定义的方法,变量等都需要return出去之后 html 中才能使用,下面这个语法糖可以让我们不用一个个写return

setup语法糖: 在<script setup> </script>中写方法、状态的话,不需要把方法或状态return回去, vue会自动帮我们return, 而且也不需要用components注册用到的组件。

ref(): 是一个函数,使用 ref 函数可以创建一个包装过的响应式对象,使其能够在 Vue 组件中进行响应式数据绑定。ref接受的参数是基本类型、数组、对象类型的。(当参数是对象时, ref内部其实是调用的reactive)

reactive(): 使用 reactive函数可以创建一个包装过的响应式对象,reactive接受的参数是对象类型

响应式数据指的是当我们的变量发生变化的时候, 跟这个变量相关的元素就会自动刷新
上面的代码中我们点击button的时候会把age = 18, 但实际上我们页面显示的时候age还是等于10, 因为age不是响应式的变量
所以我们需要用ref创建age变量, let age = ref(10), 这样age发生变化时, 跟age相关的元素也会自动刷新。(需要注意: 在js中使用由ref创建的响应式对象是要加上".value", 比如 age.value;在html中则不需要, 可直接写成age)

toRefstoRef:当我们把一个对象或者变量解构的时候。假设person对象中有name, age const {name, age} = person,那么此时解构出来的的nameage不再具有响应式。为了使解构出来的仍然具有响应式,那么应该用toRefstoRef包括起来。 const {name, age} = toRefs(person).

computed():是基于其他数据的值计算出来属性,并且当这些数据变化时,计算属性的值会自动更新

计算属性是基于它们的依赖进行缓存的,只在其依赖发生变化时才会重新计算,而方法每次调用时都会重新执行。

如下, 如果是基于函数getFullName()计算全名的话当name发生变化是控制台会输出3次1, 如果是用FullNameByComputed的话, 控制台只会输出一个1

<span>{{ getFullName() }}</span><br>
<span>{{ getFullName() }}</span><br>
<span>{{ getFullName() }}</span><br>setup : () => {let firstname = ref('');let lastname = ref('');const getFullName = () => {return firstname.value + lastname.value;}const FullNameByComputed= computed(() => {console.log(1); return firstname.value + lastname.value;});return {firstname, lastname, getFullName, FullNameByComputed}
}

通过上面的computed创建的FullNameByComputed是一个类似ref创建的对象, 在js(script标签)中要访问FullNameByComputed的话需要FullNameByComputed.value
如果需要直接修改value的话需要在创建对象的时候传递get和set方法,如下

const getFullNameComputed = computed({get: ()=> {return firstname.value + "-" + lastname.value;},set: (newName)=> {let name = newName.split('-');firstname.value = name[0];lastname.value = name[1];}});

上面代码中,当我们FullNameByComputed.value的话, vue会自动调用get方法, 当我们FullNameByComputed.value=newName的时候,会自动调用set方法, 并把等号右边的值传递到set参数中

1.3、常用语法糖

v-model: 是 Vue.js 中用于在表单控件(如输入框、复选框、单选按钮等)和组件之间创建双向数据绑定
如下: 我们让username和输入框双向绑定, 当用户在输入框中输入字符时, username 就会变成用户输入的值。其中username需要是响应式的变量

<input v-model="username" type="text">
<p>{{ username }}</p>
let username = ref('');

v-for: 通过 ... in ... 用来遍历数组
如下: 假设我们有一个persons数组, 数组长度是3,那么我们可以通过v-for来生成3个li标签。其中对于遍历生成的标签我们需要通过:key="“给他绑定一个唯一的key, 一般用id。(注意key前面的:, 不写:的话,vue会把person.id当成字符串解析)

<li v-for="person in persons" :key="person.id">{{ person.name }}</li>

v-ifv-else就如他们的字面意思, 判断用的

注意: 上面文章和下面文章中用到的函数需要自己引入,如computedref等等,文章中就不再过多赘述了。

2、路由器router:

2.1、路由的定义与使用:

通过 Vue Router,我们可以轻松地定义路由规则,将不同的 URL 映射到不同的组件,并在这些组件之间切换,通俗的讲就是我们可以让页面在不同的url上显示我们想要显示的组件。

router是路由器的意思, route是路由的意思,我们需要给vue的实例创建一个router, 通过createRouter()函数.

const router = createRouter({history: createWebHistory(),    // 路由器的工作模式, 下面会讲到routes : [{path : "/home",	// url匹配path的时候路由器会渲染这个路由的组件name : "HomeView",	// 当前的路由route的名字component : Person,	// 路由的组件},	// 后面可以继续写多个route, router匹配时会从前往后匹配{},...]
})

使用router:

引入:
我们通过createApp()可以创建一个vue实例, const app = createApp(App), 通过app.use(router)使实例使用router。use(router)的参数是我们上面代码用createRouter()创建的

上面我们创建并在实例中使用了router, 但是我们并没有给router说,我们要在页面的哪个部分渲染组件, 所以我们要在我们想要渲染的位置写上<RouterView/>(一般是在App.vue的template的某个地方)。

最后实现的效果就是, 当url跟我们的某个route匹配时,vue的router就会自动的在我们指定的渲染位置上渲染url对应的组件

渲染模式

渲染模式分为前端渲染和后端渲染, html中可以通过a href标签实现点击跳转url,这是后端渲染。(点击a标签的时候页面会重新加载一下, 感觉不出来的话可以点击F12 选中network, 每次点击时network中会重新加载文件,)

vue中我们可以通过<router-link to="">点击跳转</router-link>,来代替a标签,to相当于href,这就是实现了前端渲染。(当我们点击的时候会发现浏览器并没有重新加载。)(这里不详细讲前后端渲染了)

to的三种写法
<router-link to="">点击跳转</router-link>中的to有三种写法.(to前面加上:, 才能让vue不把后面的内容解析成字符串)

  1. to="/home"
  2. :to="{path : "/home"}"
  3. :to="{name: "HomeView"}"

路由模式

  1. Hash 模式路由使用 URL 的 hash(#)部分来模拟一个完整的 URL,实际 URL 的路径部分始终是 # 符号之前的内容
  2. History 模式利用 HTML5 History API 来管理路由,这使得 URL 看起来像普通的 URL,没有 # 符号。

2.2、路由的传参:

一般用第二种。(useRoute()创建的对象中包含queryparams)

  1. 通过props.query + path
    传递:
    上面我们通过to的第一种写法后面加上?加上我们要传的参数即可(通过&分隔要传不同的参数)。<router-link :to="`/home?name=${name}`">router link</router-link><router-link :to="{ path : '/home', query: { name, } }" > router link </router-link>, 通过这种方式即可把当前组件中的name传递到要路由到的组件中
    接收:
    路由组件通过useRoute()创建对象, 对象的query对象中就存着我们传递的数据const route = useRoute(); console.log(route.query.name)

  2. 通过props.params + name
    前提我们需要修改router的routes的path路径, 通过用:占位。path : "/home/:name"。
    然后可以通过<router-link :to="{ name: 'HomeView', params: { name : '1', } }" > router link </router-link>,或 <router-link :to="`/home/${name}`">router link</router-link> 进行传递
    需要渲染的路由组件中通过route.params.name访问

2.3、路由的props配置:

一般传参用上面2.2的第二种写法就行, 下面这个也是一种传参的写法, 只不过不需要用useRoute

{path : "/home/:name",name : "HomeView",component : Person,props(route) {	// props接收的是当前的路由信息, 里面有path,params,query等等, 你可以输出查看下return route.params;},//  props:true,	// 等价于 return route.params// props(route) {return route.query}},

如上在路由中添加代码中的三种props代码的话,就相当于是在<Person :name="name"/>, 那么我们就可以通过defineProps来解析出路由中要传的name了。(defineProps3.1中会讲, 注意:每种props写法要对应上面路由的传参对应的传递写法)

2.4、编程式路由:

上面我们都是通过router-link标签的to属性实现跳转, router-link标签相当于html的a标签,那么我们只能实现通过点击链接的形式实现跳转, 如果要实现点击button实现跳转,那就可以通过管理路由器实现。(通过路由器就可以实现多种形式的跳转)

通过useRouter()创建一个router路由器,router.push()就可以实现跳转,push中可传递的参数和2.1中 “to的三种写法” 的参数一样

2.4、路由重定向:

通过在route配置中添加下面代码("/"重定向到"/home")

{path : "/",redirect : "/home",
},
{path: '/:pathMatch(.*)',	// 匹配所有路径redirect: '/404',	//重定向到/404},

3、组件传递数据

我们在项目中分别创建Person.vueApp.vue, 其中App.vue中使用<Person/>创建Person组件实例, 即AppPerson的父组件

在一般情况下我们父传子的时候用的是下面讲的第一种1. 通过defineProps子传父的时候用的第二种2. 通过自定义事件

3.1、父组件向子组件传递数据

  1. 通过defineProps

父组件中<Person :person="person" :str="str" />, 前面我们向子组件中传递了personstr变量, 其中=右边的"person""str" 是我们在父组件<script>的setup中定义的两个变量, =左边的是 子组件接受时用到的name, 一般命名和父组件中定义时的变量名相同。(个人习惯)

子组件中const AppProps = defineProps(["person", "str"]), 其中[]中的两个字符串对应父组件中的name, AppProps 是包含personstr的对象, 这样子组件中就可以通过AppProps.person访问

3.2、子组件向父组件传递数据

  1. 通过defineProps
    在上面父向子传的时候,可以让父组件给子组件传递一个get方法, 然后让子组件中用defineProps接收一下这个方法,在合适的时候调用, 把要传的数据放到get方法的参数列表

  2. 通过自定义事件defineEmits(不只局限于子组件向父组件, 任意两个组件之间都可以)
    父组件中定义了get-child-name自定义事件, 给事件绑定了一个函数, 子组件在合适的时机触发get-child-name事件即可

//父组件中
<Person @get-child-name="getChildName" />
const getChildName = (ChildName) => {console.log(ChildName.value)
}//子组件中
const name = ref('child')
const emit = defineEmits()
const sendName = () => {emit('get-child-name', name)
}
  1. 通过defineExpose(可跳过,不常用3!)
    父组件中<Person ref="child_Person" />在子组件的实例上添加上ref属性, 然后在setup中定义const child_Person = ref();,child_Person就是包含子组件暴漏出来的数据的对象(记得ref响应式对象要.value取值)。
    (注意: 用child_Person访问子组件的数据时要写在onMounted函数中, onMounted函数可以确保子组件已经被挂载, 不然可能访问不到)
    子组件中通过let name = 'hh'; let age = 18; defineExpose({name, age});, 将自己要暴漏出去的写在defineExpose

3.3、子组件修改父组件的数据

<script setup></script>如果是在这个中通过defineProps中过去的父组件数据的话, 可以直接修改父组件的数据

3.4 mitt自定义事件管理库

上面讲到的3.2的第二种自定义事件一般用于子组件和父组件, 但对于层级较深的就需要一层一层传递,很麻烦, mitt就可以很好帮我们解决问题

mitt一个js的事件管理库, 一般用于管理自定义事件。(安装指令npm install mitt)

一般在一个js文件中创建一个mitt实例, 在其他要用到自定义事件管理的文件中引入mitter

创建一个新的事件总线实例,返回一个包含 on, off, emit, all 等方法的对象,用于管理事件的订阅和发布。
const mitter = mitt();订阅指定类型的事件,当该类型的事件被触发时,执行指定的处理函数。
mitter.on('eventName', (data) => {console.log('Event received with data:', data);
});取消订阅指定类型的事件,停止执行特定的处理函数。
mitter.off('eventName', handlerFunction);触发指定类型的事件,并传递可选的事件数据给订阅该事件的处理函数。
mitter.emit('eventName', { message: 'Hello, mitt!' });订阅所有类型的事件,当任何类型的事件被触发时执行指定的处理函数。
mitter.all((type, data) => {console.log(`Event ${type} received with data:`, data);
});// 清除所有事件监听器
mitter.all.clear();

4、组件之间共享数据Pinia

对于子组件和父组件之间,我们可以通过上面讲到的方法实现数据共享,但是对于有更深层级的组件,我们就需要集中管理状态的方法。Pinia就可以解决这个问题, 安装命令npm install pinia

4.1、数据的定义

在实例中引入pinia, 跟引入router一样

import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia();
app.use(pinia)

一般来说我们会把要共享的组件的数据的pinia放到一个src文件夹下的store中的js文件中。然后在需要使用的文件中引入js, 生成store

import { defineStore } from 'pinia'
// defineStore接收的第一个参数是这个store的id(自己定义)
export const usePersonStore = defineStore('Person', {state() {return {name: 'hello',	//return 的就是要共享的数据}}
})

如果要使用Person的数据的话就:

import { usePersonStore } from '@/store/Person'
const PersonStore = usePersonStore()	//PersonStore 是一个对象
//PersonStore 中包含的就有name, PersonStore.name或PersonStore.$state.name

4.2、数据的修改

  1. 直接修改
PersonStore.name = 'ld'
  1. 通过$patch修改
PersonStore.$patch({name: 'ld'})
  1. 通过action修改
export const usePersonStore = defineStore('Person', {
// 在action中可以写方法, vue会自动维护一个this, 用来访问当前store中的数据actions: {changeName() {this.name = 'ld'}},state() {return {name: 'yxc'}}
})PersonStore.changeName()	// 

对于PersonStore解构出来的数据跟1.2中讲的一样也是不再具有响应式,我们可以用storeToRefs来解构。(虽然也可以用toRefs,但非常不建议)

4.3、getters

如果我们需要计算和返回基于已有状态(state)的新数据,那么可以在getters中写方法

state() {return {name: 'yxc',age: 18}},getters: {	// vue也会自动维护一个thisdoubleName() {return this.name + this.name}}

4.4、subscribe

subscribe 是用于监听 store 的状态变化的方法。Pinia 提供了一种简单而直观的方式来订阅状态变化

订阅方法:通过 store.$subscribe(callback) 方法来订阅状态变化,callback 接受一个参数 mutation,可以是状态的变化信息或其他相关内容。

取消订阅:订阅方法返回一个取消订阅的函数 unsubscribe(),你可以在不需要继续监听状态变化时调用它来取消订阅。

响应式更新:Pinia 使用 Vue.js 的响应式系统来管理状态,因此任何影响状态的变化都会触发订阅者的回调函数。

PersonStore.$subscribe((mutation, state) => {})

mutation: 一个对象,描述了引起状态变化的 mutation。它包含以下属性:

  • storeId: 发生变化的 store 的 ID。
  • type: 变化的类型,通常是 direct(直接变化)或 patch(通过 patch 变化)。
  • events: 包含变化详情的数组。

state: 变化后的 store 状态。


学到这里, 你就可以用vue写项目了。
犹豫篇幅太长,其他vue中不常用的内容放到下篇文章了

下篇文章地址,待更

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

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

相关文章

Arrays.stream使用方法总结

Arrays.stream使用方法总结 本文介绍Arrays的stream流用法 Arrays.stream使用方法总结对数组简单操作最大值max最小值min平均值average数组长度count数组去重后长度distinct数组排序sorted 对数组复杂操作获得intStream对象匹配allMatch匹配anyMatch过滤filter限制数量limit遍…

AI大模型时代来临:企业如何抢占先机?

AI大模型时代来临:企业如何抢占先机? 2023年,被誉为大模型元年,AI大模型的发展如同一股不可阻挡的潮流,正迅速改变着我们的工作和生活方式。从金融到医疗,从教育到制造业,AI大模型正以其强大的生成能力和智能分析,重塑着行业的未来。 智能化:企业核心能力的转变 企…

世界智能产业博览会开幕 - 天空卫士汽车行业方案入选优秀案例

6月20日&#xff0c;以“智行天下、能动未来”为主题的2024世界智能产业博览会在国家会展中心&#xff08;天津&#xff09;开幕。主席向博览会致贺信并指出&#xff1a;中国高度重视人工智能发展&#xff0c;积极推动互联网、大数据、人工智能和实体经济深度融合&#xff0c;培…

netty系列(三)client启动

client启动&#xff1a; server是在bootstrap.bind的时候启动&#xff0c;而同样&#xff0c;client是在bootstrap.connect时启动&#xff0c;流程都是一样的&#xff1a;创建NioSocketChannel&#xff0c;和workgroup中的一个eventloop绑定起来&#xff0c;然后再执行connect…

[Python学习篇] Python函数

定义函数 语法&#xff1a;使用关键字 def def 函数名(参数): 代码1 代码2 ...... 调用函数 语法&#xff1a; 函数名(参数) 注意&#xff1a;不同的需求&#xff0c;参数可有可无。在Python中&#xff0c;函数必须先定义后使用 示例&#xff1a; # 定义函数 d…

Linux 程序打包

参考文献&#xff1a; Linux(ubuntu)下打包C代码并运行于其他ubuntu上linux C打包程序总结Linux shell 中获取当前目录的方法Linux shell路径变量出现空格时的处理方法 假设编译了一个 cmd 可执行文件&#xff0c;想要把它交给其他人运行。 找到动态库 首先新建一个文件夹 …

csdn如何建立专栏,并且把已发布的文章,放到专栏里

不会在csdn上建立专栏&#xff0c;管理自己的博客&#xff1f; 建立了专栏&#xff0c;不知道该怎么放入文章&#xff1f; 本文将一步步带你解决这些问题。 我是蚊子码农&#xff0c;欢迎各位的点赞、关注和收藏&#xff0c;有了你们的激励&#xff0c;我会带来更好的作品。…

聚焦 Navicat 17 新特性 | 让用户界面交互更丝滑

随着 Navicat 17 的发布&#xff0c;引起业界热烈反响和深入讨论。早前&#xff0c;我们介绍了 Navicat 17 《模型设计创新与优化​​​​​​​》与《查询与配置》的新特性。此外&#xff0c;Navicat 在用户界面交互方面进行了显著优化&#xff0c;新增了一系列实用的功能&…

(javascript)为什么await在forEach中不生效?

转载&#xff1a;为啥await在forEach中不生效&#xff1f;-腾讯云开发者社区-腾讯云 (tencent.com) 两天要写循环遍历请求接口&#xff0c;于是就在forEach中用到了await&#xff0c;但是根本不是我想要的啊&#xff01; 于是各种查&#xff0c;各种搜&#xff0c;终于有点明…

《后端程序猿 · 基于 Lettuce 实现缓存容错策略》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;如需交流&#xff…

机器学习辅助的乙醇浓度检测

目录 1.为什么要机器学习 2. 神经网络一般组成 3.BP神经网络工作过程 4.评价指标 5.实操代码 1.为什么要用机器学习 人工分析大量的谐振模式&#xff0c;建立各种WGM的响应与未知目标之间的关系&#xff0c;是一个很大的挑战。机器学习(ML)能够自行识别全谱的全部特征。作为…

如何在Lazada平台快速出单?测评助力商家突破销量瓶颈

Lazada在短短的几年里已经发展成了东南亚地区最大的在线购物网站之一 &#xff0c;很多商家也想要在这样一个大的跨境平台上发展。那么&#xff0c;对于希望在Lazada平台上大展拳脚的商家而言&#xff0c;出单是否容易呢? ​一、Lazada出单容易吗? Lazada出单的难易程度并非…

漫步5G-A City,一份独属于上海的浪漫

作家亨利詹姆斯曾写道&#xff0c;“城市漫步&#xff0c;让我接触到了这个世界上最好的东西”。 用漫无目的地行走&#xff0c;来体验和观察一座城市&#xff0c;上海凭借丰富多元的文化特质&#xff0c;成为citywalk这种浪漫生活方式的流行地。 无论你是漫步在美术馆、画廊林…

数据抓取技术在视频内容监控与快速读取中的应用

引言 在数字化时代&#xff0c;视频内容的快速读取和监控对于内容提供商来说至关重要。思通数科的OPEN-SPIDER抓取技术为这一需求提供了高效的解决方案。 OPEN-SPIDER技术概述 OPEN-SPIDER是思通数科开发的一种先进的数据抓取技术&#xff0c;它能够&#xff1a; - 高效地从各…

ananconda 和 pip傻傻分不清???

Anaconda 和 pip 都是 Python 编程语言中用于管理包&#xff08;libraries&#xff09;和环境的工具&#xff0c;但它们在功能和设计理念上有所不同。 Anaconda Anaconda 是一个面向科学计算的发行版&#xff0c;包括了 Python 语言和许多常用的科学计算及数据分析库。Anacon…

Stable Diffusion【基础篇】:降噪强度(denoising strength)

提到降噪强度&#xff08;denoising strength&#xff09;&#xff0c;大家一定不会陌生&#xff0c;这个参数是图生图中最关键的参数之一。今天在Stable Diffusion Art网站看到一篇介绍降噪强度&#xff08;denoising strength&#xff09;的文章&#xff08;地址&#xff1a;…

uniapp返回上一页并传递参数,上一页接收参数并刷新数据

因为navigateBack不支持携带参数&#xff0c;所以只能触发一个自定义事件&#xff0c;并传递参数 params 给上一页。 // 触发自定义事件&#xff0c;并返回上一页 uni.$emit(refreshPreviousPage, params); //返回上一页 uni.navigateBack({ delta: 1 }); 在上一页的 onShow …

vcanfd配置与使用

canfd CAN FD (Controller Area Network Flexible Data-rate) 是传统 CAN (Controller Area Network) 的升级版本&#xff0c;旨在满足现代汽车电子系统和工业自动化中对更高数据速率和更大数据负载的需求。以下是对 CAN FD 的详细介绍&#xff1a; CAN 和 CAN FD 的背景 CA…

从hugging face 下模型

支持国内下载hugging face 的东西 下模型权重 model_id 是红色圈复制的 代码 记得设置下载的存储位置 import os from pathlib import Path from huggingface_hub import hf_hub_download from huggingface_hub import snapshot_downloadmodel_id"llava-hf/llava-v1…

C#——MD5 base64加密-base64加密解密

MD5 base64加密 在C#中&#xff0c;MD5是一个不可逆的加密算法&#xff0c;因为它是散列函数&#xff0c;用于创建信息的唯一指纹&#xff08;也称为摘要&#xff09;。不过&#xff0c;可以使用MD5进行加密&#xff0c;然后使用Base64对结果进行编码。但是&#xff0c;请注意…