第三阶段:vue3的学习与实战
Day9:
1.Vue3的优势:
1.更容易维护:
1.组合式API
2.更好的TypeScript支持
2.更快的速度:
1.重写diff算法
2.模版编译优化
3.更高效的组件初始化
3.更小的体积:
1.良好的Treeshaking
2.按需引入
4.更优的数据响应式:
Proxy
2.Vue3 组合式APIvs Vue2 选项式 API
需求:点击按钮,让数字 +1
<script>
export default {
data () {
return {
count:0
}
},
methods: {
addCount (){
this.count++
}
}
}
</script>
<script setup>
import { ref } from 'vue'
const count = ref(0)
const addCount = () => count.value++
</script>
1.代码量变少了
2.分散式维护转为集中式维护,更易封装复用
3.项目目录和关键文件
1.关键文件:
1.vite.config.js-项目的配置文件 基于vite的配置
2.package.json-项目包文件 核心依赖项变成了 Vue3.x和 vite
3.main.js-入口文件 createApp函数创建应用实例
4.app.vue-根组件 SFC单文件组件 script-template-style
变化-:脚本script和模板template顺序调整
变化二:模板template不再要求唯一根元素
变化三:脚本script添加setup标识支持组合式API
5.index.html-单页入口 提供id为app的挂载点
4.setup选项中写代码的特点
<template>
<!-- 使用数据和方法-->
{{ message }}
<button @click="logMessage">
log message
</button>
</template>
5. script setup语法糖
1.原始复杂写法
<script>
export default {
setup (){
// 数据
const message = 'this is message'
// 函数
const logMessage = () => {
console.log(message)
}
return {
message,
logMessage
}
}
}
</script>
2.语法糖写法
<script setup>
// 数据
const message ='this is message
// 函数
const logMessage = () =>{
console.log(message)
}
</script>
3.总结
1.setup选项的执行时机?
beforecreate钩子之前 自动执行
2.setup写代码的特点是什么?
定义数据+函数 然后以对象方式return
3.<script setup>解决了什么问题?
经过语法糖的封装更简单的使用组合式API
4.setup中的this还指向组件实例吗?
指向undefined
6.
1.reactive()
1.作用:接受对象类型数据的参数传入并返回一个响应式的对象
2.核心步骤:
<script setup>
// 导入
import { reactive } from 'vue'
// 执行函数 传入参数 变量接收5
const state = reactive(对象类型数据)
</script>
1. 从 vue 包中导入 reactive 函数
2.在 <script setup>中执行 reactive 函数并传入类型为对象的初始值,并使用变量接收返回值
2.ref()
1.作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
2.核心步骤:<script setup>
// 导入
import { ref } from 'vue'
// 执行函数 传入参数 变量接收
const count = ref(简单类型或者复杂类型数据)
</script>
1.从 vue 包中导入 ref 函数
2.在<script setup>中执行 ref 函数并传入初始值,使用变量接收 ref 函数的返回值
3.总结
1.reactive和ref函数的共同作用是什么?
用函数调用的方式生成响应式数据
2. reactive vs ref ?
1.reactive不能处理简单类型的数据
2.ref参数类型支持更好但是必须通过.value访问修改
3.ref函数的内部实现依赖于reactive函数
3.在实际工作中推荐使用哪个?
推荐使用ref函数,更加灵活统一
7.computed计算属性函数
计算属性基本思想和Vue2的完全一致,组合式API下的计算属性只是修改了写法
核心步骤:1.导入computed函数
2.执行函数 在回调参数中return基于响应式数据做计算的值,用变量接收
<script setup>
// 导入
import { computed }from 'vue'
// 执行函数 变量接收 在回调参数中return计算值
const computedState = computed(() => {
return 基于响应式数据做计算之后的值
})
</script>
3.总结
最佳实践
1.计算属性中不应该有“副作用”
比如异步请求/修改dom
2.避免直接修改计算属性的值
计算属性应该是只读的,特殊情况可以配置 get set
8.watch函数
1.作用:侦听一个或者多个数据的变化,数据变化时执行回调函数
2.俩个额外参数:1.immediate(立即执行)2.deep(深度侦听)
1.基础使用-侦听单个数据
1.导入watch函数
2.执行watch函数传入要侦听的响应式数据(ref对象)和回调函数
<script setup>
// 1.导入watch
import { ref, watch } from 'vue
const count=ref(0)
//2.调用watch 侦听变化
watch(count,(newValue,oldValue) => {
console.log(`count发生了变化,老值为${oldValue},新值为${newValue}`)
})
</script>
2.immediate
说明:在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调
const count =ref(0)
watch(count, () => {
console.log('count发生了变化')
}, {
immediate: true
})
3.精确侦听对象的某个属性
需求:在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调
const info = ref({
name :'cp'
age: 18
})
watch(
() => info.value.age,
() => console.log('age发生变化了')
)
4.总结
1.作为watch函数的第一个参数,ref对象需要添加.value吗?
不需要,第一个参数就是传 ref 对象
2.watch只能侦听单个数据吗?
单个 或者 多个
3.不开启deep,直接监视 复杂类型,修改属性 能触发回调吗?
不能,默认是浅层侦听
4.不开启deep,精确侦听对象的某个属性?
可以把第一个参数写成函数的写法,返回要监听的具体属性
9.Vue3的生命周期API(选项式 VS 组合式)
选项式API 组合式API
beforeCreate/created setup
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
1.组合式API下的父传子
1.基本思想
1.父组件中给子组件绑定属性
2.子组件内部通过props选项接收
2.defineProps 原理:就是编译阶段的一个标识,实际编译器解析时,遇到后会进行编译转换
3.总结
父传子
1.父传子的过程中通过什么方式接收props?
defineProps({属性名:类型})
2.setup语法糖中如何使用父组件传过来的数据?
const props=defineProps({属性名:类型})
props.xxX
子传父
1.子传父的过程中通过什么方式得到emit方法?
defineEmits(「'事件名称’)
2.怎么触发事件
emit('自定义事件名'参数)
10.如何使用(以获取dom为例 组件同理)
<script setup>
import { ref } from 'vue'
//1.调用ref函数得到ref对象
const h1Ref = ref(null)
</scrip>
<templat>
<!-- 2.通过ref标识绑定ref对象 -->
<h1 ref="h1Ref">我是dom标签h1</h1>
</template>
1.调用ref函数生成一个ref对象
2.通过ref标识绑定ref对象到标签
3.总结
1.获取模板引用的时机是什么?
组件挂载完毕
2.defineExpose编译宏的作用是什么?
显式暴露组件内部的属性和方法
11.
1.跨层传递普通数据
1.顶层组件通过provide函数提供数据
2.底层组件通过inject函数获取数据
顶层组件:provide('key',顶层组件中的数据)
底层组件:const message = inject('key')
2.跨层传递响应式数据
在调用provide函数时,第二个参数设置为ref对象
顶层组件:provide('app-key',ref对象)
底层组件:const message =inject('app-key')
3.跨层传递方法
顶层组件可以向底层组件传递方法,底层组件调用方法修改顶层组件中的数据
顶层组件:const setCount = () => {
count.value++
}
provide('setCount-key', setCount)
底层组件:const setCount = inject('setCount-key')
12.Vue3.3新特性-defineoptions
1.背景说明:
1.有<script setup>之前,如果要定义 props,emits 可以轻而易举地添加一个与 setup 平级的属性。
2.但是用了 <script setup>后,就没法这么干了 setup 属性已经没有了,自然无法添加与其平级的属性。
2.为了解决这一问题,引入了 defineProps 与 defineEmits 这两个宏。但这只解决了 props 与 emits 这两个属性。
1.如果我们要定义组件的 name 或其他自定义的属性,还是得回到最原始的用法--再添加一个普通的 <script>标签
2.这样就会存在两个<script>标签。让人无法接受,
3.所以在 Vue 3.3 中新引入了 defineOptions 宏。顾名思义,主要是用来定义 Options AP!的选项。可以用defineOptions 定义任意的选项,props,emits,expose,slots 除外(因为这些可以使用 defineXXX 来做到)
13.Vue3 中的v-model和 defineModel
在vue3中,自定义组件上使用v-mode1,相当于传递一个modelValue属性,同时触发 update:modelValue 事件
<Child v-model="isVisible">
// 相当于
<Child :modelValue="isVisible" @update:modelValue="isVisible=$event">
我们需要先定义 props,再定义 emits 。其中有许多重复的代码。如果需要修改此值,还需要手动调
<script setup>
const modelValue = defineModel()
modelValue .value++
</script>
14.什么是Pinia
1.Pinia 是 Vue 的最新 状态管理工具 ,是 Vuex 的 替代品
1.提供更加简单的API(去掉了 mutation)
2.提供符合,组合式风格的API(和 Vue3 新语法统一)
3.去掉了 modules 的概念,每一个 store 都是一个独立的模块
4.配合 TypeScript 更加友好,提供可靠的类型推断
2.手动添加Pinia到Vue项目
在实际开发项目的时候,关于Pinia的配置,可以在项目创建时自动添加现在我们初次学习,从零开始:
1.使用 Vite 创建一个空的 Vue3 项目
npm create vue@latest
2.按照官方文档 安装 pinia 到项目中
3.action异步实现
1.编写方式:异步action函数的写法和组件中获取异步数据的写法完全一致
2.接口地址:http://geek.itheima.net/v10/channels
3.需求:在Pinia中获取频道列表数据并把数据渲染App组件的模板中
4.总结
1. Pinia是用来做什么的?
新一代的状态管理工具,替代vuex
2.Pinia中还需要mutation吗?
不需要,action 既支持同步也支持异步
3。Pinia如何实现getter?
computed计算属性函数
4.Pinia产生的Store如何解构赋值数据保持响应式?
storeToRefs
5.Pinia 如何快速实现持久化?
pinia-plugin-persistedstate