学习笔记:Vue3(图片明天处理)

文章目录

  • 1.概述
    • 1.1定义
    • 1.2特性
    • 1.3组合式API
  • 2.基本用例-项目搭建
  • 3.项目目录介绍
    • 3.1概述
    • 3.2查看文件
  • 4.组合式API
    • 4.1概述
    • 4.2新的API风格
      • 4.2.1概述
      • 4.2.2写法
      • 4.2.3基本用例-Setup选项使用
      • 4.2.4基本用例-语法糖写法(重点)
      • 4.2.5执行时机
      • 4.2.6代码特点
    • 4.3响应式对象
      • 4.3.1概述
      • 4.3.1基本用例-Reactive函数使用
      • 4.3.2基本用例-Ref函数使用
    • 4.4计算
      • 4.4.1概述
      • 4.4.2基本用例-Computed函数使用
    • 4.5侦听
      • 4.5.1概述
      • 4.5.2基本用例-Watch函数使用
      • 4.5.3侦听多个数据
      • 4.5.4立即执行-immediate
      • 4.5.5深度侦听-deep
    • 4.6生命周期函数
      • 4.6.1概述
      • 4.6.2基本用例-生命周期钩子使用
      • 4.6.3执行多次
    • 4.7父子通信
      • 4.7.1概述
      • 4.7.2基本用例-Dom属性实现父传子
      • 4.7.3父传子动态绑定
      • 4.7.4Emit实现子传父通信
    • 4.8模板引用
      • 4.8.1概述
      • 4.8.2基本用例-ref标识获取Dom对象
      • 4.8.3defineExpose实现访问组件内部属性
    • 4.9跨组件通信
      • 4.9.1概述
      • 4.9.2基本用例-Provide和inject使用
      • 4.9.3跨层传递响应式数据
      • 4.9.4跨层传递方法
  • 5.案例-基础综合
    • 5.1概述
    • 5.2实现列表渲染
    • 5.3实现删除功能
    • 5.4实现编辑功能
  • 6.状态管理库pinia
    • 6.1概述
    • 6.2基本用例
  • 知识加油站
    • 1.PNPM包管理工具使用
    • 2.Vite介绍
    • 3.Axios和Ajax区别

1.概述

笔记小结:

  • 定义:Vue 3 是一种流行的 JavaScript 前端框架,相对于Vue2,提升性能可维护性开发体验
  • 特性:更容易维护、更快的速度、更小的体积、更优的数据响应式
  • 组合式API:组合式 API 是 Vue 3 中引入的一种新的编写组件逻辑的方式

1.1定义

​ Vue 3 是一种流行的 JavaScript 前端框架,用于构建用户界面和单页应用程序(SPA)。它是 Vue.js 框架的第三个主要版本,是对 Vue.js 2 的重大升级和改进。Vue 3 专注于提升性能可维护性开发体验,引入了许多新的特性和改进

​ 官方网站:简介 | Vue.js (vuejs.org)

1.2特性

在这里插入图片描述

  1. 更快的性能: Vue 3 在底层进行了重大的重构,采用了 Proxy 代理,使得响应式数据的追踪更加高效。这带来了更快的渲染性能和更小的包体积。
  2. Composition API: Vue 3 引入了 Composition API,允许开发人员更灵活地组织和复用组件逻辑。这使得代码更具可维护性和可读性。
  3. Teleport: Teleport 是 Vue 3 新增的一个功能,它允许将一个组件的内容插入到 DOM 树中的任何位置。这对于在不同的 DOM 结构中渲染组件内容非常有用。
  4. Fragments: Vue 3 支持使用 Fragments,即不需要额外的父元素包裹组件内容。
  5. 全局 API 的修改: Vue 3 对全局 API 进行了优化和修改,提供了更好的 TypeScript 支持。
  6. 模板语法的改进: Vue 3 在模板语法方面进行了一些改进,使其更加强大和灵活。
  7. 静态类型检查增强: Vue 3 在类型检查方面引入了一些新的功能,提高了代码的可靠性。

1.3组合式API

​ 组合式 API 是 Vue 3 中引入的一种新的编写组件逻辑的方式,旨在提供更灵活、更可维护的代码结构。它是对 Vue 2 中的选项式 API(Options API)的补充和扩展,让开发人员能够更自由地组合和复用组件逻辑。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 使用Vue2和Vue3完成相同的前端功能,发现代码量变少了、从分散式维护转为了集中式维护

2.基本用例-项目搭建

笔记小结:

  1. 创建Vue应用:

    pnpm create vue
    
  2. 初始化项目

    pnpm install
    pnpm run dev
    
  3. 访问

    localhost:5173
    

说明:

  • 基于Pnpm+Vite搭建
  • Node.Js 版本需要大于等于16.0

步骤一:创建Vue应用

pnpm create vue

说明:

  • 使用pnpm包管理工具进行vue项目的创建

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 先搭建一个简单的项目,因此使用以上选择即可

步骤二:初始化项目

1.利用VsCode打开终端

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2.执行命令

pnpm install
pnpm run dev

说明:

pnpm run dev 命令会在当前项目中查找名为 dev 的脚本,并执行该脚本,通常用于启动开发服务器或执行其他开发环境相关的任务

步骤三:演示

  • 浏览器访问地址

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 若能看见此界面,说明Vue3项目搭建完成

3.项目目录介绍

笔记小结:本小节概述

3.1概述

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.2查看文件

1.查看项目package.json文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

  1. dependencies
    • 这部分定义了项目在生产环境中所需的依赖包。这些依赖包将会随着项目的部署一起打包到生产环境中,用于实际的运行
    • 例如,Vue 3 框架本身、axios、lodash 等常用的库通常会放在 dependencies 中。
  2. devDependencies
    • 这部分定义了项目在开发过程中所需的依赖包。这些依赖包通常不会被包含在最终的生产构建中,只在开发阶段使用
    • 例如,开发工具、测试库、代码检查工具等通常会放在 devDependencies 中。
    • 运行 npm installyarn install 时,不加 --production 参数,只会安装 devDependencies 中的依赖。

2.查看项目vite.config.js文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

  • ``vite.config.js是 Vite 构建工具中的配置文件,用于配置项目的构建和开发行为。Vite 是一个基于现代浏览器原生 ES 模块的开发服务器和构建工具,旨在提供快速的开发体验。在vite.config.js` 文件中,你可以定义各种选项和插件配置别名配置代理配置
  • 此文件类似于Vue2中的`vue.config.js``

3.查看项目main.js文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

main.js文件,又叫入口文件,决定了项目是否能够跑起来

4.查看项目App.vue文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ Vue3创建的模板,需要使用setup语法糖,让Vue支持主键式API写法。并且不再要求唯一一个根元素。

4.组合式API

笔记小结:

  1. setup选项的执行时机?

    beforeCreate钩子之前 自动执行

  2. setup写代码的特点是什么?
    定义数据 + 函数 然后以对象方式return

  3. <script setup> 解决了什么问题?

经过语法糖的封装更简单的使用组合式API

  1. setup中的this还指向组件实例吗?
    指向undefined

  2. reactive和ref函数的共同作用是什么 ?
    用函数调用的方式生成响应式数据

  3. reactive vs ref ?

  4. reactive不能处理简单类型的数据

  5. ref参数类型支持更好但是必须通过.value访问修改

  6. ref函数的内部实现依赖于reactive函数

  7. 在实际工作中推荐使用哪个?
    推荐使用ref函数,更加灵活,小兔鲜项目主用ref

  8. 作为watch函数的第一个参数,ref对象需要添加.value吗?
    不需要,watch会自动读取

  9. watch只能侦听单个数据吗?
    单个或者多个

  10. 不开启deep,直接修改嵌套属性能触发回调吗?
    不能,默认是浅层侦听

  11. 不开启deep,想在某个层次比较深的属性变化时执行回调怎么做?
    可以把第一个参数写成函数的写法,返回要监听的具体属性

  12. 组合式API中生命周期函数的格式是什么?
    on + 生命周期名字

  13. 组合式API中可以使用onCreated吗?
    没有这个钩子函数,直接写到setup中

  14. 组合式API中组件卸载完毕时执行哪个函数?
    onUnmounted

父子通信(重点)

  1. 父传子的过程中通过什么方式接收props?
    defineProps( { 属性名:类型 } )

  2. setup语法糖中如何使用父组件传过来的数据?
    const props = defineProps( { 属性名:类型 } )
    子传父

  3. 子传父的过程中通过什么方式得到emit方法?
    defineEmits( [‘事件名称’] )

  4. 获取模板引用的时机是什么?
    组件挂载完毕

  5. defineExpose编译宏的作用是什么?
    显式暴露组件内部的属性和方法

  6. provide和inject的作用是什么?
    跨层组件通信

  7. 如何在传递的过程中保持数据响应式?
    第二个参数传递ref对象

  8. 底层组件想要通知顶层组件做修改,如何做?
    传递方法,底层组件调用方法

  9. 一颗组件树中只有一个顶层或底层组件吗?
    相对概念,存在多个顶层和底层的关系

4.1概述

​ 组合式 API 是 Vue 3 中引入的一种新的 API 设计模式,旨在更好地组织和复用逻辑代码。它是一种基于函数的 API 风格,通过将逻辑代码拆分为一组功能独立的函数,然后在组件中组合使用这些函数,从而实现更好的代码复用和可维护性

4.2新的API风格

4.2.1概述

Setup选项,为Vue3的一种新的API风格。更少的样板内容,更简洁的代码、能够使用纯 TypeScript 声明 props 和自定义事件、更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)、更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)

4.2.2写法

写法一:复杂写法

  • 以下是SetUp选项的复杂写法
<script>export default {setup(){return{}}}
</script>

补充:

  • 以下是Vue2的data函数加上返回值写法
<script>export default {data() {return {}}}
</script>
  • Vue3的复杂写法与Vue2的data函数加上返回值写法一致

方式二:语法糖写法✳

<script setup></script>

说明:

​ 语法糖写法,简化了Vue2的data函数

4.2.3基本用例-Setup选项使用

步骤一:实现新API风格组件JS行为

  • 编写组件JS行为区域,实现Setup复杂语法使用
<script>import { onBeforeMount } from 'vue'export default {setup(){const message = 'this is message' // 变量直接赋值const logMessage = ()=>{ // 函数方法console.log(message)}// 必须return,后面的<template>模板才能够拿到return {// message,message,logMessage}}}
</script>

补充:

​ 在Vue2中由Vue管理的函数,一定不要写箭头函数,否则this就不再是Vue实例了。但在Vue3的setup选项中,箭头函数赋值为对象,因此没有这个说法了

步骤二:实现组件模板

<template>{{message}} <!--插值语法-->
</template>

说明:

​ 编写项目App.vue文件的组件模板结构

步骤三:演示

  • 查看setup函数返回对象和不返回对象区别

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当没有Setup函数中没有返回对象时,模板里的数据将不可用

4.2.4基本用例-语法糖写法(重点)

步骤一:实现setup选项语法糖语法

  • 编写组件JS行为区域,实现Setup语法糖写法使用
<script setup> // 此处添加 setup属性const message = 'this is message' // 对象可以为变量const logMessage = ()=>{  // 对象可以为函数console.log(message)}
</script>

注意:

​ 此时

补充:

  • 通过Vue提供的编译工具可以发现,语法糖写法其实就是将语法糖写法变为了复杂写法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤二:实现组件模板

<template>
{{message}}
</template>

步骤三:演示

  • 语法糖模式一样能实现新API组件的展示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 省去了setup函数返回对象的写法

4.2.5执行时机

setup生命周期在beforeCreat之前

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.2.6代码特点

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 代码的书写需要通过return的方式进行返回。这点已经在写法小节中说明。

注意:

  • 在Vue3中,对象的使用不再有this,而是直接使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 可以看到this为undefined未定义

4.3响应式对象

4.3.1概述

​ Vue3中,新的API编程风格里,对象的响应式对象需要通过手动来决定。跟Vue2做区分,Vue2的data函数的返回值默认全是响应式对象

4.3.1基本用例-Reactive函数使用

说明:

​ 接受对象类型数据的参数传入并返回一个响应式的对象

步骤一:实现新API风格组件JS行为

  • 编写组件JS行为区域,实现对象类型响应式对象
<script setup>// 1.导入函数import { reactive } from 'vue'// 2.执行函数 传入对象参数 变量接收const state = reactive({msg:'this is msg'})const setSate = ()=>{// 3.修改数据更新视图state.msg = 'this is new msg'}
</script>

说明:

​ Reactive函数类是于Vue2的Data函数,用于返回响应式对象

步骤二:实现组件模板

<template>{{ state.msg }} <!-- 插值语法 --><button @click="setState">change msg</button> <!--按钮点击-->
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当点击按钮后,更改了对象state.msg的值,页面也会动态的随之变化

4.3.2基本用例-Ref函数使用

说明:

​ 接收**简单类型或者对象类型的数据传入并返回一个响应式的对象**

步骤一:实现Ref函数

  • 编写组件JS行为区域,实现对象类型简单类型响应式对象使用
<script setup>// 1.导入函数import { ref } from 'vue'// 2.执行函数 传入简单类型或对象类型参数 变量接收const count = ref(0)const setCount = ()=>{// 3.修改数据更新视图必须加上.valuecount.value++}
</script>

说明:

​ Reactive函数类是于Vue2的Data函数,用于返回响应式对象

补充:

  • 因为Ref函数的返回值为对象,因此可以通过对象获取它的value值来查看其属性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤二:实现组件模板

<template>
<button @click="setCount">{{count}}</button> <!--此处ref函数的对象的属性值接使用即可-->
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当点击按钮后,更改了对象count.value的值,页面也会动态的随之变化

4.4计算

4.4.1概述

在Vue3中,计算函数的写法跟vue2不同,但核心思想没有发生改变

4.4.2基本用例-Computed函数使用

说明:

执行函数 在回调参数中return基于响应式数据做计算的值,用变量接收

步骤一:实现Computed函数使用

  • 编写组件JS行为区域,实现响应式数据计算
<script setup>// 1.导入函数import {ref, computed } from 'vue'// 2.编写原始数据const count = ref(0)// 3.编写计算属性const doubleCount = computed(()=>count.value * 2) // 2.原始数据const list = ref([1,2,3,4,5,6,7,8])// 3.计算属性listconst filterList = computed(()=>{return  list.value.filter(item => item > 2) // 利用filter函数实现数值过滤}) 
</script>

补充:Computed最佳实践

  1. 计算属性中不应该有“副作用”。比如异步请求/修改dom,也就是说,再计算属性内部只做普通运算、修改就行,不要有其余操作,就像发送ajax请求
  2. 避免直接修改计算属性的值。计算属性应该是只读的,也就是说,不要再再计算属性之外再做其余非读操作

步骤二:实现组件模板

<template>
原始数据{{list}} <br>
计算数据{{filterList}}
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4.5侦听

4.5.1概述

侦听一个或者多个数据的变化,数据变化时执行回调函数,俩个额外参数 immediate控制立刻执行,deep开启深度侦听

4.5.2基本用例-Watch函数使用

步骤一:实现Watch函数侦听单个数据使用

  • 编写组件JS行为区域,实现单个数据的侦听
<script setup>// 1. 导入watchimport { ref, watch } from 'vue'const count = ref(0)// 2. 调用watch 侦听变化watch(count, (newValue, oldValue)=>{ // 当watch函数使用ref的对象时,无需count.value,可以直接传入对象console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)})// 修改count方法const changeCount = ()=>{count.value++}
</script>

步骤二:实现组件模板

<template><button @click="changeCount">修改count++</button> <!--按钮点击-->
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当侦听的数据发生改变时,就执行侦听的逻辑

补充:

​ 当侦听的对象数据的value值发生改变,是不会执行侦听逻辑的。详细请查看深度侦听小节

4.5.3侦听多个数据

说明;

​ 当多个数据发生改变时,需要执行同一套侦听逻辑时使用

步骤一:实现Watch函数侦听多个数据使用

  • 编写组件JS行为区域,实现多个数据的侦听
<script setup>// 1. 导入watchimport { ref, watch } from 'vue'const count = ref(0)const name = ref('cp')// 2. 调用watch 侦听变化watch([count, name], ([newCount, newName],[oldCount,oldName])=>{console.log(`count或者name变化了,[newCount, newName],[oldCount,oldName]`)})
</script>

说明:

​ 侦听多个数据,第一个参数可以改写成数组的写法

步骤二:实现组件模板

<template>
<button @click="changeCount">修改count++</button> <!--按钮点击-->
<button @click="changeName">修改count</button> <!--按钮点击-->
</template>

步骤三:演示

  • 分别点击两个按钮

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当侦听的数据任一其一发生改变时,就会执行它们共通的侦听逻辑

4.5.4立即执行-immediate

说明:

​ 当项目被访问时,需要默认执行一次侦听里面的逻辑时使用

步骤一:添加Watch函数立即执行属性

  • 编写组件JS行为区域,为监听函数,添加immediate属性
<script setup>// 1. 导入watchimport { ref, watch } from 'vue'const count = ref(0)// 2. 调用watch 侦听变化watch(count, (newValue, oldValue)=>{ // 当watch函数使用ref的对象时,无需count.value,可以直接传入对象console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)},{// 3.立即执行immediate:true })// 修改count方法const changeCount = ()=>{count.value++}
</script>

步骤二:实现组件模板

<template><button @click="changeCount">修改count++</button> <!--按钮点击-->
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当项目被访问时,就会默认执行一次侦听里面的逻辑

4.5.5深度侦听-deep

说明:

​ 当需要修改嵌套对象的属性时使用

步骤一:添加Watch函数深度监听属性

  • 编写组件JS行为区域,为监听函数,添加deep属性
<script setup>
// 1. 导入watch
import { ref, watch } from 'vue'
const state = ref({ count: 0 ,age:18})
//2. 监听对象state 并开启deep
watch(state, ()=>{console.log('count和age数据变化了')
},{// 3.深度监听deep:true 
})// 4.侦听对象的个别属性
watch(()=> state.value.age,()=> console.log("age属性变化了")
)// 修改count方法const changeCount = ()=>{// 此时修改可以触发回调state.value.count++
}// 修改age方法
const changeAge = ()=>{// 此时修改可以触发回调state.value.age++
}
</script>

补充:

  • 当需要进行对象里面的属性值的个别侦听是,需要用侦听函数,同时返回需要侦听的对象与侦听的执行逻辑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤二:实现组件模板

<template>
<button @click="changeCount">修改count++</button> <!--按钮点击-->
<button @click="changeAge">修改age++</button> 
</template>

步骤三:演示

1.实现侦听里面的对象任一属性侦听

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当开启深度属性时,点击按钮会看到侦听逻辑已执行。若无深度属性,无论怎样点击按钮都不会执行侦听逻辑

注意:

​ 此时,只要侦听对象的任一属性发生变化,都会执行侦听逻辑

2.实现侦听里面的对象的个别属性侦听

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 对象个别属性的改变,互不影响

4.6生命周期函数

4.6.1概述

​ 生命周期函数是在组件的生命周期中会被自动调用的一组特殊函数,它们允许你在不同的阶段执行代码。在 Vue.js 中,组件的生命周期分为创建阶段、更新阶段和销毁阶段,而生命周期函数则对应于这些不同的阶段。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ beforeCreate和created变为了setup,beforeDestory和destoryed变为了onBeforeUnmount和onUnmounted

4.6.2基本用例-生命周期钩子使用

说明:

​ 执行生命周期函数,传入回调

步骤一:添加生命周期钩子

  • 编写组件JS行为区域,添加挂载钩子
<script setup>import { onMounted } from 'vue'onMounted(()=>{console.log("我挂载了") // 自定义逻辑})
</script>

步骤二:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 生命周期钩子执行成功

4.6.3执行多次

说明:

​ 当需要补充或者分散同一生命周期钩子时可定义多个相同生命周期钩子来使用

步骤一:添加生命周期钩子

  • 编写组件JS行为区域,添加挂载钩子
<script setup>import { onMounted } from 'vue'onMounted(()=>{console.log("我挂载了1") // 自定义逻辑})onMounted(()=>{console.log("我挂载了3")})onMounted(()=>{console.log("我挂载了2")})</script>

步骤二:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当有多个相同的生命周期钩子时,会从上往下依次执行

4.7父子通信

4.7.1概述

​ 在 Vue 3 中,父子组件之间的通信依然可以通过 Props 和 Emit 实现,但也引入了一些新的方式,如 setup 函数、provideinject

4.7.2基本用例-Dom属性实现父传子

步骤一:编写父组件

  • 编写组件JS行为区域与组件模板
<script setup> // Vue3的setup语法糖,已经帮助我们实现主键的注册
// 1.引入子组件
import sonComVue from "./components/son-com.vue";
</script>
<template><div>父传子通信</div><p><sonComVue message="玥玥,我爱你"/></p><!--2.传递信息-->
</template>

注意:

  • 此处与Vue2不同,不需要实现逐渐注册

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

补充:

  • 通过官方提供的编译工具可以发现,setup语法糖的写法会被自动编译为Vue2的写法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

步骤二:编写子组件

  • 编写组件JS行为区域与组件模板
<script setup >
// 1.通过defineProps编译器宏接收子组件传递的数据
const props = defineProps({message: String
})
</script>
<template>
{{message}}
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 子组件内容正常显示,控制台无报错

4.7.3父传子动态绑定

说明:

​ 当需要通过父组件向子组件传递动态数据时使用

步骤一:编写父组件

  • 编写组件JS行为区域与组件模板
<script setup>
// 1.引入子组件
import sonComVue from "./components/son-com.vue";
import { ref } from 'vue'// 3.设置动态改变
const age = ref(520)
setTimeout(() => {age.value++
}, 3000);</script>
<template><div>父传子通信</div><p><sonComVue message="玥玥" :age="age"/></p><!--2.传递动态信息-->
</template>

步骤二:编写子组件

  • 编写组件JS行为区域与组件模板
<script setup >
// 1.通过defineProps编译器宏接收子组件传递的数据
const props = defineProps({message: String
})
</script>
<template>
{{message}}
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 三秒后,数据发生动态改变

4.7.4Emit实现子传父通信

说明:

​ 当需要通过子组件向父组件传递动态数据时使用

步骤一:编写父组件

  • 编写组件JS行为区域与组件模板
<script setup>
// 1.引入子组件
import sonComVue from "./components/son-com.vue";// 2.执行父组件中的方法
const getMessage=(msg)=>{console.log(msg)
}
</script>
<template><div>父传子通信</div><p><sonComVue @get-message="getMessage"/></p> <!--3.绑定本地点击事件-->
</template>

步骤二:编写子组件

  • 编写组件JS行为区域与组件模板
<script setup >
// 1.通过defineEmits编译器宏生成emit方法
const emit = defineEmits(["get-message"])
// 3.实现本地方法逻辑
const sendMsg=()=>{emit('get-message',"this is son msg")
}</script>
<template>
<button @click="sendMsg">sendMsg</button><!--2.通过点击事件来实现通信-->
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当通过点击子组件中的按钮后,信息成功传递到父组件

补充:

  • 模型执行流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 通过子组件触发事件,再有父组件绑定的自定义事件接收,从而形成事件传递,因此父组件中可以执行此组件的逻辑

4.8模板引用

4.8.1概述

通过 ref标识 获取真实的 dom对象或者组件实例对象

4.8.2基本用例-ref标识获取Dom对象

说明:

​ 通过ref标识,获取dom对象和组件的实例对象时使用

步骤一:实现ref获取dom对象

  • 编写组件JS行为区域和组件模板,实现Setup复杂语法使用
<script setup>
import {onMounted, ref} from "vue";
import TestCom from "./components/TestCom.vue";
// 1.调用ref函数得到ref对象
const h1Ref = ref(null)
const comRef = ref(null)// 3.查看绑定结果-组件挂载完毕之后才能获取
onMounted(          ()=>{console.log(h1Ref.value)console.log(comRef.value)
})
</script>
<template><!-- 2.通过ref标识标记绑定对象 --><h1 ref="h1Ref">我是dom标签</h1><TestCom ref="comRef" />
</template>

说明:

​ 由于组件的生命周期不同,因此再JS行为区使用生命周期钩子,来查看绑定的结果

步骤二:实现子组件逻辑

  • 编写组件JS行为区域和组件模板,实现Setup复杂语法使用
<script setup >
import {ref} from "vue";// 1.定义测试消息对象const message = ref("this is love msg")
</script>
<template>{{message}}
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 在控制台区域已成功看到dom节点的信息已获取

4.8.3defineExpose实现访问组件内部属性

说明:

​ 通过ref标识,获取dom对象和组件的实例对象时使用

步骤一:实现主组件ref获取dom对象

  • 编写组件JS行为区域和组件模板,实现Setup复杂语法使用
<script setup>
import {onMounted, ref} from "vue";
import TestCom from "./components/TestCom.vue";
// 1.调用ref函数得到ref对象
const h1Ref = ref(null)
const comRef = ref(null)// 3.查看绑定结果-组件挂载完毕之后才能获取
onMounted(          ()=>{console.log(h1Ref.value)console.log(comRef.value)
})
</script>
<template><!-- 2.通过ref标识标记绑定对象 --><h1 ref="h1Ref">我是dom标签</h1><TestCom ref="comRef" />
</template>

说明:

​ 由于组件的生命周期不同,因此再JS行为区使用生命周期钩子,来查看绑定的结果

步骤二:设置子组件访问

  • 编写组件JS行为区域和组件模板,实现Setup复杂语法使用
<script setup >
import {ref} from "vue";// 1.定义测试消息对象const message = ref("this is love msg")//2.编写defineExpose编译器宏设置需要开放的内部组件的属性和方法
defineExpose({message
})
</script>
<template>{{message}}
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 可以看到,对象的属性已经可以被主组件访问

4.9跨组件通信

4.9.1概述

顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当需要进行组件和子子组件进行通信时,会用到此方法

4.9.2基本用例-Provide和inject使用

说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 跨层传递普通数据

步骤一:主组件导入子组件

  • 编写组件JS行为区域和组件模板,实现子组件引用
<script setup>import { provide } from 'vue';import sonCom from './components/son-com.vue';provide("mylove","yueyue ,you are my love") // 1.使用provide函数,约定key和value
</script>
<template>
<h1 >父组件</h1>
<sonCom/>
</template>

步骤二:子组件导入子子组件

  • 编写组件JS行为区域和组件模板,实现子子组件引用
<script setup >import sonSonCom from './son-son-com.vue';
</script>
<template>
<h2>子组件</h2>
<sonSonCom />
</template>

步骤三:子子组件展示数据

<script setup >import { inject } from "vue";const message = inject("mylove") // 2.使用inject根据约定的key获取value
</script>
<template>
<h3>子子组件</h3>
{{message }}
</template>

步骤四:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 通过父组件传递给子组件数据,成功展示

4.9.3跨层传递响应式数据

说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 跨层传递响应数据

步骤一:主组件导入子组件

  • 编写组件JS行为区域和组件模板,实现子组件引用
<script setup>
import { provide,ref } from 'vue';
import sonCom from './components/son-com.vue';
// 1.定义响应式数据
const message = ref("yueyue ,you are my love")
// 2.使用provide函数,约定key和value
provide("mylove",message)
// 3.模拟动态改变
setTimeout(() => {message.value="yueyue,i love you"
}, 3000);
</script><template><h1 >父组件</h1><sonCom/>
</template>

步骤二:子组件导入子子组件

  • 编写组件JS行为区域和组件模板,实现子子组件引用
<script setup >import sonSonCom from './son-son-com.vue';
</script>
<template>
<h2>子组件</h2>
<sonSonCom />
</template>

步骤三:子子组件展示数据

<script setup >import { inject } from "vue";const message = inject("mylove") // 2.使用inject根据约定的key获取value
</script>
<template>
<h3>子子组件</h3>
{{message }}
</template>

步骤四:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 可以看到3秒后,数据已发生改变。说明响应式数据传递成功

4.9.4跨层传递方法

说明:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 跨层传递方法

步骤一:主组件导入子组件

  • 编写组件JS行为区域和组件模板,实现子组件引用
<script setup>
import { provide,ref } from 'vue';
import sonCom from './components/son-com.vue';
// 1.定义响应式数据
const value = ref(0)
// 2.准备传递方法
const setValue = ()=>{value.value++
}
// 3.使用provide函数,约定key和value
provide("mylove",setValue)
</script><template><h1 >父组件--{{value}}</h1><sonCom/>
</template>

步骤二:子组件导入子子组件

  • 编写组件JS行为区域和组件模板,实现子子组件引用
<script setup >import sonSonCom from './son-son-com.vue';
</script>
<template>
<h2>子组件</h2>
<sonSonCom />
</template>

步骤三:子子组件展示数据

<script setup >
import { inject } from "vue";
const setValue = inject("mylove")
</script>
<template>
<h3>子子组件</h3>
<button @click="setValue">+</button>
</template>

步骤四:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 通过点击子子组件的按钮,可以实现父组件的数据改变

5.案例-基础综合

5.1概述

说明:

​ 初始化项目,运行项目

步骤一:获取项目

git clone  http://git.itcast.cn/heimaqianduan/vue3-basic-project.git

步骤二:安装依赖包

pnpm install

步骤三:运行项目

pnpm dev

步骤四:查看项目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.2实现列表渲染

说明:

​ 列表渲染思路:1.获取响应式对象 2.获取后台数据 3.赋值响应式对象 4.渲染数据 5.挂载数据

步骤一:完成axios请求,实现列表渲染功能

1.修改项目App.vue文件,完成列表渲染

<script setup>
import Edit from './components/Edit.vue'
import axios from 'axios';
import { onMounted, ref } from 'vue';// 功能一:列表渲染
// 1.定义响应式数据容器list
const list = ref([]) //这里的响应式数据定义为空数组
// 2.获取后端数据
const getList = async ()=>{// 3.赋值数据给listconst resp = await axios.get('/list')list.value = resp.data
}
// 6.挂载数据
onMounted(()=>{getList()
})
</script><template><div class="app"><!-- 4.绑定到table组件 --><el-table :data="list"><el-table-column label="ID" prop="id"></el-table-column>  <!-- 5.完成element属性prop注入 --><el-table-column label="姓名" prop="name" width="150"></el-table-column><el-table-column label="籍贯" prop="place"></el-table-column><el-table-column label="操作" width="150"><template #default><el-button type="primary" link>编辑</el-button><el-button type="danger" link>删除</el-button></template></el-table-column></el-table></div><Edit />
</template>……
</style>

细节:

​ 此处axios获取后台数据时,需要将请求放入函数中,最好是异步方式。放入函数中便于后期调用。异步axios节约性能

补充:

​ 后台接口的数据,是通过前端的Mock来模拟后台的数据完成的开发

步骤二:演示

  • 查看浏览器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 数据渲染成功

5.3实现删除功能

说明:

思路:获取当前行的id ->通过id调用删除接口-→更新最新的列表

步骤一:完成axios请求,实现删除功能

  • 修改项目App.vue文件,完成删除功能
<script setup>
import Edit from './components/Edit.vue'
import axios from 'axios';
import { onMounted, ref } from 'vue';……// 功能二: 删除功能const onDelete = (id)=>{// 2.通过id调用删除接口axios.delete(`/del/${id}`)// 3.更新最新列表getList()
}// TODO: 编辑功能</script><template><div class="app"><el-table :data="list"><el-table-column label="ID" prop="id"></el-table-column>  <el-table-column label="姓名" prop="name" width="150"></el-table-column><el-table-column label="籍贯" prop="place"></el-table-column><el-table-column label="操作" width="150"><template #default="{row}"><el-button type="primary" link>编辑</el-button><el-button type="danger" @click="onDelete(row.id)" link>删除</el-button> <!--1.Element获取数据的id,通过点击事件传入方法--></template></el-table-column></el-table></div><Edit />
</template>……
</style>

说明:

​ element-plus可以通过的属性#default="{row}">来获取每一行的数据信息

步骤二:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当点击删除后,页面元素发生改变

5.4实现编辑功能

说明:

​ 思路:打开弹窗 -> 回填数据 ->调用接口

步骤一:实现编辑功能逻辑

  • 修改项目App.vue文件,完成编辑功能
<script setup>
import Edit from './components/Edit.vue'
import axios from 'axios';
import { onMounted, ref } from 'vue';……
// 功能三: 编辑功能
// 1.获取子组件
const editRef = ref(null)
// 3.调用字组件打开方法
const onOpen= (row)=>{editRef.value.openDialog(row) // 细节,调用组件方法,需要添加括号。并且传递数据给组件,便于数据回填
}
</script><template><div class="app"><el-table :data="list"><el-table-column label="ID" prop="id"></el-table-column><el-table-column label="姓名" prop="name" width="150"></el-table-column><el-table-column label="籍贯" prop="place"></el-table-column><el-table-column label="操作" width="150"><template #default="{row}"><el-button type="primary" @click="onOpen(row)" link>编辑</el-button><el-button type="danger" @click="onDelete(row.id)" link>删除</el-button> <!--2.Element获取数据的id,通过点击事件传入方法--></template></el-table-column></el-table></div><Edit ref="editRef" @on-update="getList"/>
</template>……
</style>

步骤二:完成axios请求,实现编辑数据的回填与更新

  • 修改项目Edit.vue文件,完成编辑数据回填、数据更新
<script setup>
// TODO: 编辑
import { reactive, ref } from 'vue'
import axios from 'axios';// 3.接收响应式数据
const from = reactive({name: String,place: String,id: Number
})// 4.3.1定义emit传入父组件的调用方法
const emit = defineEmits(["on-update"])
// 弹框开关
const dialogVisible = ref(false)
// 1.打开弹窗
const openDialog=(row)=>{ dialogVisible.value=true //打开弹窗from.name = row.namefrom.place = row.placefrom.id = row.id
}
// 2.暴露打开弹窗方法
defineExpose({openDialog // 细节,暴露组件对象,不需要添加括号
})
// 4.更新数据
const onUpdate=(id)=>{// 4.1调用接口axios.patch(`/edit/${id}`, { // 记得导入axios包name: from.name ,place: from.place 
})// 4.2关闭弹窗dialogVisible.value=false //关闭弹窗// 4.3刷新数据emit("on-update") // 此时的子组件向父组件通信时,不传递参数
}
</script><template><el-dialog v-model="dialogVisible" title="编辑" width="400px"><el-form label-width="50px"><el-form-item label="姓名"><el-input placeholder="请输入姓名" v-model="from.name"/></el-form-item><el-form-item label="籍贯" ><el-input placeholder="请输入籍贯"  v-model="from.place"/></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="onUpdate(from.id)">确认</el-button></span></template></el-dialog>
</template>

步骤三:演示

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

说明:

​ 当修改数据时,发现网络请求为2个,数据已完成更新,说明数据修改成功

6.状态管理库pinia

6.1概述

Pinia 是 Vue 的专属状态管理库,可以实现跨组件或页面共享状态,是 vuex 状态管理工具的替代品。

Pinia和 Vuex相比,具备以下优势

  1. 提供更加简单的API (去掉了 mutation )
  2. 提供符合组合式API风格的API (和 Vue3 新语法统一)
  3. 去掉了modules的概念,每一个store都是一个独立的模块
  4. 搭配 TypeScript 一起使用提供可靠的类型推断

6.2基本用例

知识加油站

1.PNPM包管理工具使用

vue3+TS+vite+pnpm 从0到1搭建移动端项目 - 掘金 (juejin.cn)

2.Vite介绍

什么是 Vite_vite是什么_前端之神的博客-CSDN博客

3.Axios和Ajax区别

AxiosAjax 都是用于在前端发送 HTTP 请求的技术,但它们之间存在一些重要的区别:

  1. 底层实现

    • Ajax(Asynchronous JavaScript and XML)是一种基于原生 JavaScript 的技术,通过使用浏览器提供的 XMLHttpRequest 对象来实现异步请求和响应处理。
    • Axios 是一个基于 Promise 的 HTTP 客户端,它并不依赖于浏览器环境,因此可以在浏览器和 Node.js 中使用。
  2. API 使用

    • Ajax 使用比较底层的 API,需要手动创建和配置 XMLHttpRequest 对象,然后监听事件来处理请求和响应。
    • Axios 提供了更高级和易用的 API,通过简单的函数调用来发送请求和处理响应,同时支持 Promise,使得处理异步请求更加方便。
  3. 功能

    • Axios 提供了许多现代化的功能,如请求和响应拦截、请求取消、全局配置、Promise 支持等,这些功能使得在复杂场景下更容易管理和控制请求。
    • Ajax 提供的功能较为基本,需要手动实现一些高级功能。
  4. 跨域请求

    • Ajax 在跨域请求时需要处理跨域问题,例如使用 JSONP 或配置 CORS 等。
    • Axios 在发送跨域请求时可以自动处理跨域问题,提供了一种更便捷的方式来处理跨域请求。
  5. 拦截器

    • Axios 支持请求和响应拦截器,可以在请求和响应被发送或接收之前对其进行拦截和处理。
    • Ajax 需要手动实现拦截器的逻辑。

​ 总的来说,虽然 AxiosAjax 都可以用于发送 HTTP 请求,但 Axios 在功能和使用上更加现代化和便捷,尤其在复杂的前端项目中更受欢迎。

更多补充:ajax与axios的使用和对比 - 掘金 (juejin.cn)

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

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

相关文章

我的读书摘记《点燃孩子的学习动力:关于儿童学习兴趣的真相》

德韦克认为乔丹的经历揭示了那些最卓越的学习者身上的一个秘密&#xff1a;人的天赋&#xff0c;是可以不断发展的&#xff01;不管早期的天赋如何&#xff0c;人终将不断超越自己&#xff0c;发展自己的天赋。 思维方式决定了学习的成功与否&#xff01;这也意味着&#xff0…

【数据结构】三、栈和队列:5.顺序队列(循环队列)(初始化,判空判满,入队,出队,实例)

文章目录 队列Queue逻辑结构物理&#xff08;存储&#xff09;结构基本操作1.顺序队列&#xff08;循环队列&#xff09;1.1初始化1.2判空&判满1.2.1判空1.2.2判满方案一方案二方案三 1.3入队循环队列 1.4出队1.5获取队头元素1.6获取队列元素个数❗1.7循环队列c实例 队列Qu…

安卓Activity的setContentView()流程分析

目录 前言一、Activity的视图加载过程1.1 视图结构1.2 流程分析1.2.1 Activity.java -->setContentView()1.2.2 Activity.java -->getWindow()1.2.3 PhoneWindow.java -->setContentView()1.2.4 PhoneWindow.java --->installDecor()1.2.4.1 PhoneWindow.java ---&…

SD-WAN怎样保障网络稳定

随着企业网络的日益复杂&#xff0c;如何确保线路的稳定性和高效性成为了网络管理的一大挑战。尤其是在线路出现故障、质量下降或拥塞时&#xff0c;如何快速响应并切换到最佳线路&#xff0c;就显得尤为重要。SD-WAN&#xff0c;作为一种新型的网络架构&#xff0c;为用户提供…

周报不止是汇报进度,如何用周报轻松提升团队协作效率?

周报是工作中常见的沟通工具&#xff0c;对于项目经理来说尤其重要。写周报不仅仅是为了完成一项任务&#xff0c;它更是项目管理中不可或缺的环节&#xff0c;它不仅有助于项目经理跟踪项目进度&#xff0c;还加强了团队成员间的沟通与协作。以下是几个关键的原因&#xff1a;…

北京车展打响新汽车“第一枪”,长安造车40年,开启“汽车机器人”时代

4月25日&#xff0c;睽违四年的2024(第十八届)北京国际汽车展览会正式启幕&#xff0c;此次车展以“新时代 新汽车”为主题&#xff0c;吸引全球1500余家主流车企及零部件制造商同台“打擂”。其中&#xff0c;长安汽车以“数智启源随你而变”为主题&#xff0c;携各子品牌及合…

掌握未来通信技术:5G核心网基础入门

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;5GC笔记仓 朋友们大家好&#xff0c;本篇文章是我们新内容的开始&#xff0c;我们本篇进入5GC的学习&#xff0c;希望大家多多支持&#xff01; 目录 一.核心网的演进2G核心网2.5G核心网3G核心网4G…

六个月滴滴实习:轻松、舒心又高薪!

不久前&#xff0c;一位在滴滴后端研发部门实习了六个月的小伙伴在牛客网上分享了他的实习体验&#xff0c; 作者详细描述了他在滴滴的实习生活。 从他的叙述中&#xff0c;我们可以感受到与其他互联网公司相比&#xff0c;滴滴的工作环境显得相对轻松和舒适。 他提到&#x…

ROS摄像机标定

文章目录 一、环境准备二、摄像头标定2.1 为什么要标定2.2 标定前准备2.2.1 标定板2.2.2 摄像头调焦 2.3 开始标定2.4 测试标定结果 总结参考资料 一、环境准备 安装usb_cam相机驱动 sudo apt-get install ros-noetic-usb-cam 安装标定功能包 sudo apt-get install ros-noet…

深度学习——常用激活函数解析与对比

1、 简介 在神经网络中&#xff0c;激活函数扮演着至关重要的角色。它们的主要目的是引入非线性因素&#xff0c;使得网络能够学习和表示更加复杂的函数映射。以下是激活函数应具备的特点&#xff0c;以及这些特点为何重要的详细解释&#xff1a; 引入非线性有助于优化网络&am…

【Ant-Desgin-React 步骤条】步骤条配合组件使用

步骤条配合组件使用 基础使用多分组进度 基础使用 /* eslint-disable no-unused-vars */ import React, { useState } from react import { Button, message, Steps, theme } from antd import After from ./components/after import Now from ./components/now const steps …

Docker 安装 Mongo

创建宿主机目录 在你的宿主机上创建必要的目录来存储 MongoDB 的数据和配置文件。这样做可以保证即使容器被删除&#xff0c;数据也能得到保留。 mkdir -p /develop/mongo/data mkdir -p /develop/mongo/config创建 MongoDB 配置文件 创建一个名为 mongod.conf 的 MongoDB 配…

RestfulApi RestTemplate代码规范介绍

1.介绍 1.1 RestfulApi Restful API 是一种设计风格&#xff0c;代表了使用 HTTP 协议构建 web 服务的一种架构原则。REST&#xff08;Representational State Transfer&#xff09;的核心思想是&#xff0c;通过 URL 定位资源&#xff0c;使用 HTTP 方法&#xff08;GET, POS…

MySQL多版本并发控制mvcc原理浅析

文章目录 1.mvcc简介1.1mvcc定义1.2mvcc解决的问题1.3当前读与快照读 2.mvcc原理2.1隐藏字段2.2版本链2.3ReadView2.4读视图生成原则 3.rc和rr隔离级别下mvcc的不同 1.mvcc简介 1.1mvcc定义 mvcc(Multi Version Concurrency Control)&#xff0c;多版本并发控制&#xff0c;是…

golang学习笔记(defer基础知识)

什么是defer defer语句用于golang程序中延迟函数的调用&#xff0c; 每次defer都会把一个函数压入栈中&#xff0c; 函数返回前再把延迟的函数取出并执行。 为了方便描述&#xff0c; 我们把创建defer的函数称为主函数&#xff0c; defer语句后面的函数称为延迟函数。延迟函数…

npm常用的命令大全(2024-04-21)

nodejs中npm常见的命令 npm主要是node包管理和发布的工具。 npm官网网址&#xff1a;npm | Homehttps://www.npmjs.com/官网英文文档&#xff1a; npm DocsDocumentation for the npm registry, website, and command-line interfacehttps://docs.npmjs.com/about-npm官网中文文…

同城便民信息小程序源码系统:相亲交友+拼车顺风车功能 带完整的安装代码包以及搭建教程

在信息化、数字化的时代&#xff0c;人们的生活越来越离不开各种智能应用。其中&#xff0c;小程序作为一种轻量级、便捷的应用形式&#xff0c;正逐渐渗透到我们日常生活的方方面面。今天&#xff0c;我们要介绍的这款“智慧同城便民信息小程序源码系统”&#xff0c;不仅集成…

每日一题:跳跃游戏II

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…

CAS机制(Compare And Swap)源码解读与三大问题

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java源码解读-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1. 前言 2. 原子性问题 3. 乐观锁与悲观锁 4. CAS操作 5. CAS算法带来的…

西米支付:支付行业中,“清算、结算、清结算”之间的区别

做支付最头疼的三个词莫过于“清算、结算、清结算”&#xff0c; 傻傻分不清&#xff0c;偶尔清晰偶尔混沌&#xff0c;有时候吧觉得自己很清晰了&#xff0c;突然跟别人聊天或者看书、看文章时又觉得糊涂起来了&#xff0c;在一些场景里好像很清晰&#xff0c;但是到了另一些…