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

VUE3版本新特性

VUE3版本新特性

  1. VUE3和VUE2的区别
  2. 路由的使用
  3. vite安装项目
  4. 新特性使用

1.VUE3和VUE2的区别

2020年9月18日,Vue.js发布版3.0版本,代号:One Piece 于 2022 年 2 月 7 日星期一成为新的默认版本! Vue3性能更高,初次渲染快55%, 更新渲染快133% 。体积更小 Vue3.0 打包大小减少41%。 同时Vue3可以更好的支持TypeScript。 vue3中文文档:Vue.js : https://cn.vuejs.org/,vue2和vue3的主要区别在于以下几点:1、生命周期函数钩子不同

beforeCreate  -> setup()    开始创建组件之前,创建的是data和method
created       -> setup()
beforeMount   -> onBeforeMount    组件挂载到节点上之前执行的函数。
mounted       -> onMounted    组件挂载完成后执行的函数
beforeUpdate  -> onBeforeUpdate    组件更新之前执行的函数。
updated       -> onUpdated    组件更新完成之后执行的函数。
beforeDestroy -> onBeforeUnmount    组件挂载到节点上之前执行的函数。
destroyed     -> onUnmounted    组件卸载之前执行的函数。
activated     -> onActivated    组件卸载完成后执行的函数
deactivated   -> onDeactivated  在组件切换中老组件消失的时候执行

2、数据双向绑定原理不同

VUE2VUE3
利用ES5的一个APIObject.defineProperty()对数据进行劫持,结合发布者订阅者模式的方式来实现的。使用了ES6的Proxy API对数据代理。

vue3提供的proxy API代理的优势在于:

  • defineProperty只能监听某个属性,不能对全对象监听
  • 可以省去for…in,闭包等内容来提升效率(直接绑定整个对象即可)
  • 可以监听数组,不再单独的对数组做特异性处理。可以检测到数组内部数据的变化。

3、定义变量和方法不同

vue2vue3
在data中定义变量,在methods中创建方法使用一个新的setup方法

vue3提供的setup方法在组件初始化构造的时候触发,使用以下三个步骤建立反应性数据:

  • 从vue引入reactive

  • 使用reactive方法来声明数据为响应性数据

  • 使用setup方法返回响应性数据,从而template可以获取这些响应式数据。

    <script>
    export default {
    setup(){// 数据和方法都写这里,更简洁const user = "username";const met =  ()=>{}
    }
    }
    </script>
    

4、API类型不同

vue2vue3
选项型api(在代码中分割不同属性:data,computed,methods等)组合型api(使用方法进行分隔,显得更加简便整洁)

5、是否支持碎片

vue2vue3
是,即可以拥有多个根节点
<template><div><h1></h1><div><div><h1></h1><div>
</template>

6、父子之间传参不同

vue2vue3
父传子:子组件通过prop接收子传父:子组件中通过$emit向父组件触发一个监听方法,传递一个参数使用setup()中的第二个参数content对象中有emit,只需要在setup()接收第二个参数中使用分解对象法取出emit就可以在setup方法中随意使用了。

7、v-if 和 v-for的优先级

VUE2VUE3
v-for 优先于 v-if 生效v-if 优先于 v-for 生效

2.使用Vite创建项目

在VUE3中使用vite来创建项目而不再使用 vue-cli,初始化项目 ,vite 是新一代前端构建工具,官网地址:https://vitejs.cn,vite的优势如:

  • 轻量快速的热重载(HMR),能实现极速的服务启动。

  • TypeScriptJSXCSS 等支持开箱即用。

  • 真正的按需编译,不再等待整个应用编译完成。注意:Vite 需要 Node.js 版本 >= 12.0.0。【使用nvm安装 node 18.14.2】

在这里插入图片描述

注意:还需要去设置仓库地址: npm config set registry https://registry.npmmirror.com在VUE2中使用npm进行包的管理,在VUE3中pnpm进行包的管理,首先我们需要安装 pnpm

  1. 安装pnpm :

在磁盘上创建一个文件夹,如: vue3-demo,然后进入目录,使用cmd窗口执行命令如下:

npm i pnpm -g
  1. 安装vite : 执行下面命令,按照提示完成项目创建

    pnpm create vite@latest 或者 yarn create vite

1.输入项目名字,默认为vue3-demo2.选择创建的项目类型,选择vue即可3.选择创建的vue项目类型, TypeScript4.启动项目

命令 : pnpm create vite@latest  执行效果如下
![1710845893295](images\1710845893295.png)- 也可以使用 : npm init vite@latest 
3. 安装依赖: `进入到创建好的项目中`执行命令 pnpm i
```shell
pnpm icnpm install
  1. 启动项目
  • 启动命令看 package.json -> scripts { … }

    pnpm dev
    

    访问控制台地址,启动效果如下imagepng然后使用开发工具,导入创建好的项目

3.项目结构认识

├── dist/                                                        //代码编译目录
└── src/├── api/                       // 接口请求目录├── assets/                    // 静态资源目录├── common/                    // 通用类库目录├── components/                // 公共组件目录├── router/                    // 路由配置目录├── store/                     // 状态管理目录├── style/                     // 通用样式目录├── utils/                     // 工具函数目录├── views/                     // 页面组件目录├── App.vue├── main.ts                                        //主ts
├── tests/                         // 单元测试目录
├── index.html                                        //默认首页,入口页面
├── jsconfig.json                  // JavaScript 配置文件
├── vite.config.js                 // Vite 配置文件
└── package.json                                        //依赖管理
└── vite.config.ts

4.route的使用

4.1.安装route路由

官网:https://router.vuejs.org/zh/installation.html

pnpm install vue-router@4

imagepng

4.2.创建页面

在src目录下创建views/order/order.vue 以及 views/user/user.vue 页面文件,内容如下

<script setup lang="ts"></script><template><div>11111111111111</div>
</template><style scoped>
</style>
----
4.3.创建router

在src目录下创建router/index.ts文件,内容如下

import { createRouter, createWebHashHistory } from 'vue-router'const router = createRouter({history: createWebHashHistory(),routes: [{path:"/",name:"home",component:()=>import("../views/User.vue")},{path:"/test",name:"test",component:()=>import("../views/Order.vue"),}],})export default router 
  • createWebHashHistory: hash 模式下使用的是createWebHashHistoryapi 进行配置 VueRouter 的历史模式。使用 hash 模式下会在浏览器网页路由当中使用哈希字符(#)对 url 进行切割并且匹配哈希字符后的字符进行判断路由匹配与跳转处理。

    4.4.在main.js中使用路由
    ...省略...
    

//导入路由import { createApp } from 'vue’import router from ‘./router/index’

//创建appconst app = createApp(App);

//使用路由app.use(router)

//挂载appapp.mount(‘#app’)

#### 4.5.在App.vue文件中指定路由出口
```vue
<template><div><!--     路由出口 ,所有页面都会放到这个里面--><router-view></router-view></div>
</template>
4.6.重启测试

5.vue的核心语法

5.1 简单入门

Vue3向下兼容Vue2语法,且Vue3中的模板中可以没有根标签

<template><div class="person"><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><button @click="changeName">修改名字</button><button @click="changeAge">年龄+1</button><button @click="showTel">点我查看联系方式</button></div>
</template><script lang="ts">export default {name:'App',data() {return {name:'张三',age:18,tel:'13888888888'}},methods:{changeName(){this.name = 'zhang-san'},changeAge(){this.age += 1},showTel(){alert(this.tel)}},}
</script>
5.2 Setup函数

在学习以下知识之前我们先了解一下 options api 和 composition api的区别:vue2中使用的是optionsAPI,来定义一个组件内部的一些属性,如methods、data等等;其缺点往往会在大项目中体现出来,比如一个简单的计数器功能,可能需要在methods内部书写一部分逻辑,在computed内部也书写一部分逻辑,那么问题来了:如果该组件内部有n个这样的小功能,那么此时代码逻辑是十分分散的,并且后期迭代维护面临的问题也是可能修改一个需求需要在不同的属性内部反复查找相关的代码,而compositionAPI的出现就是为了解决这一问题的。

vue3新增的compositionAPI主要就是为了解决API太过于分散的问题,避免一个功能点下的api太过于分散不便于维护,将同一个功能下的api统一放到一个地方,这样一来项目的开发和维护就简便多了。compositionAPI也叫做组合式API,vue3中组合式API的入口就是setup函数; imagepng

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bc0be8211fc54b6c941c036791ba4efe~tplv-k3u1fbpfcp-watermark.image

setupVue3中一个新的配置项,值是一个函数,它是 Composition API “表演的舞台,组件中所用到的:数据、方法、计算属性、监视…等等,均配置在setup中。

特点如下:

  • setup函数返回的对象中的内容,可直接在模板中使用。
  • setup中访问thisundefined
  • setup函数会在beforeCreate之前调用,它是“领先”所有钩子执行的。
5.1.普通写法[不推荐]

​ 通过 export default { setup(){ } } 来定义setup函数 , 这种方式不推荐

<template><div class="person"><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><button @click="changeName">修改名字</button><button @click="changeAge">年龄+1</button><button @click="showTel">点我查看联系方式</button></div>
</template><script lang="ts">export default {name:'Person',setup(){// 数据,原来写在data中(注意:此时的name、age、tel数据都不是响应式数据)let name = '张三'let age = 18let tel = '13888888888'// 方法,原来写在methods中function changeName(){name = 'zhang-san' //注意:此时这么修改name页面是不变化的console.log(name)}function changeAge(){age += 1 //注意:此时这么修改age页面是不变化的console.log(age)}function showTel(){alert(tel)}// 返回一个对象,对象中的内容,模板中可以直接使用return {name,age,tel,changeName,changeAge,showTel}}}
</script>
5.2.语法糖[推荐]
注意:在setup语法中使用 this 会出现unidefined , 在 `setup` 中你应该避免使用 `this`,因为它不会找到组件实例。`setup` 的调用发生在 `data` property、`computed` property 或 `methods` 被解析之前,所以它们无法在 `setup` 中被获取,这也是为了避免setup()和其他选项式API混淆。### 6.数据响应函数
什么是响应式:响应式指的是,把数据绑定当视图,当数据的值发生改变,视图也会跟着重新渲染。
#### 6.1.ref:基础数据响应式函数
VUE3提供了ref函数可以在修改完 数据后自动渲染视图,类似余双向绑定- 在js中通过  import {ref} from "vue"; 来声明 ref函数
- 注意:ref属性在js中要使用.value 取值
```javascript
<template><div class="person"><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><button @click="changeName">修改名字</button><button @click="changeAge">年龄+1</button><button @click="showTel">点我查看联系方式</button></div>
</template><script setup lang="ts" name="Person">import {ref} from 'vue'// name和age是一个RefImpl的实例对象,简称ref对象,它们的value属性是响应式的。let name = ref('张三')let age = ref(18)// tel就是一个普通的字符串,不是响应式的let tel = '13888888888'function changeName(){// JS中操作ref对象时候需要.valuename.value = '李四'console.log(name.value)// 注意:name不是响应式的,name.value是响应式的,所以如下代码并不会引起页面的更新。// name = ref('zhang-san')}function changeAge(){// JS中操作ref对象时候需要.valueage.value += 1 console.log(age.value)}function showTel(){alert(tel)}
</script>

通过ref获取dom对象

<template><input ref="inputRef" :value="refValue"/>
</template><script setup>import {ref} from "vue";//变量名 inputRef 和 dom元素上的ref="inputRef" 一样,就能获取到dom元素let inputRef = ref(null);console.log(inputRef);</script>
6.2.reactive创建:对象类型的响应式数据

对于对象类型可以使用reactive进行响应式函数处理

<template><div class="person"><h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2><h2>游戏列表:</h2><ul><li v-for="g in games" :key="g.id">{{ g.name }}</li></ul><h2>测试:{{obj.a.b.c.d}}</h2><button @click="changeCarPrice">修改汽车价格</button><button @click="changeFirstGame">修改第一游戏</button><button @click="test">测试</button></div>
</template><script lang="ts" setup name="Person">
import { reactive } from 'vue'// 数据
let car = reactive({ brand: '奔驰', price: 100 })
let games = reactive([{ id: 'ahsgdyfa01', name: '英雄联盟' },{ id: 'ahsgdyfa02', name: '王者荣耀' },{ id: 'ahsgdyfa03', name: '原神' }
])
let obj = reactive({a:{b:{c:{d:666}}}
})function changeCarPrice() {car.price += 10
}
function changeFirstGame() {games[0].name = '流星蝴蝶剑'
}
function test(){obj.a.b.c.d = 999
}
</script>

注意:其实ref接收的数据可以是:基本类型对象类型。若ref接收的是对象类型,内部其实也是调用了reactive函数

例如:

<template><div class="person"><h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2><h2>游戏列表:</h2><ul><li v-for="g in games" :key="g.id">{{ g.name }}</li></ul><h2>测试:{{obj.a.b.c.d}}</h2><button @click="changeCarPrice">修改汽车价格</button><button @click="changeFirstGame">修改第一游戏</button><button @click="test">测试</button></div>
</template><script lang="ts" setup name="Person">
import { ref } from 'vue'// 数据
let car = ref({ brand: '奔驰', price: 100 })
let games = ref([{ id: 'ahsgdyfa01', name: '英雄联盟' },{ id: 'ahsgdyfa02', name: '王者荣耀' },{ id: 'ahsgdyfa03', name: '原神' }
])
let obj = ref({a:{b:{c:{d:666}}}
})console.log(car)function changeCarPrice() {car.value.price += 10
}
function changeFirstGame() {games.value[0].name = '流星蝴蝶剑'
}
function test(){obj.value.a.b.c.d = 999
}
</script>

对比:

  1. ref用来定义:基本类型数据对象类型数据
  2. reactive用来定义:对象类型数据
  3. ref创建的变量必须使用.value
  4. reactive重新分配一个新对象,会失去响应式

7.toRef 和 toRefs【了解】

7.1.toRef解析响应式

​ 将一个响应式对象中的每一个属性,转换为ref对象,toRefstoRef功能一致,但toRefs可以批量转换。

<template><div class="person"><h2>姓名:{{person.name}}</h2><h2>年龄:{{person.age}}</h2><h2>性别:{{person.gender}}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changeGender">修改性别</button></div>
</template><script lang="ts" setup name="Person">import {ref,reactive,toRefs,toRef} from 'vue'// 数据let person = reactive({name:'张三', age:18, gender:'男'})// 通过toRefs将person对象中的n个属性批量取出,且依然保持响应式的能力let {name,gender} =  toRefs(person)// 通过toRef将person对象中的gender属性取出,且依然保持响应式的能力let age = toRef(person,'age')// 方法function changeName(){name.value += '~'}function changeAge(){age.value += 1}function changeGender(){gender.value = '女'}
</script>

8.computed计算函数

下面通过计算函数演示2个值相加,需要通过 import {computed} from “vue”; 引入函数

<template><div class="person">姓:<input type="text" v-model="firstName"> <br>名:<input type="text" v-model="lastName"> <br>全名:<span>{{fullName}}</span> <br><button @click="changeFullName">全名改为:li-si</button></div>
</template><script setup lang="ts" name="App">import {ref,computed} from 'vue'let firstName = ref('zhang')let lastName = ref('san')// 计算属性——只读取,不修改/* let fullName = computed(()=>{return firstName.value + '-' + lastName.value}) */// 计算属性——既读取又修改let fullName = computed({// 读取get(){return firstName.value + '-' + lastName.value},// 修改set(val){console.log('有人修改了fullName',val)firstName.value = val.split('-')[0]lastName.value = val.split('-')[1]}})function changeFullName(){fullName.value = 'li-si'} 
</script>

9.watch监听器

watch的作用是用来监听某个值的变化从而出发watch回调。watch可以:

  • 监听单体数据

  • 监听对象

  • 监听对象的某个属性

  • 监听多个数据

    <template><div class="watch"></div><button @click="value++">修改value</button><button @click="persion.age++">修改persion</button>
    </template>
    <script setup>
    

import {reactive, ref, watch} from “vue”;

const value = ref(1111);const persion = reactive({ username:“zs” , age:18})//监听单个值watch(value,()=>{ console.log(value);})//监听对象watch(persion,()=>{ console.log(persion);})

//监听多个,用[]包含多个watch([persion,value],()=>{ console.log(persion,value);});

//监听对象的属性 watch(persion.age,()=>{ console.log(persion);});

watch如果监听对象,可以深度监听(即:对象中又深度嵌套了对象,嵌套的对象值被修改也会被监听到)
### 10.watchEffect监听副作用[了解]
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。watchEffect的作用是只要使用到的数据都会被监听到,无需指定具体监听谁,他包含4个功能- 页面加载,watchEffect的回调就会立即执行
- 只要watchEffect 只要里面使用了任何数据,就会触发回到函数
- onCleanup函数可以清除副作用
- 返回一个stopHandler可以停止监听
```vue
<template><div class="watch_effect"></div><button @click="num++">num++</button><button @click="stopHandler">StopWatch</button>
</template><script setup>import {ref, watchEffect} from "vue";const num = ref(1111);//1.页面加载,初始化立即回执行回调
//2.只要watchEffect 只要里面使用了数据,就会触发回到函数
//3.onCleanup函数可以清除副作用
//4.返回一个stopHandler可以停止监听
/**
watchEffect(()=>{console.log(num.value);
})**/const stopHandler = watchEffect(onCleanup=>{console.log(num.value);onCleanup(()=>{console.log("清除副作用");});
})</script>

11.生命周期方法

因为 setup 是围绕 beforeCreatecreated 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。下表包含如何在 setup () 内部调用生命周期钩子:

选项式 API(VUE2)Hook inside setup
beforeCreateNot needed* 不需要
createdNot needed* 不需要
beforeMountonBeforeMount
挂载之前
mountedonMounted
页面加载完成时执行
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeUnmount
unmountedonUnmounted
页面销毁时执行
errorCapturedonErrorCaptured
renderTrackedonRenderTracked
renderTriggeredonRenderTriggered
activatedonActivated
deactivatedonDeactivated

下面是代码案例

<script setup>
import {onBeforeMount, onBeforeUnmount, onMounted, onUnmounted} from "vue";console.log("初始化")
onMounted(()=>{console.log("onMounted 挂载中...");
})onBeforeMount(()=>{console.log("onBeforeMount 挂载前....");
})
onUnmounted(()=>{console.log("onUnmounted 当销毁..")
})
onBeforeUnmount(()=>{console.log("onBeforeUnmount 当销毁前..")
})
</script>

12.父子组件[重点]

12.1.父传参数给子

第一步:创建一个父组件页面,引入子组件,并传入参数 parent.vue

<template><H1 class="parent_child">父传子</H1><h2>使用子组件传参</h2><child-vue text="传入静态文本"  :num="num" :title="title" :persion="persion"></child-vue>
</template><script setup>//引入子组件取名用驼峰,页面用中划线 <child-vue></child-vue>
import ChildVue from "@/views/parent_child/child.vue";
import {reactive, ref} from "vue";//构建一个响应式对象
const persion = reactive({username:"zs",age:18
})
//定义响应式变量
const title = ref("我是标题");
const num = ref(111);
</script>

第二步:创建一个子组件页面 : child.vue , 通过 defineProps接受父传入的参数

<template><h2>text:{{text}}</h2><h2>num:{{num}}</h2><h2>title:{{title}}</h2><h2>persion:{{persion}}</h2>
</template><script setup>
//通过defineProps来接受父传入过来的参数
const  prop = defineProps({text:String,num:Number,title:String,persion:Object
})
//在js中可以读取父传入过来的参数,但是不能修改
console.log("prop.title" , prop.title)</script>

注意:在子组件中没法修改父转件传入的参数

12.2.子传参给父

子组件给父组件传值,需要通过defineEmits在子组件声明事件方法,然后调用该事件方法传值,父组件需要监听该事件方法取值。第一步:在子组件中准备一个按钮,点击按钮就给父组件传值。然后给按钮绑定一个方法。

<h1>给父组件传参</h1>
<button @click="sendData2Parent">给父组件传参</button>------------------------------------------------------------------------------------------//声明事件
const $emits = defineEmits(["data2parent","事件名","事件名"]);const  sendData2Parent = ()=>{//调用声明的事件$emits('data2parent',"传给父组件的数据");
}
  • const $emits = defineEmits([“data2parent”,“事件2”,“事件3”]); 自定义了三个事件
  • $emits(‘data2parent’,“传给父组件的数据”); 调用自定义的事件

第二步:在父组件中绑定该事件,并调用一个函数来接受值

<child-vue @data2parent="getDataFromChild"  ...></child-vue>const getDataFromChild = (data)=>{console.log("打印数据",data);
}
  • @data2parent=“getDataFromChild” : data2parent对应了子组件中声明的事件,拿到数据后交给getDataFromChild去处理。

    12.3.子暴露

    VUE3提供了 defineExpose 来暴露子组件中的数据和方法在父组件中可以拿到子组件中暴露的数据或者方法。第一步在子组件中暴露数据

    //子暴露
    defineExpose({data:"我是子暴露的数据",sayHi:()=>{return "我是子暴露的方法被调用返回的结果";}
    })
    

    第二步:在父组件接受子暴露的数据

    <child-vueref="childVueRef" ...></child-vue>
    

//用一个响应式变量,接受子暴露的数据const childVueRef = ref(null);onMounted(()=>{ console.log(“子暴露的数据:”,childVueRef.value.data); console.log(“子暴露的方法:”,childVueRef.value.sayHi());})

- ref="childVueRef" : 接受子暴露,把数据绑定给childVueRef注意:因为在父组件的 setup 函数中,声明周期很早,此时子组件还没加载,所以需要在onMounted去调用子暴露的数据和方法才可以拿到结果。### 13.自定义Hooks函数
**hooks就是用来给我们抽取公共代码的**,hooks函数就是通过 use开头的js参数 。 自定义`hook`的优势:复用代码, 让`setup`中的逻辑更清楚易懂。
代码如下:​    useSum.ts```js
import {ref,onMounted} from 'vue'export default function(){let sum = ref(0)const increment = ()=>{sum.value += 1}const decrement = ()=>{sum.value -= 1}onMounted(()=>{increment()})//向外部暴露数据return {sum,increment,decrement}
}        

useDog.ts中内容如下

import {reactive,onMounted} from 'vue'
import axios,{AxiosError} from 'axios'export default function(){let dogList = reactive<string[]>([])// 方法async function getDog(){try {// 发请求let {data} = await axios.get('https://dog.ceo/api/breed/pembroke/images/random')// 维护数据dogList.push(data.message)} catch (error) {// 处理错误const err = <AxiosError>errorconsole.log(err.message)}}// 挂载钩子onMounted(()=>{getDog()})//向外部暴露数据return {dogList,getDog}
}

组件中使用:

<template><h2>当前求和为:{{sum}}</h2><button @click="increment">点我+1</button><button @click="decrement">点我-1</button><hr><img v-for="(u,index) in dogList" :key="index" :src="u"> <span v-show="dogList.isLoading">加载中......</span><br><button @click="getDog">再来一只狗</button>
</template><script lang="ts">import {defineComponent} from 'vue'export default defineComponent({name:'App',})
</script><script setup lang="ts">import useSum from './hooks/useSum'import useDog from './hooks/useDog'let {sum,increment,decrement} = useSum()let {dogList,getDog} = useDog()
</script>

相关文章:

VUE3版本新特性

VUE3版本新特性 VUE3和VUE2的区别路由的使用vite安装项目新特性使用 1.VUE3和VUE2的区别 2020年9月18日&#xff0c;Vue.js发布版3.0版本&#xff0c;代号&#xff1a;One Piece 于 2022 年 2 月 7 日星期一成为新的默认版本! Vue3性能更高,初次渲染快55%, 更新渲染快133% 。…...

【Oracle篇】Oracle数据库坏块处理:rman修复坏块实践与案例分析(第七篇,总共八篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…...

学懂C#编程:从一个简单的例子理解事件处理

在C#中&#xff0c;事件是一种特殊的委托类型&#xff0c;用于在对象上发生某些事情时通知订阅者。事件的处理通常包括定义事件&#xff0c;创建触发事件的条件&#xff0c;以及订阅该事件的事件处理程序。 以下是一个简单的C#事件处理示例&#xff1a; using System;// 定义…...

深入理解指针(2)

4. const 修饰指针 4.1 const修饰变量 变量是可以修改的&#xff0c;如果把变量的地址交给⼀个指针变量&#xff0c;通过指针变量的也可以修改这个变量。 但是如果我们希望⼀个变量加上⼀些限制&#xff0c;不能被修改&#xff0c;怎么做呢&#xff1f;这就是const的作⽤。 …...

C#.Net筑基-集合知识全解

01、集合基础知识 .Net 中提供了一系列的管理对象集合的类型&#xff0c;数组、可变列表、字典等。从类型安全上集合分为两类&#xff0c;泛型集合 和 非泛型集合&#xff0c;传统的非泛型集合存储为Object&#xff0c;需要类型转。而泛型集合提供了更好的性能、编译时类型安全…...

AI PPT生成器,一键在线智能生成PPT工具

PPT作为商业沟通和教育培训中的重要工具&#xff0c;PPT制作对于我们来说并不陌生。但是传统的PPT制作不仅耗时&#xff0c;而且想要做出精美的PPT&#xff0c;需要具备一定的设计技能。下面小编就来和大家分享几款AI PPT工具&#xff0c;只要输入主题&#xff0c;内容就可以在…...

stm32学习笔记---零基础入门介绍2

目录 STM32介绍 STM32家族系列 ARM介绍 ARM内核型号种类 我们学习用的STM32 片上资源/外设&#xff08;Peripheral&#xff09; 命名规则 系统结构 引脚定义 STM32的启动配置 STM32最小系统电路和其他部分电路 最小系统板的实物图 附&#xff1a;安装软件准备 声明…...

搭建取图系统app源码开发,满足广泛应用需求

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 图片已成为信息传递的重要媒介&#xff0c;广泛应用于各个领域。为满足日益增长的图片需求&#xff0c;搭建一款高效的取图系统&#xff0c;可以为用户提供便捷、全面的…...

语音质量评价方法之MOS

引言 在语音增强、语音合成、语音转换、声音转换、语音克隆、语音修复等等领域&#xff0c;常常要对输出的语音进行评价。对语音的质量评价一般关注两个方面&#xff0c;即主观评价和客观评价。主观评价就是人凭借听觉感受对语音进行打分&#xff0c;客观评价比较广泛&#xf…...

gorm简介

【1】ORM: 即Object-Relational Mapping,它的作用是在关系型数据库和对象之间作一个映射&#xff0c;这样我们在具体的操作数据库的时候&#xff0c;就不需要再去和复杂的SQL语句打交道&#xff0c;只要像平时操作对象一样操作它们就可以了。 【2】GORM gorm是go语言的一个orm…...

MySQL:SELECT list is not in GROUP BY clause 报错 解决方案

一、前言 一大早上测试环境&#xff0c;发现测试环境的MySQL报错了。 SELECT list is not in GROUP BY clause and contains nonaggregated column二、解决方案 官方文档中提到&#xff1a; 大致意思&#xff1a; 用于GROUP BY的SQL / 92标准要求满足以下条件&#xff1a; SE…...

IPython的使用技巧

1、解释说明 IPython是一个强大的Python交互式shell&#xff0c;它提供了丰富的功能&#xff0c;如自动补全、历史记录、内置帮助等。IPython使得在命令行下编写和测试Python代码变得更加方便和高效。 2、使用示例 安装IPython&#xff1a; pip install ipython启动IPython…...

Spring Boot 多线程例子

在Spring Boot中&#xff0c;多线程可以通过Java的并发工具来实现。以下是一些常见的多线程实现方法&#xff1a; 1. 使用Async注解和CompletableFuture&#xff1a; 首先&#xff0c;需要在Spring Boot应用的主类上添加EnableAsync注解&#xff0c;以启用异步支持。 java Spr…...

java干货 线程池的分析和使用

文章目录 一、了解线程池1.1 什么是线程池1.2 为什么需要线程池 二、四种线程池的使用2.1 newFixedThreadPool2.2 newCachedThreadPool2.3 newSingleThreadExecutor2.4 newScheduledThreadPool 三、自定义线程池3.1 线程池七大核心参数3.2 线程池内部处理逻辑 一、了解线程池 …...

文本张量入门

张量&#xff0c;英文为Tensor&#xff0c;是机器学习的基本构建模块&#xff0c;是以数字方式表示数据的形式。 张量的基本类型: 创建一个标量&#xff08;0维张量&#xff09;&#xff0c;也就是一个单独的数字 scalar torch.tensor(7) scalar.ndim # 返回张量的维度 0 # …...

js文字如何轮播?

<div class"td-style"> <span class"td-text">内容1内容1内容1内容1内容1内容1</span> </div> css&#xff1a; <style> .td-style { width: 160px; height: 72px; overflow: hidden; white-…...

Linux 五种IO模型

注&#xff1a;还有一种信号驱动IO&#xff0c;使用较少暂不讨论&#xff1b; 一&#xff0c;区分阻塞、非阻塞和同步、异步 看了很多文章对这两组概念解释和对比&#xff0c;说的太复杂了&#xff0c;其实没必要&#xff0c;两句话就能说清楚。 首先&#xff0c;对于读数据rec…...

深度解析响应式异步编程模型

上一篇文章中我们聊了一下线程池,基于线程池的多线程编程是我们在高并发场景下提升系统处理效率的有效手段,但却不是唯一的。今天我们来看一下另一种异步开发的常用手段-响应式编程模型 传统多线程模型的缺陷 多线程模型是目前应用最为广泛的并发编程手段,但凡遇到什么性能…...

一个软件是如何开发出来的呢?

一、前言 如今&#xff0c;AI大爆发的时代&#xff0c;作为一名IT从业者&#xff0c;你是否也想尝试开发一套自己的系统&#xff0c;实现那些看似有可能实现的天马行空的想法&#xff0c;变成一个优秀甚至伟大的产品&#xff0c;甚至带来某个行业的革新&#xff0c;那作为一名…...

宝塔板面有哪些优势

哈喽呀&#xff0c;大家好呀&#xff0c;淼淼又来和大家见面啦&#xff0c;在当今数字化时代&#xff0c;随着云计算和互联网技术的飞速发展&#xff0c;服务器管理成为了许多企业和个人开发者不可或缺的一部分。然而&#xff0c;传统服务器管理方式的复杂性和技术门槛往往令初…...

Mybatis中BaseEntity作用

新建各种对象的时候&#xff0c;一般来说&#xff0c;有几个属性是所有对象共有的&#xff0c;比如说id,is_del&#xff0c;is_enable这些&#xff0c;然后设置一个基础对象&#xff0c;以后新建所有对象的时候都继承它&#xff0c;就省的每次都要写这些共有的属性了...

IDEA2023中使用run Dashboard面板?实现批量运行微服务

1、直接点击Add service--->Run Configuration Type---->Spring Boot 2、这样就出现了run Dashboard面板&#xff0c;可同时运行多个工程模块&#xff0c;shift选中所有启动类组命名&#xff08;Group Configurations&#xff09; 3、启动所有的项目...

分数受限,鱼和熊掌如何兼得?专业or学校,这样选最明智!

文章目录 引言一、专业解析二、名校效应分析三、好专业和好学校的权衡结论个人建议 引言 24年高考帷幕落下&#xff0c;一场新的思考与选择悄然来临。对于每一位高考考生&#xff0c;学校和专业都是开启大学新生活的两个前置必选项。但有时候“鱼与熊掌不可兼得”&#xff0c;…...

CentOS 8.5 - 配置ssh的免密登录

文章目录 生成ssh密钥公钥内容放入服务器 生成ssh密钥 在本地主机安装 ssh工具&#xff0c;并生成公钥、私钥。 # 命令行输入 ssh-keygen -r rsa# 会在当前用户的家目录下生成一个.ssh目录公钥内容放入服务器 将上一步生成的id_rsa.pub公钥的内容复制到远程服务器 # 编辑文…...

反转链表(java精简版)

反转一个单向链表。 public class ReversingLinkedList {static class Node {int val;Node next;public Node(int val) {this.val val;}public boolean hasNext() {return next ! null;}}public static void main(String[] args) {//构造Node head null;Node shift null;for…...

QPair使用详解

QPair使用详解 一、创建和初始化 QPair1.1 QPair默认构造1.2 使用值初始化1.3 QPair拷贝构造 二、访问 QPair 的值2.1 修改 QPair 的值2.2 比较 QPair2.3 使用 qMakePair 辅助函数2.4 使用 QPair 的场景 三、QPair自定结构体3.1 定义自定义结构体3.2 在 QPair 中使用自定义结构…...

C# 语言在AGI 赛道上能做什么

自从2022年11月OpenAI正式对外发布ChatGPT依赖&#xff0c;AGI 这条赛道上就挤满了重量级的选手&#xff0c;各大头部公司纷纷下场布局。原本就在机器学习、深度学习领域占据No.1的Python语言更是继续稳固了自己AI一哥的位置。凭借着Microsoft 和 OpenAI 长期以来一直是紧密相连…...

微信小程序-API 本地存储

一.本地存储-同步API 存储 &#xff1a; wx.setStorageSync 获取&#xff1a;wx.getStorageSync 删除&#xff1a;wx.removeStorageSync 清空&#xff1a;wx.clearStorageSync 代码&#xff1a; save(){//存储wx.setStorageSync(id, 1) wx.setStorageSync(obj, {name:"te…...

TensorFlow音频分类修复

原先传wav格式,后来发现前端生成的wav格式不完整 后端改mp3 其实是mp3和wav都可以接收 前端MP3和wav格式不正确,导致可以接收,但都无法计算时长 该文作废,可能导致音频分类不准确 修复TensorFlow放到生产后报错问题-CSDN博客 依赖 <dependency><groupId>or…...

C#学习系列之ListView垂直滚动

C#学习系列之ListView垂直滚动 前言垂直滚动总结 前言 当ListView中不断增加新内容&#xff0c;经常是纵向滚动。 垂直滚动 这个是关键&#xff1a;<VirtualizingStackPanel/> <ListView.ItemsPanel><ItemsPanelTemplate><VirtualizingStackPanel/>&…...

非模板网站/seo工具网站

一、硬核! 30张图解HTTP常见面试题 在面试过程中。HTTP被提问的概率还是比较高的。小编我授集了5大类HTTP面试常问的题目&#xff0c;同时这5大类题跟HTTP的发展和演变关联性是比较大的&#xff0c;通过问答图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP . HTTP基…...

如何做网站静态页面/中国推广网站

点击上方 "大数据肌肉猿"关注, 星标一起成长后台回复【加群】&#xff0c;进入高质量学习交流群2021年大数据肌肉猿公众号奖励制度大家好&#xff0c;我是峰哥&#xff01;根据2021年大数据肌肉猿公众号奖励制度&#xff0c;本来应该是一个月送一次奖的&#xff0c;但…...

营销型公司网站建设/百度网站排名查询工具

并查集&#xff1a;POJ No1703 Find them, Catch them 题目链接&#xff1a;http://poj.org/problem?id1703 题意&#xff1a;两个坏蛋属于不同的组织&#xff0c;给出两个坏蛋判定是否一个组织。 题解&#xff1a;已知每次输入的两个帮派人员 x, y; 合并 (x, y N), (x N, …...

集团公司网站设计/竞价推广开户

MultiDex解决方法数越界资料Android 开发艺术探索 - 任玉刚配置在模组的gradle中配置android {defaultConfig {// enable multidex supportmultiDexEnabled true}}Android 5.0 以下需要导包dependencies {compile com.android.support:multidex:1.0.1}用法在自定义Application中…...

推广代理平台/移动优化课主讲:夫唯老师

点此下载 第一章 1&#xff0e;典型的编译程序在逻辑功能上由哪几部分组成&#xff1f; 答&#xff1a;编译程序主要由以下几个部分组成&#xff1a;词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。 2. 实现编译程序的主要方…...

自己做短视频网站/磁力猫官网cilimao

matlab GUI 使用技巧 编写一个好的GUI界面注意事项控件命名规范设置控件位置注意查询控件属性其他 bug生成exe文件 matlab GUI 使用技巧 本文首先在Github上更新&#xff0c;同时也会在CSDN和知乎同步更新。 用户界面分成两种&#xff1a;TUI&#xff08;文本交互界面&…...