目录
vite
vite是新一代前端构建工具。
优势:
- 开发环境中,无需打包操作,可快速的冷启动
- 轻量快速的热重载(HMR)
- 真正的按需编译,不再等待整个应用编译完成
传统构建工具:
vite:
创建vue3项目的两种方式
vue-cli
vue-cli需要达到4.5.1以上版本。以下为创建步骤:
1:vue create 项目名
2:选择vue3
3:cd 项目文件夹
4:npm run serve
vite
1:npm init vite-app 项目名
2:cd 项目文件夹
3:npm run dev
初始化工程
main.js
引入了createApp这个工厂函数
App.vue
可以不用一个根标签div
Composition API
setup
- vue3中的一个新的配置项,值为一个函数。
- setup是所有Composition API“表演的舞台”
- 组件中所有的数据、方法等等都要配置在setup中。
- 如果setup返回的是一个对象,那么返回的对象的属性、方法可在模板中直接使用;如果返回的是一个渲染函数可以自定义渲染内容。
<template>
<h1>{{name}}</h1>
<button @click="sayHi">点击</button>
</template>
<script>
export default {
name: 'HelloWorld',
setup(){
let name = '小李'
function sayHi(){
alert(`哈喽,我叫${name}`)
}
return {
name,
sayHi
}
}
}
</script>
vue2的配置项可以拿到vue3的setup内的数据和方法,但是vue3的setup不能拿到vue2的数据和方法,如果两者重名vue3优先,所以不建议混合使用。
- setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return都对象中的属性。
setup的注意点
- setup的执行时期:是在beforeCreate之前执行一次,this是undefined。
- setup的参数:1、props,即父组件传给子组件的数据,可以在setup里面拿到。2、context,即上下文对象,其中包含attrs(父组件通过props传的数据)、 emit(自定义事件对象)、 slots(插槽,命名建议使用v-slot:name)。
ref
让数据变成响应式数据,需要将数据用ref()包裹,让数据变成引用实现对象,这里利用的是get、set实现,所以在更改数据的值时需要利用.value。注意,ref需要引入进来才能使用。
<template>
<h2>{{age}}</h2>
<button @click="changeAge">长大</button>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'HelloWorld',
setup(){
let age = ref(1)
function changeAge(){
age.value += 1
}
return {
age,
changeAge
}
}
}
</script>
如果.value的值还是一个对象,他使用的是proxy来处理。
<template>
<h2>{{job.type}}</h2>
<h2>{{job.money}}</h2>
<button @click="changeWork">改变</button>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'HelloWorld',
setup(){
let job = ref({
type:'前端',
money:'30K'
})
function changeWork(){
job.value.type = 'ui'
}
return {
job,
changeWork
}
}
}
</script>
reactive
将对象类型转换响应式数据,其他基本数据类型仍然使用ref,它接收了该对象之后返回的是一个proxy代理对象,通过代理对象操作源对象内部数据进行操作,并且reactive定义的响应式数据是深层次的。
<template>
<h2>{{job2.type}}</h2>
<h2>{{job2.money}}</h2>
<button @click="changeWork2">改变2</button>
</template>
<script>
import {reactive} from 'vue'
export default {
name: 'HelloWorld',
setup(){
let job2 = reactive({
type:'前端',
money:'30K'
})
function changeWork2(){
job2.type = 'ui'
}
return {
job2,
changeWork2
}
}
}
</script>
vue2响应式和vue3响应式的区别
vue2
实现原理:
- 对象类型: 通过 object.defineProperty() 对属性的读取、修改进行拦截(数据劫持)
- 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包惠)
存在问题:
- 新增属性或是删除属性界面不会更新(利用$set 或 $delete来新增或删除)
- 直接根据下标修改页面不会更新(利用数组的方法进行修改)
vue3
解决了以上vue2存在的两个问题,可以直接新增、删除、下标修改。
实现原理:
将接收到的对象返回成一个代理对象,再使用代理对象中的get 和 set进行对数据读取、修改、新增的捕获。实现删除的利用的是deleteProperty对对象的某一属性进行删除。
Reflect
在windows中的对象Reflect也可以获取并且对其进行修改属性等操作。Object中进行对对象的某些操作时,如果存在错误操作时,代码会停止运行,但是如果是在Reflect中操作时会返回true或false,而不让整个代码停止运行。在vue3中的修改、添加等操作就是在Reflect中使用。
computed
在vue2中作为一个配置项,在vue3中是一个函数,
//简写
person.all = computed(()=>{
return person.job.j1.money
})
//完整
person.all = computed({
get(){
return person.job.j1.money
},
set(value){
return value
}
})
watch
在vue2中,watch是作为一个配置项,使用方法如下:
watch:{
sum:{
immediate:true,
deep:true,
handler(newVal,oldVal){
console.log('sum的值发生改变了',newVal,oldVal)
}
}
},
但在vue3中,它被作为一个组合式api来使用,所以在vue3中可以多次调用watch这个函数,这个函数的参数分别是,监视的值、执行的函数、其他配置项。
仅监视一个ref定义的值:
watch:{
sum:{
immediate:true,
deep:true,
handler(newVal,oldVal){
console.log('sum的值发生改变了',newVal,oldVal)
}
}
},
当监视的是多个ref定义的数据时,使用数组存放数据,并且newValue和oldValue也是数组存放对应的数据:
let sum = ref(0)
let sum2 = ref(1)
watch([sum,sum2],(newVal,oldVal)=>{
console.log(newVal,oldVal)
},{immediate:true})//[1, 1] [0, 1]
当监视的是reactive定义的一个响应式数据时的区别:
- 目前有的版本oldValue拿不到;
- 并且使用reactive定义的数据无论有多少层都强制开启了深度测试,deep:fasle无效;
- 如果想要监视的是对象中的某一个属性时,需要写成函数将该属性返回,此时可以拿到oldValue;
- 如果想要监视的是对象中的某一些属性时,需要返回的属性放在一个数组中。
- 如果监视的是对象的一个属性,deep:true有效,当监视的是一个对象中的对象,更改的是对象中对象的某一个属性时,需要开启深度监听。
- 当监听ref所定义的对象时,需要监听的是对象的value,该value就是借助reactive所定义的对象,或者是可以加上深度监视。
let person = reactive({
age:12,
sex:'女'
})
watch(person,(newVal,oldVal)=>{
console.log(newVal,oldVal)
})
watch(()=>person.age,(newVal,oldVal)=>{
console.log(newVal,oldVal)
})
watch([()=>person.age,()=>person.sex],(newVal,oldVal)=>{
console.log(newVal,oldVal)
})
watch(()=>person.job,(newVal,oldVal)=>{
console.log(newVal,oldVal)
},{deep:true})
wacthEffect
wacthEffect进行监视时,不需要指明监视的属性,监视的回调中用到哪个属性就监视哪些属性。
wacthEffect与computed相似,但是computed注重的是返回的值,即computed所依赖的值变了,所返回的值也变了。wacthEffect更注重的是过程,只要用到的值改变了,监视的回调函数就重新执行,不需要写返回值。
watchEffect(()=>{
let x1 = person.job.j1.money
console.log('有属性发生改变',x1)
})
生命周期函数
在vue3中可以以配置项的形式写也可以以组合式API的形式写,必须在使用之前引入,并且在使用组合式API这种方式时,setup都相当于beforeCreate以及create,所以beforeCreate以及create没办法以这种方式写。
onMounted(()=>{
console.log('----onMounted---')
})
同时使用时,除了setup、beforeCreate以及create,组合式API的比配置项的快一点,但是建议不要同时使用。
hooks函数
当写了一个功能的方法,其中包含数据、方法等内容,为了可以让多个组件可以使用这个方法,就可以在src文件夹内新建一个hooks文件夹,再在里面新建js文件,将跟功能相关的数据、方法等放入js文件夹的一个函数中,再将有用的数据return出来,如果想要在其他地方使用这个功能,就可以直接引入即可。
toRef
对于一个对象,使用p.name拿一个对象中的属性时,该属性的内容不是响应式的,但是当使用toRef去设置这个属性值时,所拿到的属性就会是响应式的。它有两个参数,第一个参数是一个对象,第二个参数是对象中的某一属性。
toRef只能处理一个属性,但是toRefs可以批量处理一个对象里的所有属性,无需指定属性,返回的将是该对象中的所有属性。
money:toRef(person.job.j1,'money')
...toRefs(person)