一.创建vue3确保vuee-cli是4.5版本以上
二.vue3在main.js中的引入与vue2不同
import {createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
三.sutpu是一个函数,把变量,方法,以前的勾子函数都放里面
async在没在使用Suspense组件时是不能出现在sustpu中的
template下可以不用加div根标签
vue3的方法变量都写到setpu函数体内
vue3也可以使用vue2的配置,vue2能读取vue3的数据 ,用this.(vue3返回的数据)
vue3的setpu不能读取vue2的数据
vue3和vue2不要混用
vue3和vue2名相同 setpu优先
setup执行的时机
在beforeCreate之前执行一次,this是undefined。
setup的参数
props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
context:上下文对象
attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。
slots: 收到的插槽内容, 相当于 this.$slots。
emit: 分发自定义事件的函数, 相当于 this.$emit。
四.ref 给基本类型做数据响应式用的
基本数据类型想要数据响应式,也就是在setpu里改了数据,想要模版也跟着变的话就要使用到ref
先要引入 import { ref } from 'vue'
把基本数据类型放到ret方法里 如:let name=ref("张三“)
在setpu上改的放要加个value 如,name.value='李四'
改了之后在模版上就不用加value,直接{{name}}
通过Object.defineProperty()的get和set来实现响应式
想要用ref方法包对象类型 做数据响应式
在setpu上修改就要obj.value.name='李四'
但是只调用第一层的数据,再下一层还是对象就不能再修改了
五.reactive 给对象类型做数据响应式用的
定义一个对象类型的响应式数据,处理不了基本类型的(基本类型用ref)
先要引入ref import { reactive } from 'vue'
js处理数据不用加.value
可以监测到深层的对象
对数组类型也能监测,
基本数据要使用可以包装成一个对象再用reactiove()
原理是用了proxy代理,还通过了windom身上的Reflect反射
new Proxy(data, {
// 拦截读取属性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 拦截设置属性值或添加新属性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 拦截删除属性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'
六.setup中的两个参数,props,context(attrs,slots,emit)
setup(props)第一个参数是props接收到的数据,会整理成一个proxy对象
setup(props,context)第二个参数是一个对象,里面有attrs emit slots
attrs相当于vue2的$attrs,当没有用props声明接收就会出现在vue3的context.attrs里
slots是使用是插槽,父组件传过来的节点
emit触发自定义事件 使用时像props一样先配置 接收 emits:['hello']
七.vue3里的computed()
需要通过import引入
vue3的写法与vue2功能是一致的
要写到steup()里面
vue3里的computed是一个方法,简写时括号里直接放一回调,完整写法放一个{}里面有get和set
import {computed} from 'vue'
setup(){
...
//计算属性——简写
let fullName = computed(()=>{
return person.firstName + '-' + person.lastName
})
//计算属性——完整
let fullName = computed({
get(){
return person.firstName + '-' + person.lastName
},
set(value){
const nameArr = value.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
}
八.watch监测函数
vue3中使用watch方法的多种情况
1.在vue3中的watch是一个方法,而vue2里是一个配置项,所以可以使用多个watch,要放置在setup(要通过import引入 import {watch} from 'vue'
2.watch里面有三个参数
3.第一个是监测的对象
4.第二个是要执行的回调,回调里第一个参数是修改后的新值,第二个是修改前的值
5.第三个参数是配置对象用{}包住,有immediate:true,和deep:true ,immediate:true是初始化时就调用一次 ,deep:true是开启深度监视
- 监测ref时,不用加.value,如果监测的是对象就要加.value,如果不加.value可以开启deep:true;
7.监测的是reactive定义的数据时,修改后的值没法得到
8.监测的是对象的属性,第一个参数就要用一个回调,回调里的返回值放监视的对象属性,监视 多个对象属性就要放在一个数组里,注意的是正常情况下监视的是对象会自动开启深度监视,改成false无效
9.监测的是对象的属性也是对象的话,vue3中特殊情况,deep:false配置才能生效.默认是false,如果里面还有再深层次的对象的放就要开启deep:true;才能监视到更深层次的对象属性
//情况一:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum变化了',newValue,oldValue)
},{immediate:true})
//情况二:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或msg变化了',newValue,oldValue)
})
/* 情况三:监视reactive定义的响应式数据
若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
若watch监视的是reactive定义的响应式数据,则强制开启了深度监视
*/
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{immediate:true,deep:false}) //此处的deep配置不再奏效
//情况四:监视reactive定义的响应式数据中的某个属性
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true})
//情况五:监视reactive定义的响应式数据中的某些属性
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true})
//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
九.watchEffect函数 不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
watch的套路是:既要指明监视的属性,也要指明监视的回调。
watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
watchEffect有点像computed:
但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
const x1 = sum.value
const x2 = person.age
console.log('watchEffect配置的回调执行了')
})
十.生命周期 有两个不同beforeUnmount 和unmount
在vue3中的setup中使用,要在前面加on如onbeforeCreate( ()=>{})括号里面放一回调
beforeCreate() created() beforeMount() mounted() beforeUpdate() Update()
beforeUnmount(){} vue2 beforeDestroy
unmount(){} vue2 destroyed
beforeCreate() created()在setup执行之前执行
十一.自定义hook函数
把封装的代码写在一个js文件上,放在hooks目录上,hooks目录要放在src目录下,在组件都要用就可以直接引入调用即可,
记得要return返回值才有用
十二.toRef和toRefs
使用toRef要先通过import引入
toRef如果返回值不通过toRef方法包果,就不是响应式数据
toRef方法里的第一个参数是对象,第二个参数是属性,深层次的对象引用在第一个参数里点出来
toRefs也要先引入
可以批量处理对象,有一个参数就可以了,参数是对象
通过...出来的都是第一层的属性,所以在模版上深层次的还是要点出来
十三.shallowReactive和shallowRef
shallowReactive只响应第一层数据属性,深层次数据的不响应
与reactive的区别就是,reactive可以对深层次数据响应
shallowRef对对象类型的数据不进行响应式
与ref区别,ref对对象用.value形式可以响应式
十四.customRef 自定义ref
<template>
<input type="text" v-model="keyword">
<h3>{{keyword}}</h3>
</template>
<script>
import {ref,customRef} from 'vue'
export default {
name:'Demo',
setup(){
// let keyword = ref('hello') //使用Vue准备好的内置ref
//自定义一个myRef
function myRef(value,delay){
let timer
//通过customRef去实现自定义
return customRef((track,trigger)=>{
return{
get(){
track() //告诉Vue这个value值是需要被“追踪”的
return value
},
set(newValue){
clearTimeout(timer)
timer = setTimeout(()=>{
value = newValue
trigger() //告诉Vue去更新界面
},delay)
}
}
})
}
let keyword = myRef('hello',500) //使用程序员自定义的ref
return {
keyword
}
}
}
</script>
十五.provide 与 inject
父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据
祖组件中
setup(){
......
let car = reactive({name:'奔驰',price:'40万'})
provide('car',car)
......
}
后代组件中
setup(props,context){
......
const car = inject('car')
return {car}
......
}
十六.响应式数据的判断
isRef: 检查一个值是否为一个 ref 对象
isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理
十七.Teleport能够将我们的组件html结构移动到指定位置的技术
<teleport to="移动位置">
<div v-if="isShow" class="mask">
<div class="dialog">
<h3>我是一个弹窗</h3>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
</teleport>
十八.Suspense等待异步组件时渲染一些额外内容,让应用有更好的用户体验
异步引入,网络慢时子组件后出
用Suspense包住的,网速快时出default,网络慢时出fallback,两个template都是同一个东西
使用了Suspense组件才能用async,用了Promise也可以出现延时加载
<template>
<div class="app">
<h3>我是App组件</h3>
<Suspense>
<template v-slot:default>
<Child/>
</template>
<template v-slot:fallback>
<h3>加载中.....</h3>
</template>
</Suspense>
</div>
</template>
import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
十九.全局API的转移
将全局的API,即:Vue.xxx调整到应用实例(app)上
2.x 全局 API(Vue) 3.x 实例 API (app)
Vue.config.xxxx app.config.xxxx
Vue.config.productionTip 移除
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties
————————————————
版权声明:本文为CSDN博主「ungame」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/A081127/article/details/124554466
————————————————
版权声明:本文为CSDN博主「ungame」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/A081127/article/details/124554466
网友评论