vue3的优点
1.新增一些组合api可以更好的组织、封装、服用代码
比如setup入口函数,reactive 包装数组,toref将转换响应式对象中某个属性为单独响应式数据
2.新特性:Fragment(代码段)、Teleport(传送对html位移)、Suspense(异步组件加载期间可以加载一些额外内容,比如loading)。
3.性能优化,数据绑定原理发生变化,使用proxy将整个对象进行绑定
4..可以更好的兼容Vue3.0+ts
1.如何创建一个vue3项目
npm init vite-app
2.如何创建Vue3实例
1.导入createApp函数
2.编写一个根组件 App.vue 导入进来
3.基于根组件创建应用实例
4.挂载到index.html的#app容器中
import{createApp} from 'vue'
improt App from './App.vue'
cosnt app=createApp(App)
app.monut('#app')
3.setup入口函数
是作为组合API的入口函数
- setup 的执行时机是什么?
执行机制早于Vue2的beforeCreate.
- setup 中的 this 指向是什么?
他的this绑定undefined
- 想在模板中使用 setup 中定义的数据,该怎么做?
数据和方法写在setup函数中,通过return进行返回到模板中使用
一把返回值是一个对象,也可以是一个函数
4.reactive 包装数组
reactive是一个函数,用来将普通对象/数组包装成响应式式数据使用(基于proxy),无法直接处理基本数据类型
用法就是将需要响应式的数据用reactive包裹起来
列表删除
使用场景,比如列表数据,点击删除,就需要对这个数组进行包装
抽离函数(优化)
将同一功能的数据和业务逻辑抽离为一个函数,代码更易读,更容易复用。
根据不同的业务进行划分,再在setup中进行一个赋值(也就是一个浅拷贝)
然后return出对应的数据
添加功能
比如添加个数据直接添加到原数组中,后续修改这数据,会影响数组中的数据.
解决方法:
用Object.assign进行一个拷贝,将拷贝的到的对象再添加到新的数组
用Object.assign({},添加的数据) 第一个参数为一个空对象,第二个参数是需要拷贝的数据
然后再添加到新数组
拆分文件
在不同的文件存储数据和方法,然后使用时候再引入这个文件,然后对数据进行一个拷贝
5.为什么换成 Proxy
Vue3(组合 API)常用的生命周期钩子有 7 个,可以多次使用同一个钩子,执行顺序和书写顺序相同。
vue3的生命周期周期
setup、onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted
6.toref
作用:如果是只需要对象的一个属性,如果是整个对象比较浪费性能,只需要利用toref将这个属性retrun出去。
转换响应式对象中某个属性为单独响应式数据,并且转换后的值和之前是关联的
cost obj=reactive({
name:'ifer',
age:10
)
cosnt name=toRef(obj,'name')
return {name}
如果是用解构出想要的那个数据,会失去响应式
7.ref函数
ref 函数,常用于把简单数据类型包裹为响应式数据,注意 JS 中操作值的时候,需要加 .value 属性,模板中正常使用即可。
ref与toref的区别就在于ref是将简单数据类型直接包裹成响应式数据,而toref则书包裹对象的属性,这个对象还是需要使用reactive进行包裹
使用:计数器,能够通过 ref 属性获取 DOM 或组件
获取单个dom
<div ref="dom">我是box</div>
const dom = ref(null)
return {dom}
获取多个dom或组件
<li v-for="i in 4" :key="i" :ref="setDom">第 {{ i }} li</li>
const domList = []
const setDom = (el) => {
domList.push(el)
}
8.computed
与vue2.x没什么区别,用法不同了
可以传入对象的属性,
比如:
setup() {
const person = reactive({
firstName: '朱',
lastName: '逸之',
})
// 也可以传入对象,目前和上面等价
person.fullName = computed({
get() {
return person.firstName + ' ' + person.lastName
},
set(value) {
const newArr = value.split(' ')
person.firstName = newArr[0]
person.lastName = newArr[1]
},
})
- 给 computed 传入函数,返回值就是计算属性的值。
- 给 computed 传入对象,get 获取计算属性的值,set 监听计算属性改变。
9.watch
点击自增的效果
监听单个是单个元素,监听多个则是数组的形式
立即触发监听:immediate:true
修改对象的属性并不会触发监听,需要开启深度监听
深度监听:deep:true
setup() {
const age = ref(18)
const num = ref(0)
const handleClick = () => {
age.value++
num.value++
}
// 数组里面是 ref 数据
watch([age, num], (newValue, oldValue) => {
console.log(newValue, oldValue)
})
return { age, num, handleClick }
注意:监听 reactive 数据时,强制开启了深度监听,配置无效;监听对象的时候 newValue 和 oldValue 是全等的
10. watchEffect
1. 不指定监视哪一个,这里面用到了谁就监听谁
2. 第一次的时候肯定会执行
例如对 obj.hobby.eat 的修改,由于这里用到了 obj.hobby.eat,则会执行
!注意如果这里用的是 obj 则不会被执行
11.响应式数据的判断
- isRef: 检查一个值是否为 ref 对象。
- isReactive: 检查一个对象是否是由 reactive 创建的响应式代理。
- isReadonly: 检查一个对象是否是由 readonly 创建的只读代理。
- isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理。
12.setup 函数参数
比如父传子的时候,父组件的setup中return的数据,子自组件引入后,通过props接收,
然后在子组件setup(props){}
子传父在父传子的基础上setup(props, { emit }),通过emit触发事件
emits: ['change-money'],
setup(props, { emit }) {
// attrs 捡漏、slots 插槽
const changeMoney = (m) => {
// #2 子组件通过 emit 进行触发
emit('change-money', m)
}
return { changeMoney }
},
-
setup 第一个参数的是什么?
props
-
第二个参数 context 中包含什么信息?
需要触发的事件,以及传参
13.v-model
vue2中v-model语法糖
<Son :value="msg" @input="msg=$event" />
vue3中v-model语法糖
<Son :modelValue="msg" @update:modelValue="msg=$event" />
14.Fragment
- Vue2 中组件必须有一个跟标签。
- Vue3 中组件可以没有根标签,其内部会将多个标签包含在一个 Fragment 虚拟元素中。
- 好处:减少标签层级和内存占用。
15.Teleport
移动html标签的位置
传送,能将特定的 HTML 结构(一般是嵌套很深的)移动到指定的位置,解决 HTML 结构嵌套过深造成的样式影响或不好控制的问题。
<script>
import { ref } from 'vue'
import Dialog from './Dialog.vue'
export default {
name: 'Child',
components: {
Dialog,
},
setup() {
const bBar = ref(false)
const handleDialog = () => {
bBar.value = !bBar.value
}
return {
bBar,
handleDialog,
}
},
}
</script>
16.Suspense
异步组件加载期间,可以使用此组件渲染一些额外的内容,增强用户体验。