Vue3【相对于vue2的变化】

VUE3

1.入门

1.创建工程

1.Vue3

vue-cli构建(vue2构建方式相同)

vite

npm init vite-app 工程名

cd …

npm i

npm run dev

2.特点

Vue3组件可以不用写div根目录

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3.0 + Vite" />
</template>

2.Composition API

1.Setup

返回一个对象(常用)

export default {
  name: 'App',
  setup(){
    let name = '张三';
    let age = 33;

    function echo(){
      alert(name+age)
    }

    return {
      name,
      age,
      echo
    }
  }
}

注意事项

vue2和setup不要混用

如果有重名setup优先

setup不能是一个async函数,因为返回值是promise而不是return的对象

2.ref函数

作用:定义一个响应式的数据

语法:

const xxx = ref(initValue)

创建一个包含响应式数据的引用对象(reference对象)。

JS中操作数据:

xxx.value

模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div

备注:

接收的数据可以是:基本类型、也可以是对象类型。

基本类型的数据:响应式依然是靠 Object.defineProperty()的

对象类型的数据:内部“求助”了Vue3.0中的一个新函数——reactivelset完成的。

3.reactive函数

作用:定义一个对象类型的响应式数据(基本类型别用它,用ref 函数)

语法:

const 代理对象=reactive(被代理对象)接收一个对象(或数组),返回一个代理器对象(proxy对象)

reactive定义的响应式数据是“深层次的”。

内部基于 ES6的Proxy实现,通过代理对象操作源对象内部数据都是响应式的

4.Vue3实现响应式

Proxy

#region

let person = {
    name:'zs',
    age:33
}

const p = Proxy(person,{
    get(target,propName){
        console.log("get",target,propName);
    },
    set(target,propName,value){
        console.log("set",target,propName);
        target[propName]=value;
    },
    deleteProperty(target,propName){
        console.log("deleteProperty",target,propName);
        delete target[propName];
    }
})

5.reactive对比ref

从定义数据角度对比:

ref用来定义:基本类型数据。

reactive用来定义:对象(或数组)类型数据。

备注:ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象。

从原理角度对比:

ref通过 0bject.defineProperty()的get与set来实现响应式(数据劫持)。

reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据。

从使用角度对比:

ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value

reactive定义的数据:操作数据与读取数据:均不需要.value

3.计算属性和监视

1.computed

简写写法

let add = computed(()=>{
    return strs.value+'1234';
})

完整写法

get(){}

set(){}

let add = computed({
    get(){
        console.log("get");
        return strs.value+'1234'
    },
    set(value){
        return console.log("set"+value);
    }
})

2.watch

/* 监视一项 */
watch(sum,(newValue,oldValue)=>{
    console.log(newValue,oldValue);
})

/* immediate:true配置项 */
watch(sum,(newValue,oldValue)=>{
    console.log(newValue,oldValue);
},{immediate:true})

/* newValue和oldValue都是数组 */
watch([sum,str],(newValue,oldValue)=>{
    console.log(newValue,oldValue);
},{immediate:true})

与Vue2.x中watch配置功能一致

两个小“坑”:

监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。

监视reactive定义的响应式数据中某个属性时:deep配置有效。

//情况一:监视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})

3.watchEffect函数

当在里面使用的变量被修改时调用

4.生命周期钩子

5.自定义hook

将组合API进行封装

复用代码 类似于vue2的mixin

6.Toref和Torefs

创建一个ref数据,其值value指向另一个对象中的某个属性

const name = toRef(person,‘name’);

将响应式对象中的某个属性单独提供给外部使用时

toRef和toRefs作用相同,可以批量创建多个ref对象

4.其他Composition API

1.shallowReactive

只考虑第一层数据的响应式

2.shallowRef

只处理基本基本数据类型的响应式,不进行对象的响应式处理

3.readonly

只读

不允许数据被修改时

4.shallowReadonly

浅只读,只考虑第一层数据

不允许数据被修改时

5.toRaw

转换为原始对象

toRaw:

作用:将一个由reactive生成的响应式对象转为普通对象

使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新

6.markRaw

把…标记为原始

作用:标记一个对象,使其永远不会再成为响应式对象

应用场景:

1.有些值不应被设置为响应式的,例如复杂的第三方类库等

2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

7.customRef

自定义ref

实现防抖效果

<template>
    <div>
        <input type="text" v-model="keyWord">
        <h3>{{keyWord}}</h3>
    </div>
</template>

<script lang="ts">
import {ref,customRef} from 'vue';
export default {
    name:'Person',
    setup() {

        function myref(value){
        let timer
            //传递参数
            return customRef((tarck:any,trigger:any):any => {
                return {
                    get(){
                        console.log(`获取${value}`);
                        tarck(); //通知vue追踪value的变化
                        return value;
                    },
                    
                    set(newValue):void{
                        clearTimeout(timer);
                        timer = setTimeout(()=>{
                            console.log(`修改${value}`);
                            value = newValue;
                            trigger(); //通知vue重新解析模板
                        },500)
                    }
                }
            });
            
        }

        let keyWord:any = myref('h');
        return {keyWord};
    }
}
</script>

<style>

</style>

8.provide,inject

实现祖孙组件通信

provide提供数据

inject使用数据

provide('per',per);

setup(){
    let per = inject('per');
    return {per};
}

9.响应式数据的判断

isRef

isReactive

isReafonly

isProxy

5.新组件

1.Fragment

减少标签层级,减少内存占用

2.Teleport

将组件html结构移动到指定位置

import {toRefs,provide, reactive,defineAsyncComponent} from 'vue';
const Student = defineAsyncComponent(()=> import('./components/Student.vue'))
<Suspense>
    <template #default>
<Student/>
    </template>
    <template #fallback>
<div>组件加载中...</div>
    </template>
</Suspense>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值