创建项目:vue create vue3_test(vue-cli3版本4.5以上)
// 非响应式,未配置ref
setUp() {
// 数据
let name = '葛检'
let age = 30
// 方法
function sayHello() {
alert(`我叫${name},今年${age}`)
}
// 返回数据和方法
return {
name,
age,
sayHello
}
// 返回一个渲染函数
}
在vue2配置和vue3配置不要混合使用
import {ref} from 'vue'
let name = ref('张三')// 返回一个引用实例对象,里面包含value属性,然后原型里面有一个set和get函数实现
// 修改
name.value = '李四'
age.value = 48
let job = ref({
type: '前端开发',
salary: '30k'
})
job.value.type ="ui设计师"
ref:接收的数据可以是基本类型,也可以是对象类型,基本类型依赖于set和get实现,对象类型,需要借助于reactive也就是pooxy来实现
import {reactive} from 'vue'
let obj = reactive({
type: '前端开发',
salary: '30K'
})
job.type = 'ui设计师'(proxy对象)
ley hobby = reactive([1,2,3,4,5])
hobby[0] = a // 在vue2中是无法检测到这种数据通过下标修改数据的,无法及时更新页面,vue3通过proxy解决了这个问题
v2: object.definePropertry()对属性的读取和修改进行拦截,数据劫持(set,get)
缺点: 1新增属性,删除属性,界面不更新,2通过数组下标,修改数组,界面不会更新
解决: this.$set(obj,name,value)、this.$delete(obj,name)
v3: window.proxy实现
模拟v3实现响应式
let person = {
name:'张三',
age: 13
}
const p = new Proxy(person,{
get (target,propName) { // target-源对象,propName-修改的属性名
return target[propName]
},
set (target,propName,value) {// value -修改后的值
target[propName] = value
}
deleteProperty (target,propName) { // 删除属性
return delete target[propName]
}
}) //代理
p.name = '李四',这杨的话,person.name === '李四' 为true
v3响应式原理依赖于=>Reflect反射
window.Reflect// 存在set,get,deleteProerty方法以及defineProperty
所以将模拟代码修改为
const p = new Proxy(person,{
get (target,propName) { // target-源对象,propName-修改的属性名
return Reflect.get(target,propName)
},
set (target,propName,value) {// value -修改后的值
Reflect.set(target,propName,value)
}
deleteProperty (target,propName) { // 删除属性
return Reflect.deleteProerty(target,propName)
}
}) //代理
1,定义数据类型区别,
2,原理不同,一个是v2,一个是proxy
3,使用角度,ref需要.value,反而reactive不需要,直接.属性 =
setup执行的时机 => 在beforeCreate之前执行一次,this是undefined
setup的参数 =>
prop: 值为对象,包含自建外部传递进来的,并且在组件内部申明接收了的属性
context: 上下文对象
attes:值为对象,包含组件外部传递进来的,
slots: 收到的插槽内容
emit: 分发自定义事件的函数,相当于this.$emit
import {ref,reactive, computed,watch} from 'vue'
setUp() {
let person = reactive({
firstName: '张',
lastName: '三'
})
let sum = ref(0)
let suma = ref(0)
// 计算属性
person.pullName = computed(() => {
return person.firstName + '_' + person.lastName
})
// 监听一个属性
wacth(sum,(newvalue,oldvalue) = > {
console.log('sum变化了')
})
// 监听多个属性
wacth([sum,suma],(newvalue,oldvalue) = > {
value则变成了一个数组
console.log('sum变化了')
})
// 第三个参数为配置参数
wacth([sum,suma],(newvalue,oldvalue) = > {
value则变成了一个数组
console.log('sum变化了')
},{immediate: true})
// 监听对象reactive
wacth(person,(newvalue,oldvalue) = > {
坑: 对象类型oldvalue是最新value,无法返回以前的值,deep:true无法关闭,v3监听默认开启深度监听,无法关闭
console.log('person变化了')
})
// 监听对象某个属性reactive!!!得写成函数形式
wacth(() => person.age,(newvalue,oldvalue) = > {
坑: 不能直接监听person.gae 需要写成一个函数 ()=> person.age,假如需要监听多个属性,得写成数组函数
当你监听多层属性,需要配置deep:true
console.log('person变化了')
})
return {
person,
sum,
suma
}
}
import {watchEffect} from 'vue'
watchEffect (() => {
//用到哪个变量就监测哪个变量和计算属性有点像
const x1 = sum.value
})
destroy-销毁生命周期变成了unmounted,beforDestroy->beforUmounte
组合式API,生命周期可以在setUp中执行,但是beforcreated和creadted无法通过组合式API执行(这2个其实等同于setUp)
-本质是一个函数,吧setup函数里面使用的compositionApi进行封装,
-类似于混入mixin
-复用代码,逻辑变的清楚易懂
- 创建一个ref对象,他的value值指向另外一个对象的属性
- const name = toRef(person,'name')
- 吧响应书对象的某个属性单独提取出来,使用
- toRefs类似,可以批量创建ref对象 const obj = toRefs(person) return {...obj}
shallowReactive: 只处理对象最外层竖向的响应式(浅响应式)
shallowRef: 只处理基本数据类型的响应式,不处理对象的
当一个对象数据结构比较深,变化的时候,只有外层属性变化 => shallowReactive
有一个对象数据后续功能不会修改该对象中的属性,是用新的对象来替换 => shallowRef
readonly: 响应式数据变成只读(深只读,任何层次属性都只读)
shallowReadonly:响应式数据变只读(浅只读,只有最外层属性只读)
当不希望数据被修改时使用
toRaw: 将一个reactive生成的响应式对象变为普通对象
markRaw: 标记一个对象,永远不会再成为响应式对象(提高性能,第三方库,以及大数据不变列表)
创建一个自定义ref,并对其依赖项跟踪和更新触发进行显示控制
作用 => 实现防抖效果
作用:实现祖孙组件之间传值(跨级组件)
provide: 在祖组件进行传值进去
inject: 在孙组件接收
// 父组件
setUp() {
let car = reactive({
name: '奔驰',
price: '40W'
})
provide('car', car) // 给自己的后代组件传递数据'car对象'
return {
...toRef(car)
}
}
// 后代组件
setUp() {
let car = inject('car') // 接收祖组件传进来的值
return {
car
}
}
1.isRef—检查一个值是否为ref对象
2.isReactive – 检查一个对象是否由reactive创建的响应式代理
3.isReadonly – 检查一个对象是否由readonly创建的只读代理
4.isProxy – 检查一个对象是都由reacttive或者readonly方法创建的代理
let car = reactive({
name: '奔驰',
price: '40W'
})
console.log(isReactive(car)) // 返回一个布尔值,假如为true则为响应式数据,否则为否
自定义hook函数,吧相关功能代码,组织在一起
vue2.0需要一个根组件,在vue3.0中可以没有根组件,(在一个虚拟的fragment虚拟元素中)
作用: 可以将一段html元素,传送到任意dom元素的某个节点
//挂载在body节点下 to:可以下id-#ceshi,可以写元素标签body
html片段