vue3相关知识点
title: vue_1 date: 2025-01-28 12:00:00 tags:- 前端 categories:- 前端
vue3
Webpack ~ vite
vue3是基于vite创建的
vite 更快一点
一些准备工作
准备后如图所示
插件
Main.ts
// 引入createApp用于创建应用 import {createApp} from 'vue' // 引入App根组件 import App from './App.vue'createApp(App).mount('#app')
App 是根组件,createApp是盆
npm run dev
APP.vue
<template><div class="app"><h1>你好啊!</h1></div> </template><script lang="ts">export default {name:'App' //组件名} </script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;} </style>
简单效果实现
<template><div class="person"><h2>姓名:{% raw %}{{name}}{% endraw %}</h2><h2>年龄:{% raw %}{{age}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button></div> </template><script lang="ts">export default {name:'Person',data(){return {name:'张三',age:18,tel:'13888888888'}},methods:{// 修改姓名changeName(){this.name = 'zhang-san'},// 修改年龄changeAge(){this.age += 1},// 展示联系方式showTel(){alert(this.tel)}}} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;} </style>
这个代码分别是cue组件的三个主要部分,分别对应的模版,脚本和样式
模版部分:也就是trmplate
模版
模版是vue组件的视图部分,定义了组件的html结构
在vue中。模版部分是通过高{% raw %}{ {}}{% endraw %}语法实现数据绑定的,{% raw %}{ {name}}{% endraw %} 会绑定到 data 中的 name 数据。
其中的@click 指令绑定点击事件,点击按钮时执行相应的方法,chageName,changeAge,changeTel
<template><div class="person"><h2>姓名:{% raw %}{{name}}{% endraw %}</h2><h2>年龄:{% raw %}{{age}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button></div> </template>
脚本部分
脚本定义了vue组件的逻辑部分
-
data :组件的状态,即组件中使用的数据
-
Methods:定义组件的方法,这些方法可以在模版中调用来响应用户事件
-
name : 组件的名字,这里是'Person',在vue开发工具中查看到这个组件
<script lang="ts">export default {name:'Person',data(){return {name:'张三',age:18,tel:'13888888888'}},methods:{// 修改姓名changeName(){this.name = 'zhang-san'},// 修改年龄changeAge(){this.age += 1},// 展示联系方式showTel(){alert(this.tel)}}} </script>
这段代码是一个 Vue 组件 的脚本部分,使用的是 TypeScript 语法。它定义了组件的 数据、方法 和 组件的名称
export default {name: 'Person', 这里就是组件的名称data() { ... },methods: { ... } }
export default 是一个 ES6 模块语法,它表示该文件导出的内容是一个对象,并且该对象是默认导出的。这使得 Vue 在加载组件时可以导入这个对象并使用它来渲染组件
样式部分
<style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;} </style>
scoped 属性确保这些样式只作用于当前组件,不会影响到其他组件。这是因为 Vue 会为每个组件自动加上独特的属性选择器(如 .person 只作用于当前组件的 .person 元素)。
app.vue
<template><div class="app"><h1>你好啊!</h1><Person/></div> </template><script lang="ts">import Person from './components/Person.vue'export default {name:'App', //组件名components:{Person} //注册组件} </script><style>.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;} </style>
Export default{}
export default {name: 'App',components: { Person } }
export default 语句使得这个对象成为当前模块的默认导出。这意味着在其他地方使用 import 时,就可以导入这个对象。该对象定义了一个 Vue 组件,组件的名字是 App(通过 name: 'App' 设置)。App 是这个 Vue 组件的名称,它通常是根组件或父组件的名称。
• name 属性指定了当前组件的名字。在 Vue 开发工具中,App 组件将显示为 App,它通常是 Vue 应用的根组件。
• App 组件是父组件,而 Person 组件是它的子组件。
• components 是一个 Vue 组件选项,表示当前组件所使用的子组件。
• 这里通过 components: { Person } 注册了 Person 组件,意味着在 App 组件的模板中可以使用 <Person 标签来引用 Person 组件。
• 由于我们已经通过 import Person from './components/Person.vue' 导入了 Person 组件,所以在 components 中注册它时,只需要直接写 Person 就可以了。
【OptionsAPI 与 CompositionAPI】
Options API 的弊端
Options
类型的 API
,数据、方法、计算属性等,是分散在:data
、methods
、computed
中的,若想新增或者修改一个需求,就需要分别修改:data
、methods
、computed
,不便于维护和复用。
Composition API 的优势
可以用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起。
<template><div class="person"><h2>姓名:{% raw %}{{name}}{% endraw %}</h2><h2>年龄:{% raw %}{{age}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button></div> </template><script lang="ts">export default {name:'Person',beforeCreate(){console.log('beforeCreate')},setup(){console.log(this) //setup中的this是undefined,Vue3在弱化this了// 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据let name = '张三'let age = 18let tel = '13888888888'// 方法function changeName() {name = 'zhang-san' //注意:这样修改name,页面是没有变化的console.log(name) //name确实改了,但name不是响应式的}function changeAge() {age += 1 //注意:这样修改age,页面是没有变化的console.log(age) //age确实改了,但age不是响应式的}function showTel() {alert(tel)}// 将数据、方法交出去,模板中才可以使用return {name,age,tel,changeName,changeAge,showTel}}} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;} </style>
这段代码展示了一个vue3组件的setup()函数的使用,并且展示了一些vue3中的特性
Setup与compositionAPI
-
组件名称
export default {name: 'Person',beforeCreate() {console.log('beforeCreate')},
beforeCreate() 是一个 生命周期钩子,它会在 Vue 实例被创建之前调用。这是 Vue 2 和 Vue 3 中都存在的生命周期钩子,但是在 Vue 3 的 Composition API 中,生命周期钩子的使用方式发生了变化,通常会使用 onBeforeMount 等新的钩子函数(在 setup() 函数中)。
-
setup函数
setup() {console.log(this) // setup中的this是undefined,Vue3在弱化this了
• setup() 函数是 Vue 3 引入的 Composition API 的一部分,目的是简化组件的状态和行为的管理。
• 在 setup() 中,this 是 undefined,这与 Vue 2 中的 this(指向当前组件实例)不同。Vue 3 通过 Composition API 进行了优化,弱化了对 this 的依赖,增强了对组合逻辑的关注。此时,你应该通过返回的对象来访问数据和方法,而不是通过 this。
-
定义数据
let name = '张三' let age = 18 let tel = '13888888888'
-
定义方法
function changeName() {name = 'zhang-san' // 注意:这样修改name,页面是没有变化的console.log(name) // name确实改了,但name不是响应式的 } function changeAge() {age += 1 // 注意:这样修改age,页面是没有变化的console.log(age) // age确实改了,但age不是响应式的 } function showTel() {alert(tel) }
changeName()、changeAge() 和 showTel() 是组件的方法。修改 name 和 age 时,你会发现页面没有发生变化。这是因为 name 和 age 是普通的 JavaScript 变量,而不是响应式数据。
如果你希望这些数据能够自动反映到模板中,应该使用 Vue 3 的响应式 API(如 ref() 或 reactive())。
-
返回数据与方法
return { name, age, tel, changeName, changeAge, showTel }
setup与optionAPI&xompositionAPI
-
模版部分
<template><div class="person"><h2>姓名:{% raw %}{{name}}{% endraw %}</h2><h2>年龄:{% raw %}{{age}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button><hr><h2>测试1:{% raw %}{{a}}{% endraw %}</h2><h2>测试2:{% raw %}{{c}}{% endraw %}</h2><h2>测试3:{% raw %}{{d}}{% endraw %}</h2><button @click="b">测试</button></div> </template>
• name、age:显示 data 或 setup 中的数据。
• a、c、d:展示的是通过 data() 中的数据。
• 还有一些按钮和方法,如 changeName、changeAge 和 showTel。
-
脚本部分
beforeCreate(){console.log('beforeCreate') }
记清楚这个模版
-
data
data(){return {a: 100,c: this.name, // 这里的 `this.name` 会在 `data` 被调用时是 `undefined`,因为 `name` 在 Vue 3 的 `setup()` 中还没有定义。d: 900,age: 90} }
-
methods
methods:{b(){console.log('b')} }
定义了一个方法b,他会在点击按钮时输出b
-
setup
setup(){let name = '张三'let age = 18let tel = '13888888888'function changeName() {name = 'zhang-san'console.log(name)}function changeAge() {age += 1console.log(age)}function showTel() {alert(tel)}return {name, age, tel, changeName, changeAge, showTel} }
在setup()中,你定义了name, age,tel,他们是普通的javascript 变量,因此他们不是响应式的。修改的时候页面不会刷新
相比较下,我更偏向于上一个写法
setup语法糖
<template><div class="person"><h2>姓名:{% raw %}{{name}}{% endraw %}</h2><h2>年龄:{% raw %}{{age}}{% endraw %}</h2><h2>地址:{% raw %}{{address}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button></div> </template><script lang="ts" setup name="Person">// 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据let name = '张三'let age = 18let tel = '13888888888'let address = '北京昌平区宏福苑·宏福科技园'// 方法function changeName() {name = 'zhang-san' //注意:这样修改name,页面是没有变化的console.log(name) //name确实改了,但name不是响应式的}function changeAge() {age += 1 //注意:这样修改age,页面是没有变化的console.log(age) //age确实改了,但age不是响应式的}function showTel() {alert(tel)} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;} </style>
重点是分析脚本
<script lang="ts" setup name="Person">// 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据let name = '张三'let age = 18let tel = '13888888888'let address = '北京昌平区宏福苑·宏福科技园'// 方法function changeName() {name = 'zhang-san' //注意:这样修改name,页面是没有变化的console.log(name) //name确实改了,但name不是响应式的}function changeAge() {age += 1 //注意:这样修改age,页面是没有变化的console.log(age) //age确实改了,但age不是响应式的}function showTel() {alert(tel)} </script>
<script lang="ts" setup name="Person">// 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据
这里发生了改变
1. <script setup:
• setup 是 Vue 3 的 Composition API 的新语法。它简化了组件的声明,并且没有 export default,所有的变量和方法都自动暴露给模板。
• name="Person" 是组件的名称,但是在 <script setup> 中并不需要显式定义,可以直接通过文件名推导。
2. 定义的变量:
• let name = '张三',let age = 18,let tel = '13888888888',let address = '北京昌平区宏福苑·宏福科技园':这些变量是普通的 JavaScript 变量,它们 不是响应式的。如果你修改这些变量,视图不会自动更新。
3. 修改数据的函数:
• changeName 和 changeAge 中直接修改了 name 和 age,但是由于没有使用 Vue 的响应式 API,页面不会随着这些变量的变化而自动重新渲染。
• 这是一个问题,因为 Vue 3 中的响应式系统(通过 ref 或 reactive)才能让数据变化时自动更新视图。
ref创建
哪一个是响应式的,就改变哪一个
<template><div class="person"><h2>姓名:{% raw %}{{name}}{% endraw %}</h2><h2>年龄:{% raw %}{{age}}{% endraw %}</h2><h2>地址:{% raw %}{{address}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button></div> </template><script lang="ts" setup name="Person">import {ref} from 'vue'// 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据let name = ref('张三')let age = ref(18)let tel = '13888888888'let address = '北京昌平区宏福苑·宏福科技园'// 方法function changeName() {name.value = 'zhang-san' // JS中操作ref对象时候需要.valueconsole.log(name.value) }function changeAge() {age.value += 1 console.log(age.value) // JS中操作ref对象时候需要.value}function showTel() {alert(tel)} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;} </style>
这段代码已经解决了你之前提到的 响应式数据 问题,通过使用 ref 将 name 和 age 变成了响应式变量,确保它们的变化能够自动更新到视图中。让我们来逐部分解释这个代码:
ref()用于创建单一响应式数据,而reactive()用于创建对象的响应式数据
import { ref } from 'vue';<script lang="ts" setup name="Person">// 使用 ref() 创建响应式数据let name = ref('张三');let age = ref(18);let tel = ref('13888888888');let address = ref('北京昌平区宏福苑·宏福科技园');// 方法function changeName() {name.value = 'zhang-san'; // 修改时需要通过 `.value` 访问和修改 ref 数据console.log(name.value);}function changeAge() {age.value += 1;console.log(age.value);}function showTel() {alert(tel.value);} </script>
Reactive-对象类型
<template><div class="person"><h2>汽车信息:一辆{% raw %}{{car.brand}}{% endraw %}车,价值{% raw %}{{car.price}}{% endraw %}万</h2><button @click="changePrice">修改汽车的价格</button><br><h2>游戏列表:</h2><ul><li v-for="g in games" :key="g.id">{% raw %}{{g.name}}{% endraw %}</li></ul><button @click="changeFirstGame">修改第一个游戏的名字</button><hr><h2>测试:{% raw %}{{obj.a.b.c}}{% endraw %}</h2><button @click="changeObj">测试</button></div> </template><script lang="ts" setup name="Person">import { reactive } from 'vue'// 定义数据类型type Car = {brand: string;price: number;}type Game = {id: string;name: string;}type Obj = {a: {b: {c: number;}}}// 响应式数据let car = reactive<Car>({ brand: '奔驰', price: 100 })let games = reactive<Game[]>([{ id: 'aysdytfsatr01', name: '王者荣耀' },{ id: 'aysdytfsatr02', name: '原神' },{ id: 'aysdytfsatr03', name: '三国志' }])let obj = reactive<Obj>({a: {b: {c: 666}}})// 方法function changePrice() {car.price += 10console.log(car.price)}function changeFirstGame() {games[0].name = '流星蝴蝶剑'}function changeObj() {obj.a.b.c = 999} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
何时使用 reactive:
1. 对象和数组的响应式数据:
• reactive 主要用于对象和数组类型的响应式处理。因为它会深度递归地将对象的每一个属性都变成响应式的。
• 如果你想让一个复杂的对象(例如包含嵌套对象或数组的对象)自动反应数据变化并更新视图时,就应该使用 reactive。
2. 对象需要嵌套响应式:
• 如果你有多层嵌套的数据结构,并且想要使所有的嵌套属性都成为响应式的,reactive 是非常合适的。比如,一个对象内部有数组,数组内部又有对象等。
3. 非原始数据类型:
• reactive 适用于对象和数组,但不适用于原始类型(例如:number、string、boolean)。如果你只需要处理一个原始数据类型,可以使用 ref。
4. 复杂的数据结构:
• 当你有一个比较复杂的对象,且其中可能包含许多不同类型的属性,reactive 能够方便地使这些属性变得响应式,避免手动为每个属性都使用 ref 或者其他方法来设置响应式。
<template><div class="person"><h2>姓名:{% raw %}{{ person.name }}{% endraw %}</h2><h2>年龄:{% raw %}{{ person.age }}{% endraw %}</h2><h2>地址:{% raw %}{{ person.address }}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="showTel">查看联系方式</button></div> </template><script lang="ts" setup name="Person">import { reactive } from 'vue'// 使用 reactive 来定义响应式对象const person = reactive({name: '张三',age: 18,tel: '13888888888',address: '北京昌平区宏福苑·宏福科技园'})// 修改姓名function changeName() {person.name = 'zhang-san'console.log(person.name) }// 修改年龄function changeAge() {person.age += 1 console.log(person.age) }// 展示联系方式function showTel() {alert(person.tel)} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;} </style>
<template><div class="person"><h2>汽车信息:一辆{% raw %}{{car.brand}}{% endraw %}车,价值{% raw %}{{car.price}}{% endraw %}万</h2><button @click="changeBrand">修改汽车的品牌</button><button @click="changePrice">修改汽车的价格</button><button @click="changeCar">修改汽车</button><hr><h2>当前求和为:{% raw %}{{sum}}{% endraw %}</h2><button @click="changeSum">点我sum+1</button></div> </template><script lang="ts" setup name="Person">import {ref,reactive} from 'vue'// 数据let car = reactive({brand:'奔驰',price:100})let sum = ref(0)// 方法function changeBrand(){car.brand = '宝马'}function changePrice(){car.price += 10}function changeCar(){// car = {brand:'奥拓',price:1} //这么写页面不更新的// car = reactive({brand:'奥拓',price:1}) //这么写页面不更新的// 下面这个写法页面可以更新Object.assign(car,{brand:'奥拓',price:1})}function changeSum(){// sum = ref(9) //这么写页面不更新的sum.value += 1}</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
// 修改汽车(对象赋值的问题)function changeCar() {// 通过 Object.assign 保持响应式Object.assign(car, { brand: '奥拓', price: 1 })}
这里是重点
Torefs && toref
类似于解构
<template><div class="person"><h2>姓名:{% raw %}{{person.name}}{% endraw %}</h2><h2>年龄:{% raw %}{{person.age}}{% endraw %},{% raw %}{{nl}}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button></div> </template><script lang="ts" setup name="Person">import {reactive,toRefs,toRef} from 'vue'// 数据let person = reactive({name:'张三',age:18})// 使用toRefs从person这个响应式对象中,解构出name、age,且name和age依然是响应式的// name和age的值是ref类型,其value值指向的是person.name和person.agelet {name,age} = toRefs(person)let nl = toRef(person,'age')console.log(nl.value)// 方法function changeName(){name.value += '~'console.log(name.value,person.name)}function changeAge(){age.value += 1}</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
1. reactive 和 toRefs 的使用:
• reactive:用于创建响应式对象。你使用 reactive 来创建 person 对象,该对象包含 name 和 age。
• toRefs:将 reactive 对象的属性解构出来,变成单独的响应式 ref。你通过 toRefs(person) 将 person 对象中的 name 和 age 分别解构为 ref 类型的响应式数据。这样,name 和 age 的每个属性都保持响应式。**
• toRef:用来将对象的特定属性转换为 ref。你通过 toRef(person, 'age') 将 person 对象的 age 属性变成一个 ref 类型。
2. changeName 和 changeAge 方法:
• changeName:修改 name 的值,通过 name.value 更新。由于 name 是通过 toRefs 解构出来的,它依然是响应式的,因此当修改 name.value 时,视图会自动更新。
• changeAge:同样修改 age 的值,age 也是一个 ref 类型,通过 age.value 来更新。
computed计算属性
<template><div class="person">姓:<input type="text" v-model="firstName"> <br>名:<input type="text" v-model="lastName"> <br><button @click="changeFullName">将全名改为li-si</button> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br></div> </template><script lang="ts" setup name="Person">import {ref,computed} from 'vue'let firstName = ref('zhang')let lastName = ref('san')// fullName是一个计算属性,且是只读的/* let fullName = computed(()=>{console.log(1)return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value}) */// fullName是一个计算属性,可读可写let fullName = computed({// 当fullName被读取时,get调用get(){return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value},// 当fullName被修改时,set调用,且会收到修改的值set(val){const [str1,str2] = val.split('-')firstName.value = str1lastName.value = str2}})function changeFullName(){fullName.value = 'li-si'} </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
在这里面有一个计算属性,她的作用是基于已有的响应式数据计算新的值,计算属性的返回值会自动缓存,只有当它依赖的数据发生变化时,才会重新计算。
计算属性是只读的,也可以是可读可导的
现在展开对代码进行讲解
-
模版部分
<template><div class="person">姓:<input type="text" v-model="firstName"> <br>名:<input type="text" v-model="lastName"> <br><button @click="changeFullName">将全名改为li-si</button> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br>全名:<span>{% raw %}{{fullName}}{% endraw %}</span> <br></div> </template>
其中那么多全名是为了对齐进行测试
-
脚本部分
<script lang="ts" setup name="Person">import {ref,computed} from 'vue'let firstName = ref('zhang')let lastName = ref('san')// fullName是一个计算属性,且是可读可写的let fullName = computed({// 当fullName被读取时,get调用get(){return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value},// 当fullName被修改时,set调用,且会收到修改的值set(val){const [str1,str2] = val.split('-')firstName.value = str1lastName.value = str2}})function changeFullName(){fullName.value = 'li-si'} </script>
只读
// fullName是一个计算属性,且是只读的/* let fullName = computed(()=>{console.log(1)return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value}) */
可读可写
// fullName是一个计算属性,可读可写let fullName = computed({// 当fullName被读取时,get调用get(){return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' + lastName.value},// 当fullName被修改时,set调用,且会收到修改的值set(val){const [str1,str2] = val.split('-')firstName.value = str1lastName.value = str2}})
2. computed:
• computed 是 Vue 3 中的 计算属性,它会根据其他响应式数据的变化动态计算一个值,并且当相关数据改变时,计算属性会自动更新。
• fullName 是一个 可读可写的计算属性,通过 get 和 set 方法来控制:
• get():当 fullName 被读取时,它会拼接 firstName 和 lastName,并且确保 firstName 的首字母大写。
• set(val):当 fullName 被修改时,set 会接收到新的值,并将其拆分为 firstName 和 lastName,更新这两个响应式变量。
3. changeFullName 方法:
• 当点击按钮时,会调用 changeFullName 方法,并设置 fullName 的值为 'li-si'。由于 fullName 是计算属性,这会触发 set 方法,从而更新 firstName 和 lastName 的值为 'li' 和 'si'。
watch监视
情况一
<template><div class="person"><h1>情况一:监视【ref】定义的【基本类型】数据</h1><h2>当前求和为:{% raw %}{{sum}}{% endraw %}</h2><button @click="changeSum">点我sum+1</button></div> </template><script lang="ts" setup name="Person">import {ref,watch} from 'vue'// 数据let sum = ref(0)// 方法function changeSum(){sum.value += 1}// 监视,情况一:监视【ref】定义的【基本类型】数据const stopWatch = watch(sum,(newValue,oldValue)=>{console.log('sum变化了',newValue,oldValue)if(newValue >= 10){stopWatch()}}) </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
<script lang="ts" setup name="Person">import { ref, watch } from 'vue'// 数据let sum = ref(0)// 方法function changeSum() {sum.value += 1}// 监视,情况一:监视【ref】定义的【基本类型】数据const stopWatch = watch(sum, (newValue, oldValue) => {console.log('sum变化了', newValue, oldValue)if (newValue >= 10) {stopWatch() // 停止监听}}) </script>
watch的基本语法
watch(source, callback, options)
• source:要监视的数据源(可以是一个响应式对象、ref 等)。
• callback:数据变化时调用的回调函数,它会接收到新值和旧值。
• options:可选参数,允许你配置 watch 的行为。
在你的例子中,watch 监视了 sum 的变化,每当 sum 发生变化时,回调函数就会执行,打印出新旧值。如果新值大于或等于 10,就停止监视。
<template><div class="person"><h1>情况二:监视【ref】定义的【对象类型】数据</h1><h2>姓名:{% raw %}{{ person.name }}{% endraw %}</h2><h2>年龄:{% raw %}{{ person.age }}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button></div> </template><script lang="ts" setup name="Person">import {ref,watch} from 'vue'// 数据let person = ref({name:'张三',age:18})// 方法function changeName(){person.value.name += '~'}function changeAge(){person.value.age += 1}function changePerson(){person.value = {name:'李四',age:90}}/* 监视,情况一:监视【ref】定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视watch的第一个参数是:被监视的数据watch的第二个参数是:监视的回调watch的第三个参数是:配置对象(deep、immediate等等.....) */watch(person,(newValue,oldValue)=>{console.log('person变化了',newValue,oldValue)},{deep:true})</script> <style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
2. watch 监视对象变化:
• watch 是 Vue 3 提供的 API,用来监听响应式数据(如 ref 或 reactive)的变化。当监视的数据变化时,watch 的回调函数会被触发。
你在代码中通过 watch(person, ...) 来监听 person 对象的变化。watch 会接收到两个参数:
• newValue:person 变化后的新值。
• oldValue:person 变化前的旧值。
• deep: true:由于 watch 默认只监视对象的引用变化,如果你需要监视对象内部属性的变化(即对象内部的数据变化),需要设置 { deep: true },这样 Vue 会递归地监视对象内部的每个属性变化。
• 深度监视:
• deep 是 watch 的一个选项,它使得 Vue 能够监听 对象属性的变化。当对象的嵌套属性发生变化时,watch 的回调也会被触发。
• 如果没有开启深度监视,那么只有对象的引用变化(如直接替换整个对象)才会触发回调。如果只是修改对象的某个属性,默认不会触发回调。
3. person.value = { name: '李四', age: 90 }:
• 在 changePerson 方法中,直接给 person 赋值一个新的对象,这会改变 person 的引用,从而触发 watch 监听的回调。
情况3
<template><div class="person"><h1>情况三:监视【reactive】定义的【对象类型】数据</h1><h2>姓名:{% raw %}{{ person.name }}{% endraw %}</h2><h2>年龄:{% raw %}{{ person.age }}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changePerson">修改整个人</button><hr><h2>测试:{% raw %}{{obj.a.b.c}}{% endraw %}</h2><button @click="test">修改obj.a.b.c</button></div> </template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18})let obj = reactive({a:{b:{c:666}}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changePerson(){Object.assign(person,{name:'李四',age:80})}function test(){obj.a.b.c = 888}// 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的watch(person,(newValue,oldValue)=>{console.log('person变化了',newValue,oldValue)})watch(obj,(newValue,oldValue)=>{console.log('Obj变化了',newValue,oldValue)})</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
情况四
<template><div class="person"><h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1><h2>姓名:{% raw %}{{ person.name }}{% endraw %}</h2><h2>年龄:{% raw %}{{ person.age }}{% endraw %}</h2><h2>汽车:{% raw %}{{ person.car.c1 }}{% endraw %}、{% raw %}{{ person.car.c2 }}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改第一台车</button><button @click="changeC2">修改第二台车</button><button @click="changeCar">修改整个车</button></div> </template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18,car:{c1:'奔驰',c2:'宝马'}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changeC1(){person.car.c1 = '奥迪'}function changeC2(){person.car.c2 = '大众'}function changeCar(){person.car = {c1:'雅迪',c2:'爱玛'}}// 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式/* watch(()=> person.name,(newValue,oldValue)=>{console.log('person.name变化了',newValue,oldValue)}) */// 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数watch(()=>person.car,(newValue,oldValue)=>{console.log('person.car变化了',newValue,oldValue)},{deep:true})</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
watch(() => person.car, (newValue, oldValue) => {console.log('person.car变化了', newValue, oldValue) }, { deep: true })
• deep: true:由于 person.car 是一个对象,默认情况下,watch 只会监听对象的引用变化。如果你想监听对象内部的嵌套属性(如 c1 和 c2)的变化,需要设置 { deep: true },这会开启深度监视。
• 在 深度监视 下,watch 不仅会监视 person.car 的引用变化,还会监视 person.car.c1 和 person.car.c2 的变化。
这是对象类型的写法
情况5-监视多个事件
<template><div class="person"><h1>情况五:监视上述的多个数据</h1><h2>姓名:{% raw %}{{ person.name }}{% endraw %}</h2><h2>年龄:{% raw %}{{ person.age }}{% endraw %}</h2><h2>汽车:{% raw %}{{ person.car.c1 }}{% endraw %}、{% raw %}{{ person.car.c2 }}{% endraw %}</h2><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button><button @click="changeC1">修改第一台车</button><button @click="changeC2">修改第二台车</button><button @click="changeCar">修改整个车</button></div> </template><script lang="ts" setup name="Person">import {reactive,watch} from 'vue'// 数据let person = reactive({name:'张三',age:18,car:{c1:'奔驰',c2:'宝马'}})// 方法function changeName(){person.name += '~'}function changeAge(){person.age += 1}function changeC1(){person.car.c1 = '奥迪'}function changeC2(){person.car.c2 = '大众'}function changeCar(){person.car = {c1:'雅迪',c2:'爱玛'}}// 监视,情况五:监视上述的多个数据watch([()=>person.name,person.car],(newValue,oldValue)=>{console.log('person.car变化了',newValue,oldValue)},{deep:true})</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
// 监视,情况五:监视上述的多个数据watch([()=>person.name,person.car],(newValue,oldValue)=>{console.log('person.car变化了',newValue,oldValue)},{deep:true})
就是加了个中括号
watch- effect
<template><div class="person"><h2>需求:当水温达到60度,或水位达到80cm时,给服务器发请求</h2><h2>当前水温:{% raw %}{{temp}}{% endraw %}℃</h2><h2>当前水位:{% raw %}{{height}}{% endraw %}cm</h2><button @click="changeTemp">水温+10</button><button @click="changeHeight">水位+10</button></div> </template><script lang="ts" setup name="Person">import {ref,watch,watchEffect} from 'vue'// 数据let temp = ref(10)let height = ref(0)// 方法function changeTemp(){temp.value += 10}function changeHeight(){height.value += 10}// 监视 -- watch实现/* watch([temp,height],(value)=>{// 从value中获取最新的水温(newTemp)、最新的水位(newHeight)let [newTemp,newHeight] = value// 逻辑if(newTemp >= 60 || newHeight >= 80){console.log('给服务器发请求')}}) */// 监视 -- watchEffect实现watchEffect(()=>{if(temp.value >= 60 || height.value >= 80){console.log('给服务器发请求')}})</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
详细讲解:
watch 的用法:
• watch 是 Vue 3 中的一个 API,用于监视一个或多个响应式数据。当监视的数据发生变化时,watch 会触发回调函数,并将最新的值传递给回调函数。
• watch([temp, height], (value) => {...}):
• temp 和 height 是你监视的两个数据源。
• 当这两个数据发生变化时,watch 会调用回调函数 (value)。
• value 是一个数组,包含了 temp 和 height 的新值。注意:这两个值的顺序与传入 watch 时的顺序一致,value[0] 是 temp 的新值,value[1] 是 height 的新值。
回调函数:
• value:
• value 是一个数组,包含了所有被监视的数据的新值。在这个例子中,value 是 [newTemp, newHeight]。
• 通过解构赋值 let [newTemp, newHeight] = value,可以直接获取 temp 和 height 的新值。
• 条件判断:
• 如果 newTemp(水温)大于等于 60,或者 newHeight(水位)大于等于 80,就执行 console.log('给服务器发请求')。
• 这段逻辑可以用于监测水温或水位达到某个阈值时,触发某些操作(例如,发送请求给服务器)。
标签属性
<template><div class="person"><h1>中国</h1><h2 ref="title2">北京</h2><h3>尚硅谷</h3><button @click="showLog">点我输出h2这个元素</button></div> </template><script lang="ts" setup name="Person">import {ref,defineExpose} from 'vue'// 创建一个title2,用于存储ref标记的内容let title2 = ref()let a = ref(0)let b = ref(1)let c = ref(2)function showLog(){console.log(title2.value)}defineExpose({a,b,c}) </script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
TS
index.ts
// 定义一个接口,用于限制person对象的具体属性 export interface PersonInter {id:string,name:string,age:number }// 一个自定义类型 // export type Persons = Array<PersonInter> export type Persons = PersonInter[]
interface 定义接口
export interface PersonInter {id: string,name: string,age: number }
interface :接口用于定义对象的结构与约束
在这里:PersonInter是一个接口,约束了一个person对象必须具有的属性
• id:类型为 string,表示唯一标识符。
• name:类型为 string,表示人员的姓名。
• age:类型为 number,表示人员的年龄。
• type:类型别名可以用来给复杂的类型(如数组、联合类型等)取一个简短的名字。
• Persons:类型别名定义为一个 PersonInter 对象数组(即 PersonInter[]),表示一个由多个 person 对象组成的列表。
<script lang="ts" setup name="Person">import {type PersonInter,type Persons} from '@/types'// let person:PersonInter = {id:'asyud7asfd01',name:'张三',age:60}let personList:Persons = [{id:'asyud7asfd01',name:'张三',age:60},{id:'asyud7asfd02',name:'李四',age:18},{id:'asyud7asfd03',name:'王五',age:5}]</script>
• import { type ... }:
• type 是 TypeScript 的关键字,用来导入类型信息。它能明确表明这是一个类型导入,而不是普通值。
• 从 @/types 文件中导入了两个类型:PersonInter 和 Persons。
• @/types:
• 表示一个类型定义文件的路径。一般情况下,这个文件夹是项目中专门用来存放全局类型定义的。
• 在这个 types 文件中,定义了以下内容(假设内容如下):
• let personList: Persons:
• 通过 :Persons 明确指定了 personList 的类型是 Persons。
• Persons 的定义是 PersonInter[],即一个数组,数组的每个元素都必须符合 PersonInter 接口的结构。
• personList 的用途:
• personList 是一个数组,其中存储了多个 person 对象。
• 每个对象必须具有 id(字符串)、name(字符串)和 age(数字)属性,否则 TypeScript 会抛出类型错误。
• 数据校验示例:
• 如果你尝试添加一个不符合 PersonInter 结构的对象,比如:
let personList: Persons = [{ id: 'asyud7asfd04', name: '赵六' } // 缺少 age 属性 ]
props的使用
<template><div class="person"><ul><li v-for="p in list" :key="p.id">{% raw %}{{p.name}}{% endraw %} -- {% raw %}{{p.age}}{% endraw %}</li></ul></div> </template><script lang="ts" setup name="Person">import {withDefaults} from 'vue'import {type Persons} from '@/types'// 只接收list// defineProps(['list'])// 接收list + 限制类型// defineProps<{list:Persons}>()// 接收list + 限制类型 + 限制必要性 + 指定默认值withDefaults(defineProps<{list?:Persons}>(),{list:()=> [{id:'ausydgyu01',name:'康师傅·王麻子·特仑苏',age:19}]})// 接收list,同时将props保存起来/* let x = defineProps(['list'])console.log(x.list) */</script><style scoped>.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}li {font-size: 20px;} </style>
拆分代码:
-
模版部分
<template><div class="person"><ul><li v-for="p in list" :key="p.id">{% raw %}{{p.name}}{% endraw %} -- {% raw %}{{p.age}}{% endraw %}</li></ul></div> </template>
这里面含有v-for循环,那么这个是什么?
-
遍历list数据(通过props传递到组件中)
-
每个p是list数组中的一项
-
:key="p.id" 为每个列表项绑定唯一的 key,提高渲染性能。
• {% raw %}{ {p.name}}{% endraw %} 和 {% raw %}{ {p.age}}{% endraw %} 动态展示每个对象的 name 和 age 属性。
-
脚本部分
-
导入工具与类型
import { withDefaults } from 'vue' import { type Persons } from '@/types'
• withDefaults:
• 用于为 defineProps 定义的 props 设置默认值。它接收两个参数:
• defineProps 的返回值(包含 props 的类型约束)。
• 一个对象,用来指定每个 prop 的默认值。
-
那么对应的index.ts
// 定义一个接口,用于限制person对象的具体属性 export interface PersonInter {id:string,name:string,age:number, }// 一个自定义类型 // export type Persons = Array<PersonInter> export type Persons = PersonInter[]
-
相关文章:

vue3相关知识点
title: vue_1 date: 2025-01-28 12:00:00 tags:- 前端 categories:- 前端vue3 Webpack ~ vite vue3是基于vite创建的 vite 更快一点 一些准备工作 准备后如图所示 插件 Main.ts // 引入createApp用于创建应用 import {createApp} from vue // 引入App根组件 import App f…...

基于springboot+vue的流浪动物救助系统的设计与实现
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...

MySQL(单表访问)
今天是新年,祝大家新年快乐,但是生活还是得继续。 后面也会持续更新,学到新东西会在其中补充。 建议按顺序食用,欢迎批评或者交流! 缺什么东西欢迎评论!我都会及时修改的! 大部分截图和文章采…...

UE5.3 C++ CDO的初步理解
一.UObject UObject是所有对象的基类,往上还有UObjectBaseUtility。 注释:所有虚幻引擎对象的基类。对象的类型由基于 UClass 类来定义。 这为创建和使用UObject的对象提供了 函数,并且提供了应在子类中重写的虚函数。 /** * The base cla…...

SpringBoot 中的测试jar包knife4j(实现效果非常简单)
1、效果图 非常快的可以看见你实现的接口 路径http://localhost:8080/doc.html#/home 端口必须是自己的 2、实现效果 2.1、导入jar包 <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-star…...

Java Web 开发基础介绍
Java学习资料 Java学习资料 Java学习资料 一、引言 在当今数字化时代,Web 应用无处不在。Java 凭借其强大的功能、良好的跨平台性和丰富的开发框架,成为 Web 开发领域的热门选择之一。Java Web 开发允许开发者构建动态、交互式的 Web 应用程序&#x…...

Android Studio:视图绑定的岁月变迁(2/100)
一、博文导读 本文是基于Android Studio真实项目,通过解析源码了解真实应用场景,写文的视角和读者是同步的,想到看到写到,没有上帝视角。 前期回顾,本文是第二期。 private Unbinder mUnbinder; 只是声明了一个 接口…...

LabVIEW春节快乐
尊敬的LabVIEW开发者与用户朋友们: 灵蛇舞动辞旧岁,春风送暖贺新年!值此癸巳蛇年新春佳节来临之际,向每一位深耕LabVIEW开发领域的伙伴致以最诚挚的祝福:愿您与家人在新的一年里平安顺遂、阖家幸福,事业如…...

rewrite规则
NGINX 中 rewrite最后的标记含义: flag标记有: last 相当于Apache里的[L]标记,表示完成rewrite,匹配完,再向下匹配。地址栏会显示跳转后的地址 break 终止匹配, 不再匹配后面的rewrite规则,地址栏会显示跳…...

Android车机DIY开发之学习篇(七)NDK交叉工具构建
Android车机DIY开发之学习篇(七)NDK交叉工具构建 1.ubuntu安装GCC sudo apt-get update sudo apt-get install gcc g sudo gcc --version sudo g --version 2.测试GCC VSCODE中新建Hello.c编译 #include <stdio.h> int main(void) { printf(“Hello, this is a progr…...

【初/高中生讲机器学习】0. 本专栏 “食用” 指南——写在一周年之际⭐
创建时间:2025-01-27 首发时间:2025-01-29 最后编辑时间:2025-01-29 作者:Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏,很高兴遇见你~ 我是 Geeker_LStar,一名高一学生,热爱计…...

虚幻基础11:坐标计算旋转计算
能帮到你的话,就给个赞吧 😘 文章目录 坐标line startget actor rotationget forward vector 旋转计算 坐标 ue中通常使用向量计算坐标。 line start 起始坐标点。 get actor rotation 获取旋转值: 当前角色朝向 get forward vector 获…...

Rust:Rhai脚本编程示例
当然,以下是一个简单的Rhai脚本编程示例,展示了如何在Rust中使用Rhai执行脚本。 首先,你需要确保你的Rust项目中包含了rhai库。你可以在你的Cargo.toml文件中添加以下依赖项: [dependencies] rhai "0.19" # 请检查最…...

关于el-table翻页后序号列递增的组件封装
需求说明: 项目中经常会用到的一个场景,表格第一列显示序号(1、2、3...),但是在翻页后要递增显示序号,例如10、11、12(假设一页显示10条数据),针对这种情况,封…...

【深度学习】softmax回归
softmax回归 回归可以用于预测多少的问题。 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数。 事实上,我们也对分类问题感兴趣:不是问“多少”,而是问“哪一个”: 某个电子邮…...

设计模式-建造者模式、原型模式
目录 建造者模式 定义 类图 优缺点 角色 建造者模式和工厂模式比较 使用案例 原型模式 定义 类图 优缺点 应用场景 应用类型 浅克隆 深克隆 建造者模式 定义 将一个复杂的对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,…...

【Redis】List 类型的介绍和常用命令
1. 介绍 Redis 中的 list 相当于顺序表,并且内部更接近于“双端队列”,所以也支持头插和尾插的操作,可以当做队列或者栈来使用,同时也存在下标的概念,不过和 Java 中的下标不同,Redis 支持负数下标&#x…...

三个不推荐使用的线程池
线程池的种类 其实看似这么多的线程池,都离不开ThreadPoolExecutor去创建,只不过他们是简化一些参数 newFixedThreadPool 里面全是核心线程 有资源耗尽的风险,任务队列最大长度为Integer.MAX_VALUE,可能会堆积大量的请求ÿ…...

mybatis(78/134)
前天学了很多,关于java的反射机制,其实跳过了new对象,然后底层生成了字节码,创建了对应的编码。手搓了一遍源码,还是比较复杂的。 <?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE …...

Progressive Pretext Task Learning for Human Trajectory Prediction | 文献翻译
祥龙回首留胜景,金蛇起舞贺新程。 概述 行人轨迹预测是一项旨在预测行人未来位置的任务,它通常涵盖了从短期到长期的整个时间范围内的轨迹。然而,现有的研究试图通过单一、统一的训练范式来解决整个轨迹预测问题,往往忽视了行人轨…...

54.数字翻译成字符串的可能性|Marscode AI刷题
1.题目 问题描述 小M获得了一个任务,需要将数字翻译成字符串。翻译规则是:0对应"a",1对应"b",依此类推直到25对应"z"。一个数字可能有多种翻译方法。小M需要一个程序来计算一个数字有多少种不同的…...

【数据结构】_链表经典算法OJ(力扣版)
目录 1. 移除链表元素 1.1 题目描述及链接 1.2 解题思路 1.3 程序 2. 反转链表 2.1 题目描述及链接 2.2 解题思路 2.3 程序 3. 链表的中间结点 3.1 题目描述及链接 3.2 解题思路 3.3 程序 1. 移除链表元素 1.1 题目描述及链接 原题链接:203. 移除链表…...

【Linux】统计文本中每行指定位置出现的字符串的次数
统计文本中每行指定位置出现的字符串的次数 假定情景 某些项目,会把某个特定事件记录到Log中并且落盘(保持到硬盘)。基于落盘后的日志,要统计这些日志里产生该特定事件的次数 统计脚本 可以写一个sh脚本,来解析某个…...

【赵渝强老师】K8s中Pod探针的ExecAction
在K8s集群中,当Pod处于运行状态时,kubelet通过使用探针(Probe)对容器的健康状态执行检查和诊断。K8s支持三种不同类型的探针,分别是:livenessProbe(存活探针)、readinessProbe&#…...

商品信息管理自动化测试
目录 前言 一、思维导图 二、代码编写 1.在pom.xml文件中添加相关依赖 2.自动化代码编写 三、代码测试 小结 前言 1. 针对商品信息管理项目进行测试,商品信息管理项目主要有商品列表页、部门列表页、员工列表页,主要功能:对商品信息的…...

Redis实战(黑马点评)——redis存储地理信息、位图、HyperLogLog 用法
Redis存储geo数据类型基本介绍 geo 就是 geolocation 的简写形式,代表地理坐标。redis 在 3.2 版本中加入了对 geo 的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有: geoadd:添加一个地理空…...

判断1到100之间有多少个素数,并输出所有的素数。
def is_prime(num): #判断一个数是否素数if num<1:return False #因为1和负数都不是素数for i in range(2,int(num**0.5)1): #从2开始到根号num的整数结束,因为一个数num不是素数,那么把必定有一个小于或等于根号num的因素if num%i0:return False #如…...

JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南
1、简述 Content Negotiation(内容协商) 是 RESTful 服务的重要特性,允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制,通过它,服务器能够根据客户端需求返回适合的内…...

layui Table单元格编辑支持Enter键换行,包括下拉框单元格
layui Table表格编辑支持Enter键换行 可编辑单元格 $(".layui-table td").keydown(function (e) {// console.log("111",e);var index $(this).index(),tr $(this).parent(tr),isKeydown (event.type "keydown");if (e.code "Enter&q…...

Swoole的MySQL连接池实现
在Swoole中实现MySQL连接池可以提高数据库连接的复用率,减少频繁创建和销毁连接所带来的开销。以下是一个简单的Swoole MySQL连接池的实现示例: 首先,确保你已经安装了Swoole扩展和PDO_MySQL扩展(或mysqli,但在这个示…...