文章目录
- 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特性
- 更快的性能: Vue 3 在底层进行了重大的重构,采用了 Proxy 代理,使得响应式数据的追踪更加高效。这带来了更快的渲染性能和更小的包体积。
- Composition API: Vue 3 引入了 Composition API,允许开发人员更灵活地组织和复用组件逻辑。这使得代码更具可维护性和可读性。
- Teleport: Teleport 是 Vue 3 新增的一个功能,它允许将一个组件的内容插入到 DOM 树中的任何位置。这对于在不同的 DOM 结构中渲染组件内容非常有用。
- Fragments: Vue 3 支持使用 Fragments,即不需要额外的父元素包裹组件内容。
- 全局 API 的修改: Vue 3 对全局 API 进行了优化和修改,提供了更好的 TypeScript 支持。
- 模板语法的改进: Vue 3 在模板语法方面进行了一些改进,使其更加强大和灵活。
- 静态类型检查增强: Vue 3 在类型检查方面引入了一些新的功能,提高了代码的可靠性。
1.3组合式API
组合式 API 是 Vue 3 中引入的一种新的编写组件逻辑的方式,旨在提供更灵活、更可维护的代码结构。它是对 Vue 2 中的选项式 API(Options API)的补充和扩展,让开发人员能够更自由地组合和复用组件逻辑。
说明:
使用Vue2和Vue3完成相同的前端功能,发现代码量变少了、从分散式维护转为了集中式维护
2.基本用例-项目搭建
笔记小结:
创建
Vue
应用:pnpm create vue
初始化项目
pnpm install pnpm run dev
访问
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
文件
说明:
dependencies
:
- 这部分定义了项目在生产环境中所需的依赖包。这些依赖包将会随着项目的部署一起打包到生产环境中,用于实际的运行。
- 例如,Vue 3 框架本身、axios、lodash 等常用的库通常会放在
dependencies
中。devDependencies
:
- 这部分定义了项目在开发过程中所需的依赖包。这些依赖包通常不会被包含在最终的生产构建中,只在开发阶段使用。
- 例如,开发工具、测试库、代码检查工具等通常会放在
devDependencies
中。- 运行
npm install
或yarn 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
笔记小结:
setup选项的执行时机?
beforeCreate钩子之前 自动执行
setup写代码的特点是什么?
定义数据 + 函数 然后以对象方式return
<script setup>
解决了什么问题?经过语法糖的封装更简单的使用组合式API
setup中的this还指向组件实例吗?
指向undefinedreactive和ref函数的共同作用是什么 ?
用函数调用的方式生成响应式数据reactive vs ref ?
reactive不能处理简单类型的数据
ref参数类型支持更好但是必须通过.value访问修改
ref函数的内部实现依赖于reactive函数
在实际工作中推荐使用哪个?
推荐使用ref函数,更加灵活,小兔鲜项目主用ref作为watch函数的第一个参数,ref对象需要添加.value吗?
不需要,watch会自动读取watch只能侦听单个数据吗?
单个或者多个不开启deep,直接修改嵌套属性能触发回调吗?
不能,默认是浅层侦听不开启deep,想在某个层次比较深的属性变化时执行回调怎么做?
可以把第一个参数写成函数的写法,返回要监听的具体属性组合式API中生命周期函数的格式是什么?
on + 生命周期名字组合式API中可以使用onCreated吗?
没有这个钩子函数,直接写到setup中组合式API中组件卸载完毕时执行哪个函数?
onUnmounted父子通信(重点)
父传子的过程中通过什么方式接收props?
defineProps( { 属性名:类型 } )setup语法糖中如何使用父组件传过来的数据?
const props = defineProps( { 属性名:类型 } )
子传父子传父的过程中通过什么方式得到emit方法?
defineEmits( [‘事件名称’] )获取模板引用的时机是什么?
组件挂载完毕defineExpose编译宏的作用是什么?
显式暴露组件内部的属性和方法provide和inject的作用是什么?
跨层组件通信如何在传递的过程中保持数据响应式?
第二个参数传递ref对象底层组件想要通知顶层组件做修改,如何做?
传递方法,底层组件调用方法一颗组件树中只有一个顶层或底层组件吗?
相对概念,存在多个顶层和底层的关系
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最佳实践
- 计算属性中不应该有“副作用”。比如异步请求/修改dom,也就是说,再计算属性内部只做普通运算、修改就行,不要有其余操作,就像发送ajax请求
- 避免直接修改计算属性的值。计算属性应该是只读的,也就是说,不要再再计算属性之外再做其余非读操作
步骤二:实现组件模板
<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
函数、provide
和 inject
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相比,具备以下优势
- 提供更加简单的API (去掉了 mutation )
- 提供符合组合式API风格的API (和 Vue3 新语法统一)
- 去掉了modules的概念,每一个store都是一个独立的模块
- 搭配 TypeScript 一起使用提供可靠的类型推断
6.2基本用例
知识加油站
1.PNPM包管理工具使用
vue3+TS+vite+pnpm 从0到1搭建移动端项目 - 掘金 (juejin.cn)
2.Vite介绍
什么是 Vite_vite是什么_前端之神的博客-CSDN博客
3.Axios和Ajax区别
Axios
和 Ajax
都是用于在前端发送 HTTP 请求的技术,但它们之间存在一些重要的区别:
-
底层实现:
- Ajax(Asynchronous JavaScript and XML)是一种基于原生 JavaScript 的技术,通过使用浏览器提供的
XMLHttpRequest
对象来实现异步请求和响应处理。 - Axios 是一个基于 Promise 的 HTTP 客户端,它并不依赖于浏览器环境,因此可以在浏览器和 Node.js 中使用。
- Ajax(Asynchronous JavaScript and XML)是一种基于原生 JavaScript 的技术,通过使用浏览器提供的
-
API 使用:
- Ajax 使用比较底层的 API,需要手动创建和配置
XMLHttpRequest
对象,然后监听事件来处理请求和响应。 - Axios 提供了更高级和易用的 API,通过简单的函数调用来发送请求和处理响应,同时支持 Promise,使得处理异步请求更加方便。
- Ajax 使用比较底层的 API,需要手动创建和配置
-
功能:
- Axios 提供了许多现代化的功能,如请求和响应拦截、请求取消、全局配置、Promise 支持等,这些功能使得在复杂场景下更容易管理和控制请求。
- Ajax 提供的功能较为基本,需要手动实现一些高级功能。
-
跨域请求:
- Ajax 在跨域请求时需要处理跨域问题,例如使用 JSONP 或配置 CORS 等。
- Axios 在发送跨域请求时可以自动处理跨域问题,提供了一种更便捷的方式来处理跨域请求。
-
拦截器:
- Axios 支持请求和响应拦截器,可以在请求和响应被发送或接收之前对其进行拦截和处理。
- Ajax 需要手动实现拦截器的逻辑。
总的来说,虽然 Axios
和 Ajax
都可以用于发送 HTTP 请求,但 Axios
在功能和使用上更加现代化和便捷,尤其在复杂的前端项目中更受欢迎。
更多补充:ajax与axios的使用和对比 - 掘金 (juejin.cn)