likes
comments
collection
share

Vue3基础

作者站长头像
站长
· 阅读数 18

前提:Vue3依然支持Vue2的语法。并且Vue3和Vue2的优先级相同。

Vue3的基础介绍

1. Vue3项目的创建

1.1 使用 vue-cli 创建

    // 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
       vue --version
       
    // 安装或者升级你的@vue/cli
        npm install -g @vue/cli
        
    // 创建
        vue create <project-name>
        
    // 启动
        cd <project-name>
        npm run serve

1.2 使用 vite 创建

vite官网

## 创建工程
npm create vite <project-name>

## 进入工程目录
cd <project-name>

## 安装依赖
npm install

## 运行
npm run [dev](url)

2. Vue3的组合式API(Composition API)

2.1 Composition API是什么

  • ① Composition API是一系列 API 的集合,使我们可以使用函数的方式书写 Vue 组件。
  • ② 组合式 API 是 Vue 3 及 Vue 2.7 的内置功能

2.2 Composition API的分类

  • 响应式API。例如 ref() 和 reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
  • 生命周期钩子函数。例如 onMounted() 和 onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
  • 依赖注入。例如 provide() 和 inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。

2.3 常用的Composition API

2.3.1 setup函数

  • 作用:Vue3要求代码必须写在setup函数内部。包括响应式数据、计算属性、方法、生命周期钩子函数等。
  • 参数:
    • props。值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性

    • context。上下文对象

      • 1、 attrs。值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。
      • 2、 emit。分发自定义事件的函数, 相当于 this.$emit。
      • 3、 slots。收到的插槽内容, 相当于 this.$slots。

Vue3基础

2.3.2 ref函数

  1. 作用:定义基本类型的响应式数据
  2. 原理:Object.defineProperty
  3. 【注意】建议只用来定义基本数据类型(string,boolean,number)。如果定义引用类型会在内部调用reactive方法来生成数据
  4. 使用:
    • 在script中获取或者设置值时需要 .value。
    • 在页面上使用不需要 .value

Vue3基础

2.3.3 reactive函数

  1. 作用:定义引用类型的响应式数据
  2. 原理:proxy代理
  3. 语法:let 代理对象 = reactive(源对象)

2.3.4 toRef函数

  1. 作用:复制 reactive 里的单个属性并转成 ref
  2. 语法: const name = toRef(person,'name')

2.3.5 toRefs函数

  1. 作用:复制 reactive 里的所有属性并转成 ref
  2. 语法:toRefs(person)

【ref对象和reactive对象对toRef与toRefs的应用】 Vue3基础

2.3.6 computed计算属性

写法1:默认是get的写法

<template>
    <div>{{total}}</div>
</template>

<script>
    import {ref,computed} from 'vue';
    export default{
        setup(){
            let num = ref(10);
            let total = computed(()=>{
                return num.value+'美金';
            })
            return {
                num,
                total
            }
        }
    }
</sctipt>

写法2:有get和set的写法。computed方法中放一个对象,对象中有get和set方法

<template>
    <div>{{total=10000}}</div>
    <div>{{total}}</div>
</template>

<script>
    import {ref,computed} from 'vue';
    export default {
        setup(){
            let num = ref(20);
            let total = computed({
                get(){
                    return num.value+'英镑'
                }
                set(val){
                    if(val==0){
                        num.value='一个子没有'
                    }else{
                        num.value = val
                    }
                }
            })
        }
    }
</script>

2.3.7 watch监听

情况一:监听单个ref响应式数据 (基本数据类型)

<script>
    import {ref ,watch} from 'vue'
    export default {
        setup(){
            let str = ref('abc');
            watch(str,(newVal,oldVal)=>{
                console.log(newVal);
                console.log(oldVal)
            },{immediate:true})
        }
    }
</script>

情况二:监听多个ref响应式数据 (基本数据类型) ---> 利用数组实现多个监听

<script>
    import {ref,watch} from 'vue'
    export default {
        setup(){
            let str = ref('字符串数据');
            let num = ref(99)
            watch([str,num],(newVal,oldVal)=>{
                console.log(newVal);
                console.log(oldVal);
            },{immediate:true})
        }
    }
</script>

情况三:监听1个reactive响应式数据 (引用数据类型)

特点:强制开启深度监听(只要有数据变化,就能被监听到)

<script>
    import {reactive,watch} from 'vue'
    export default {
        let person = reactive({
            name:'大刘',
            age:30,
            children:{
                name:'小刘',
                age:2
            }
        })
        watch(person,(newVal,oldVal)=>{
            console.log(newVal);
            console.log(oldVal);
        },{immediate:true,deep:true})
    }
</script>

情况四:监听reactive响应式数据的1个属性 ---> 利用函数

<script>
    import {reactive,watch} from 'vue'
    export default {
        let person = reactive({
            name:'大刘',
            age:30,
            children:{
                name:'小刘',
                age:2
            }
        })
        watch(()=>person.children,(newVal,oldVal)=>{
            console.log(newVal);
            console.log(oldVal);
        },{immediate:true,deep:true})
    }
</script>

情况五:监听reactive响应式数据的多个属性 ---> 利用函数+数组

<script>
    import {reactive,watch} from 'vue'
    export default {
        let person = reactive({
            name:'大刘',
            age:30,
            children:{
                name:'小刘',
                age:2
            }
        })
        watch([()=>person.name,()=>person.children],(newVal,oldVal)=>{
            console.log(newVal);
            console.log(oldVal);
        },{immediate:true,deep:true})
    }
</script>

2.3.8 watchEffect函数

  • watch:明确指出监听的数据

  • watchEffect:没有明确指出监听的数据。在监听回调用了哪个数据,就监听哪个数据

    <template> 
        <div>{{str}}</div>
        <button @click='change'>改变</button> 
    </template>
    
    <script>
        import {ref,watchEffect} from 'vue';
        let str = ref('str的数据')
        const change = ()=>{
            str.value='修改后的数据';
            // cancelWatch(); 调用该方法会取消监听
        }
       let cancelWatch = watchEffect(()=>{
            str.value; // 在这里用到了str,所以触发了str的watchEffect监听
            console.log('触发了str的监听')
        })
    </script>
    

2.3.9 hook函数 ---> 第2个setup函数

  • hook本质就是一个函数,和setup函数类似。类比Vue2中的mixin

Vue3基础

2.3.10 生命周期钩子函数

  • vue2与Vue3生命周期钩子函数的对应关系:

    • beforeCreate ===> setup()
    • created=======> setup()
    • beforeMount ===> onBeforeMount
    • mounted =======> onMounted
    • beforeUpdate ===> onBeforeUpdate
    • updated =======> onUpdated
    • beforeDestroy ==> onBeforeUnmount
    • Destroyed =====> onUnmounted
  • 【重要】vue2和vue3的生命周期图解

    1. vue2生命周期 Vue3基础

    2. vue3生命周期 Vue3基础

2.3.11 vue3中配置全局过滤器

【注意】在vue3中过滤器已经被废弃。全局过滤器只是定义了一些全局方法。

  • 在main.js中配置全局过滤器,代码如下

    import {createApp} from 'vue';
    import App from './App.vue'
    let app =  createApp(App)
    
    //配置全局过滤器
    app.config.globalProperties.$filters = {   // $filters是自己取的一个属性名
        RMB(val,str){
            return val+str
        }
    }
    
    app.mount('#app')
    
  • 全局过滤器的使用,例如在组件Home.vue中使用: $filters.RMB(20,'元')

    <template>
        <div>{{ $filter.RMB(20,'元') }}</div>
    </template>
    

2.3.12 vue3配置全局自定义指令

  • 在main.js中配置全局自定义指令,代码如下

    import {createApp} from 'vue';
    import App from './App.vue'
    let app =  createApp(App)
    
    //配置全局自定义指令
    app.directive = ('drag',{
        mounted(el,binding,vnode){  //第一次插入DOM时触发。相当于vue2的bind(){}
            //写一个盒子拖拽的指令
            el.onmousedown=function(e){
                let disX = e.offsetX;
                let disY = e.offsetY;
                document.onmousemove=function(e){
                    el.style.left=e.pageX-disX+'px';
                    el.style.top=e.pageY=disY+'px'
                }
                document.onmouseup=function(){
                    document.onmousemove=document.onmouseup=null
                }
            }
        }
        updated(el,binding,vnode){  //每次DOM更新都会触发。相当于vue2的update(){}
        
        }
    })
    
    app.mount('#app')
    
  • 全局自定义指令的使用,例如在组件Home.vue中使用: v-drag

    <template>
        <div v-drag></div>
    </template>
    

2.4 其他一些Composition API

2.4.1 shallowReactive 和 shallowRef ---> 数据会改变,视图不更新

  • reactive:定义引用类型的响应式数据。并且在watch时强制开启深度监听。属于深响应(所有的数据都会在视图有响应式处理)。
  • shallowReactive:只会处理最外层属性的响应式。属于浅响应(只对外层数据响应式处理)。
  • ref:定义基本数据类型的响应式数据。假如用ref定义引用类型的响应式数据,内部会调用reactive方法生成数据。ref定义的应用类型响应式数据也属于深响应
  • shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。假如用shallowRef定义引用类型的响应式数据,不会响应式处理

【注意】shallowReactive和shallowRef定义的引用数据实际已经发生了改变,只是视图没有更新。只要视图更新,shallowReactive和shallowRef数据改变的地方也会响应到页面上。

Vue3基础

2.4.2 readonly 和 shallowReactive ---> 数据不改变

  • readonly:将一个响应式数据变成只读。(深只读:所有的数据都不能修改)
  • shallowReadyonly:将一个响应式数据变成只读。(浅只读:引用类型的响应式数据的深层次可以修改)

2.4.3 provide 和 inject

  • 作用:实现祖先组件与后代组件间的通信

Vue3基础

转载自:https://juejin.cn/post/7236689719076634682
评论
请登录