Vue 3.0 学习笔记

news2024/9/22 7:32:35

Vue 3 学习笔记

文章目录

  • Vue 3 学习笔记
    • @[toc]
    • 一、初识vue3
    • 二、 常用Composition API(组合式API)
      • **1. setup函数**
      • **2. ref函数**
      • **3. reactive函数**
      • **4. Vue3.0中的响应式原理**
        • **Vue2.x的响应式**
        • **Vue3.x的响应式**
      • **5. reactivce对比ref**
      • **6. setup的两个注意点**
      • **7. 计算属性与监视属性**
        • 1.computed函数
        • 2.watch函数
          • **watch中的.value问题**
        • 3.watchEffect函数
      • **8. 生命周期**
        • 1.vue 2.0 与 vue 3.0的生命周期对比
        • 2.生命周期对应
      • **9. 自定义hook函数**
      • **10. toRef**
    • 三、 其他Composition API
      • **1. shallowReactive 与 shallowRef函数**
      • 2.readonly 与 shallowReadonly
      • 3.toRaw 与 markRaw
      • 4.customRef
      • 5.provide 与 inject
      • 6.响应式数据的判断
    • 四、Composition API 的优势
      • 1.Options API 存在的问题
      • 2.Composition API 的优势
    • 五、新的组件
      • 1.Fragment
      • 2.Teleport
      • 3.Suspense(后续可能更改)
    • 六、其他
      • 1.全局API的转移
      • 2.其他改变

一、初识vue3

1.vue3简介

  • 2020年9月18日,vue3发布3.0版本,代号大海贼时代来临,One Piece

  • 特点:

    • 无需构建步骤,渐进式增强静态的 HTML

    • 在任何页面中作为 Web Components 嵌入

    • 单页应用 (SPA)

    • 全栈 / 服务端渲染 (SSR)

    • Jamstack / 静态站点生成 (SSG)

    • 开发桌面端、移动端、WebGL,甚至是命令行终端中的界面

2.Vue3带来了什么

  • 打包大小减少40%

  • 初次渲染快55%,更新渲染快133%

  • 内存减少54%

3.分析目录结构

  • main.js中的引入
  • 在模板中vue3中是可以没有根标签了,这也是比较重要的改变
  • 应用实例并不只限于一个。createApp API 允许你在同一个页面中创建多个共存的 Vue 应用,而且每个应用都拥有自己的用于配置和全局资源的作用域。
//main.js

//引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
import {createApp} from 'vue
import App from './App.vue

//创建应用实例对象-app(类似于之前vue2中的vm实例,但是app比vm更轻)
createApp(APP).mount('#app')
//卸载就是unmount,卸载就没了
//createApp(APP).unmount('#app')

//之前我们是这么写的,在vue3里面这一块就不支持了,会报错的,引入不到 import vue from 'vue'; 
new Vue({
	render:(h) => h(App)
}).$mount('#app')

//多个应用实例
const app1 = createApp({
  /* ... */
})
app1.mount('#container-1')

const app2 = createApp({
  /* ... */
})
app2.mount('#container-2')

二、 常用Composition API(组合式API)

1. setup函数

  • 1.理解:Vue3.0中一个新的额配置项,值为一个函数

  • 2.setup是所有Composition API(组合api) “表演的舞台”

  • 3.组件中所用到的:数据、方法等等,均要配置在setup中

  • 4.setup函数的两种返回值:

    • 若返回一个对象,则对象中的属性、方法,在模板中均可以直接使用。(重点关注)

    • 若返回一个渲染函数:则可以自定义渲染内容。(不常用)

  • 5.注意点:

    • 尽量不要与Vue2.x配置混用

      • Vue2.x配置(data ,methos, computed…)中访问到setup中的属性,方法
      • 但在setup中不能访问到Vue2.x配置(data.methos,compued…)
      • 如果有重名,setup优先
    • setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性

      但如果是异步引入的方式,是可以返回一个promise的,采用defineAsyncComponent引入时

<template>
    <div>
        <h1>SetupMain</h1>
        <h2>姓名:{{ name }}</h2>
        <h2>年龄:{{ age }}</h2>
        <h2>地址:{{ address() }}</h2>
    </div>
</template>

<script>
export default {
    name: "SetupMain",
    setup() {
        function address() {
            return "无锡。。。。"
        }
        return {
            name: "wsy",
            age: 24,
            address
        }
    }
}
</script>

2. ref函数

  • 作用:定义一个响应式的数据
  • 语法 const xxx = ref(value)
    • 创建见一个包含响应式数据的引用对象(reference对象)
    • JS中操作数据: xxx.value
    • 模板中读取数据:不需要 .vuale,可以直接 <div>{{xxx}}</div>使用
  • 备注:
    • 接收的数据可以是:基本类型,也可以是对象类型
    • 基本类型的数据:响应式依旧是靠 Object.defineProperty()getset 完成的
    • 对象类型的数据:内部使用了Vue3.0中的一个新函数—— reactive函数

3. reactive函数

  • 作用:定义一个对象类型的响应式数据(基本类型不使用这个函数,用ref函数)
  • 语法:const 代理对象 = reactive(被代理对象)接收一个对象(或数组),返回一个代理器对象(proxy对象)
  • reactive定义的响应式数据是深层次的(多层数据改变都可以监测)
  • 内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据都是响应式的

在这里插入图片描述

4. Vue3.0中的响应式原理

Vue2.x的响应式

  • 实现原理:

    • 对象类型:通过Object.defineProperty()对属性进行读取,修改进行拦截(数据劫持)

    • 数组类型:通过重写更新数组的一系列方法来实现拦截,(对数组的变更方法进行了包裹)

      Object.defineProperty(data,'count'{
      	get(){},
      	set(){}
      })
      
  • 存在问题:

    • 新增属性、删除属性,界面不会更新
    • 直接通过下标修改数组,界面不会自动更新
  • vue2 解决方法

    也可以通过调用强制更新钩子 this.$forceUpdate()

    <template>
        <div>
            <h1>Test</h1>
            <h2>姓名:{{ person.name }}</h2>
            <h2 v-show="person.age">年龄:{{ person.age }}</h2>
            <h2 v-show="person.sex">性别:{{ person.sex }}</h2>
            <h2>数组:{{ list }}</h2>
            <button @click="fun1">删除年龄</button>
            <br>
            <button @click="fun2">新增性别</button>
            <br>
            <button @click="fun3">修改数组</button>
            <br>
        </div>
    </template>
    
    <script>
    import Vue from "vue"
    
    export default {
        name: "Test",
        data() {
            return {
                person: {
                    name: "xiaohua",
                    age: 18,
                },
                list: [1, 2, 3]
            }
        },
        methods: {
            fun1() {
                console.log("删除年龄成功")
                //这种方式是不会产生页面修改的
                delete this.person.age;
    
                //可以通过这种方式强制更新
                // this.$forceUpdate()
                // this.$delete(this.person,"age")
                // Vue.delete(this.person,"age")
            },
            fun2() {
                console.log("新增性别成功")
                //这种方式是不会产生页面修改的
                // this.person.sex = "女"
    
                // this.$set(this.person,"sex","女")
                Vue.set(this.person, "sex", "女")
            },
            fun3() {
                console.log("修改数组成功")
                //这种方式是不会产生页面修改的
                // this.list[0]=2
    
                this.list.splice(0, 1, 2)
            },
    
        }
    }
    </script>
    
    

Vue3.x的响应式

  • 实现原理:

    • 通过 Proxy(代理):拦截对象中任意属性的变化,包括属性值的读写,属性的添加,属性的删除等
    • 通过 Reflect(反射):对源对象的属性进行操作。
  • 大致实现代码

    var person = {name:"xiaoli",age:12}
    
    //#region
    //利用Proxy
    var p = new Proxy(person,{
      /**
        * @param target 源对象 (被代理的对象)
        * @param property 具体的某个字段 例如‘name’
        * @param receiver 就是当前这个proxy实例
        * */
      //拦截读取属性值
      get(target, property, receiver) {
        console.log(`有人读取了p身上的${property}属性`)
        /*console.log(target, property, receiver)*/
        //在底层用的不是这种写法 ,而是借助于Reflect
        // return target[property]
        return Reflect.get(target,property)
      },
      //拦截设置属性值或添加新属性
      set(target, property, newValue, receiver) {
        console.log(`有人修改了p身上的${property}属性,新值为${newValue}`)
        // console.log(target, property, receiver)
        //return target[property] = newValue
        return Reflect.set(target,property,newValue)
      },
      //拦截删除属性
      deleteProperty(target, property, receiver) {
        console.log(`有人删除了p身上的${property}属性`)
        // console.log(target, property, receiver)
        // return delete target[property]
        return Reflect.deleteProperty(target,property)
      }
    });
    //#endregion
    

    效果:

    在这里插入图片描述

5. reactivce对比ref

  • 从定义数据角度对比:
    • ref用来定义:基本数据类型的数据
    • reactive用来定义:对象(或数组)类型数据
    • 备注:ref也可以用来定义对象(或数组)类型数据,但是它内部会自动通过reactive转为 代理对象
  • 从原理角度对比:
    • ref通过 Object.defineProperty()getset 来实现响应式(数据劫持)
    • reactive通过使用Proxy来实现响应式(数据劫持),并通过 Reflect操作源对象内部的数据
  • 从使用角度对比:
    • ref定义的数据:操作数据需要 .value ,读取数据时模板中直接读取不需要 .value
    • reactive定义的数据:操作数据与读取数据:均不需要 .value

6. setup的两个注意点

  • setup执行的时机
    • 在beforCreate之前执行一次,this是undefined
  • setup的参数
    • props:值为对象,包含组件外部传递过来的,且组件内部声明接受了的属性
    • context:上下文对象
      • attrs:值为对象,包含:组件外部传递过来,但是没有在props配置中声明的属性,相当于this.$attrs
      • slots:收到的插槽内容,相当于this.$slots
      • emit:分发的自定义事件的函数,相当于this.$emit

7. 计算属性与监视属性

1.computed函数

  • 与Vue2.x中computed配置功能一致

  • 写法

    import {computed, reactive, ref} from "vue";
    
    export default {
        name: "ComputedComp",
        setup(){
            let person = reactive({
                firstName :"",
                lastName:""
            })
    
            //计算属性 简写 只读取的情况
            // let fullName = computed(()=>{
            //     return person.firstName+"_"+person.lastName
            // })
    
            //计算属性完整写法
            let fullName = computed({
                get(){
                    return person.firstName+"_"+person.lastName
                },
                set(value){
                    let nameArr = value.split("_");
                    person.firstName = nameArr[0];
                    person.lastName = nameArr[1]
    
                }
            })
    
            return{
                fullName,
                person
            }
        }
    

2.watch函数

  • 与Vue2.x中watch配置功能一直

  • 两个问题

    • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)
    • 监视reactive定义的响应式数据中的某个属性(多层级)时:deep配置有效
    setup() {
      let sum = ref(0);
      let msg = ref("你好")
      let person = reactive({name: "小张", age: 12, job: {a: {b: 1}}})
      //情况一,监视ref定义的响应式数据
      watch(sum,(newValue , oldValue)=>{
        console.log("sum变化了",newValue,oldValue)
      })
    
      //情况二,监视多个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.name,(newValue , oldValue)=>{
        console.log("person内的name属性发生变化了",newValue,oldValue)
      })
    
      //情况五:监视reactive所定义的一个响应式数据中的某些数据
      watch([()=>person.name,()=>person.age],(newValue , oldValue)=>{
        console.log("person内的name或age属性发生变化了",newValue,oldValue)
      })
    
      //特殊情况:监视reactive所定义的一个响应式数据中的多层级数据,可以利用deep
      watch(() => person.job, (newValue, oldValue) => {
        console.log("person内的job属性发生变化了", newValue, oldValue)
      }, {deep: true})
    
      return {
        sum, msg, person
      }
    
  • watch中的.value问题
    1. 监视ref定义的基本类型数据,不可以加value

      在这里插入图片描述

    2. 监视ref定义的对象类型数据,需要加value

      let personRef = ref({name: "小张", age: 12, job: {a: {b: 1}}})
      // 监视ref定义的对象类型数据,需要加value
      watch(personRef.value,(newValue , oldValue)=>{
        console.log("personRef变化了",newValue,oldValue)
      })
      

3.watchEffect函数

  • watch的语法是:既要指明监视的属性,也要指明监视的回调

  • watchEffect的语法是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就用哪个属性

  • watchEffect有点像computed

    • 但computed注重重新计算出来的值(回调函数的返回值),所以必须要写返回值
    • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值
    //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调
    watchEffect(()=>{
    const value = sum.value;
    const job = person.job.a.b;
    console.log("watchEffect被调用了")
    })
    
    

8. 生命周期

1.vue 2.0 与 vue 3.0的生命周期对比

在这里插入图片描述

2.生命周期对应

vue 2.0vue 3.0对应setup中组合api备注
setup-无setup是3.0提出的
beforeCreatebeforeCreate被setup取代创建前
createdcreated被setup取代创建
beforeMountbeforeMountonBeforeMount()挂载前
mountedmountedonMounted()挂载
beforeUpdatebeforeUpdateonBeforeUpdate()更新前
updatedupdatedonUpdated()更新
beforeDestroybeforeUnmount(改名)onBeforeUnmoun()卸载前(2.0的钩子被改名)
destroyunmounted(改名)onUnmounted()卸载

代码实例

 setup(){
        let sum  = ref(1)
        console.log("===setup===")

        onBeforeMount(()=>{
            console.log("===setup 中 onBeforeMount===")
        })
        return{
            sum
        }
    },
    beforeCreate() {console.log("===beforeCreate===")},
    created() {console.log("===created===")},
    beforeMount() {console.log("===beforeMount===")},
    mounted() {console.log("===mounted===")},
    beforeUpdate() {console.log("===beforeUpdate===")},
    updated() {console.log("===updated===")},
   //销毁钩子已经被弃用,写了也没有用
    beforeDestroy() {console.log("===beforeDestroy===")},
    //销毁钩子已经被弃用,写了也没有用
    destroyed() {console.log("===destroyed===")},
    beforeUnmount() {console.log("===beforeUnmount===")},
    unmounted() {console.log("===unmounted===");}

注意:配置项中的钩子函数与setup中的钩子函数同时存在,两个都会被触发,但是setup中的函数先被触发

9. 自定义hook函数

  • hook函数——本质是一个函数,把setup函数中使用的Composition API进行了封装

  • 类似于vue2.x中的mixin

  • 优点:复用代码,让setup中的逻辑更清楚易懂

  • 使用

    1.将需要使用的函数代码封装到一个js文件中

    import {onMounted, onUnmounted, reactive} from "vue";
    
    export default function (){
        let point = reactive({x:0,y:0})
        function clickPoint(event){
            console.log(event.pageX,event.pageY)
            point.x = event.pageX;
            point.y = event.pageY;
        }
    
        onMounted(()=>{
            //绑定一个打点事件
            window.addEventListener("click",clickPoint)
        })
    
        onUnmounted(()=>{
            //移除一个打点事件
            window.removeEventListener("click",clickPoint)
        })
        return point
    }
    

    2.在需要使用的vue文件中引入

    <template>
        <h1>Hook函数</h1>
        <h2>point: x:{{ point.x }} y:{{ point.y }}</h2>
    </template>
    
    <script>
    import clickPoint from "@/hook/usePoint"
    
    export default {
        name: "HookMain",
        setup() {
            let point = clickPoint()
            return {
                point
            }
        }
    }
    </script>
    

10. toRef

  • 作用:创建一个ref对象,其value指向另一个对象中的某个属性

  • 语法:const name = toRef(person,'name'),const x = toRefs(person)

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

  • 扩展:toRefstoRef功能一致,但可以批量创建多个ref对象

  • 使用:

    import {reactive, toRef, toRefs} from "vue";
    
    export default {
        name: "RefComp",
        setup() {
            let person = reactive({name: "小张", age: 12, job: {a: {b: 1}}})
            let nameRef = toRef(person, "name");
            let personRef = toRefs(person);
    
            return {
                ...personRef,//后续使用就可以直接使用name等属性,不用写personRef
                person, nameRef
            }
        }
    }
    

三、 其他Composition API

1. shallowReactive 与 shallowRef函数

  • shallowReactive:值处理对象最外层属性的响应式(浅响应式)

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

  • 使用

    • 如果有一个对象数据,结构比较深,但变化时只是外层属性变化,使用shallowReactive
    • 如果有一个对象属性,后续功能不会修改对象中的属性,而是生成新的对象进行替换,使用shallowRef
  • setup() {
      //只会处理对象对外层的属性响应(浅响应式)
      // let person = shallowReactive(
      //值处理基本类型的响应式 不进行对象类型的响应式处理
      let person = shallowRef(
        // let person = reactive(
        {name: "小张", age: 12, job: {a: {b: 1}}})
    
      let sum = shallowRef(0)
    
      return {
        sum,
        person
      }
    }	
    

2.readonly 与 shallowReadonly

  • readonly:让一响应式数据变为只读的(深只读)

  • shallowReadonly:让一个响应式数据变为只读的(浅只读)

  • 应用场景:不希望数据被修改时

    let person = reactive(
      {name: "小张", age: 12, job: {a: {b: 1}}})
    
    let sum = ref(0)
    
    // person = readonly(person)
    person = shallowReadonly(person)
    sum = readonly(sum)
    

3.toRaw 与 markRaw

  • toRaw:

    • 作用:将一个由reactive生成的响应式对象转为普通对象
    • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新
  • markRaw:

    • 作用:标记一个对象,使其永远不会再成为响应式对象
    • 应用场景:
      1. 有些值不应该被设置为响应式的,例如复杂的第三方类库等。
      2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
  • function fun() {
      //可以将一个reactive生成的对象转为普通对象
      console.log(toRaw(person))
    }
    
    function addCar() {
      const car = {name: '奔驰s450', price: 100};
      //可以标记一个对象,使其永远不会再成为响应式对象
      markRaw(car);
      person.car = car;
    }
    

4.customRef

  • 作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制

  • 案例,实现防抖效果

    <template>
      <h1>CustomRefComp</h1>
      <input v-model="keyword"/>
      <h3>{{keyword}}</h3>
    
    </template>
    
    <script>
    import {customRef} from "vue";
    
    export default {
        name: "CustomRefComp",
        setup(){
            // let keyword = ref("hello")
            //自定义一个myRef
            function myRef(value,delay){
                let timer
                //通过customRef去实现自定义
                return customRef((track,trigger)=>{
                    return{
                        get(){
                            track() //告诉vue这个value是需要被追踪的
                            console.log("get被触发")
                            return value;
                        },
                        set(newValue){
                            clearTimeout(timer)
                            console.log("set被触发",newValue)
                            timer = setTimeout(()=>{
                                value = newValue
                                trigger() //告诉vue去更新界面
                            },delay)
                        }
                    }
                })
            }
            let keyword = myRef("hello",500)
    
            return{
                keyword
            }
        }
    }
    

5.provide 与 inject

在这里插入图片描述

  • 作用:实现祖孙组件之间的通信

  • 使用:父组件利用provide选项来提供数据,子组件利用inject选项来使用这些数据

  • 具体写法

    1. 祖组件中

      setup(){
      	......
        let car = reactive({name:"奔驰s450",price:"100w"})
        //为后代组件提供数据
        provide("car",car);
      	......
      }
      
    2. 后代组件中

      setup(){
        ......
        //接收数据
        const car = inject("car")
        return{ car }
        ......
      }
      
  • 注意: 传递的数据是一个响应式数据,所以在后代组件中修改数据,是会影响到所有使用这个数据的地方的。

6.响应式数据的判断

  • isRef: 检查一个值是否为一个 ref 对象
  • isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
  • isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
  • isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

四、Composition API 的优势

1.Options API 存在的问题

使用传统OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 。

2.Composition API 的优势

我们可以利用hook函数更加优雅的组织我们的代码,函数。让相关功能的代码更加有序的组织在一起。

五、新的组件

1.Fragment

  • 在Vue2中: 组件必须有一个根标签
  • 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
  • 好处: 减少标签层级, 减小内存占用

2.Teleport

  • Teleport是一种能够将我们的组件html结构移动到指定位置的技术

  • 优点:

    • 不影响其他组件html的结构

      举例说明:在多层嵌套的组件结构中,我的孙组件有个弹窗组件,需要显示或隐藏,如果不使用Teleport,那么每次展示弹窗时候会影响别的组件html结构,而使用Teleport就不会影响

    • 方便定位,直接把html结构直接传送走,比如案例的传送至body处或者其他处。

  • 使用例子

    <teleport to="body">
      <div v-if="isShow" class="mask">
        <div class="dialog">
          <h1>弹窗</h1>
          <h2>内容:</h2>
          <h2>内容:</h2>
          <h2>内容:</h2>
          <button @click="isShow=false">关闭弹窗</button>
        </div>
      </div>
    </teleport>
    
    <style scoped>
    .app {
        background-color: #aa2222;
    }
    
    .mask{
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0,0,0,.5);
    }
    
    .dialog{
        position: absolute;
        top: 50%;
        left: 50%;
       transform: translate(-50%,-50%);
        width: 500px;
        background-color: #FF8A3B;
        padding: 10px;
        text-align: center;
    }
    
    </style>
    

    这种方式可以将标签内写的元素移动到to后面的元素后面,这样方便我们去做定位,例如这个例子相对于body进行垂直水平居中

    在这里插入图片描述

3.Suspense(后续可能更改)

  • 等待异步组件时渲染一些额外内容,让应用有更好的用户体验

  • 使用

    • 异步引入组件

      import {defineAsyncComponent} from "vue";
      const SusComp = defineAsyncComponent(()=>import("./components/03.新的标签/02.Suspense/SusComp.vue"))
      
    • 使用Suspense包裹组件,并配置好defaultfallback

      <Suspense>
       	异步组件返回的时候展示自己的标签
        <template v-slot:default>
      		<SusComp></SusComp>
        </template>
        
        异步组件没返回的时候展示fallback
        <template v-slot:fallback>
      		<h1>请稍等</h1>
        </template>
      
      </Suspense>
      
  • 注意:当使用异步引入组件的时候,被引入组件的setup可以返回一个promise

    setup(){
      let name = ref("ffff");
      return new Promise((resolve, reject)=>{
        setTimeout(()=>{
          resolve({name})
        },1000)
      })
    }
    

六、其他

1.全局API的转移

  • Vue 2.x 有许多全局 API 和配置。

    • 例如:注册全局组件、注册全局指令等。

      //注册全局组件
      Vue.component('MyButton', {
        data: () => ({
          count: 0
        }),
        template: '<button @click="count++">Clicked {{ count }} times.</button>'
      })
      
      //注册全局指令
      Vue.directive('focus', {
        inserted: el => el.focus()
      }
      
  • Vue3.0中对这些API做出了调整:

    • 将全局的API,即:Vue.xxx调整到应用实例(app)上

      在这里插入图片描述

2.其他改变

  • data选项应始终被声明为一个函数。

  • 过度类名的更改:

    • Vue2.x写法

      .v-enter,
      .v-leave-to {
        opacity: 0;
      }
      .v-leave,
      .v-enter-to {
        opacity: 1;
      }
      
    • Vue3.x写法

      .v-enter-from,
      .v-leave-to {
        opacity: 0;
      }
      
      .v-leave-from,
      .v-enter-to {
        opacity: 1;
      }
      

      v-enterv-leave 修改为 v-enter-fromv-leave-from

  • 移除 keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes

  • 移除 v-on.native修饰符

    • 父组件中绑定事件

      <my-component
        v-on:close="handleComponentEvent"
        v-on:click="handleNativeClickEvent"
      />
      
    • 子组件中声明自定义事件

      <script>
        export default {
      		//如果这里加上clikc,则click也会被当成自定义事件
          emits: ['close']
        }
      </script>
      

      ==注意:==使用emits声明的就是自定义事件,未声明的就当做原生事件

  • 移除 过滤器(filter)

过滤器虽然这看起来很方便,但它需要一个自定义语法,打破大括号内表达式是 “只是 JavaScript” 的假设,这不仅有学习成本,而且有实现成本!建议用方法调用或计算属性去替换过滤器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/511295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么我在大厂待了三个月就选择离开?我聊聊应届生该选择大厂还是小公司

我在互联网大厂只待了3个月就离开了&#xff0c;主要原因不是大厂的福利或者薪资不够好&#xff0c;只是因为我发现在大厂里每天都有开不完的会&#xff0c;忙碌到没有自己的生活。当时我每天10点上班&#xff0c;晚上要工作到11甚至是12点&#xff0c;甚至半夜两三点都接到过工…

LangChain-Agents 入门指南

LangChain-Agents 入门指南 LangChain-Agents 入门指南注册 Serpapi运行高级 Agents API 测试运行 Google Search其它 Here’s the table of contents: LangChain-Agents 入门指南 LangChain是一个使用LLMs构建应用程序的工具箱&#xff0c;包含Models、Prompts、Indexes、Mem…

Vue3-黑马(二)

目录&#xff1a; &#xff08;1&#xff09;vue3-ref与reactive &#xff08;2&#xff09;vue3-基础-属性绑定与事件绑定 &#xff08;3&#xff09;vue3-基础-表单绑定 &#xff08;1&#xff09;vue3-ref与reactive ref函数可以把普通的数据变成响应式的数据&#xff0…

Firewall Testing Checklist 分析

不管是在服务器、云技术、嵌入式、车载等场景&#xff0c;防火墙的作用尤为重要&#xff0c;下面从信息收集、管理审核流程、操作系统安全、已实现规则和检查配置&#xff0c;这五个方面来进行分析firewall的具体作用和能力&#xff0c;然后提供一些实用的网络firewall工具给大…

【Spring框架全系列】SpringBoot配置文件相关操作

&#x1f307;哈喽&#xff0c;大家好&#xff0c;我是小浪。上篇博客我们已经学习了如何创建一个Spring项目&#xff0c;那么创建Spirng项目还可以直接通过在Spring官网的方式来创建&#xff0c;做法也非常的简单&#xff0c;感兴趣的小伙伴可以在C站搜个教程尝试一下&#xf…

22年广东河南省赛-隐藏信息探索

任务十: 1、访问服务器的FTP服务,下载图片QR,从图片中获取flag,并将flag提交; QR.png的内容如下,可以看到,找到二维码的前三块都被反转了,需要反转回来,把这个二维码做成一个正方形,使用截图工具分隔、配合画图工具拼接+旋转。平均分为4块,分出4个方块。即可。 2、…

django 基本使用

django 下载 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django查看版本 django-admin --version 4.2.1创建项目 django-admin startproject project创建一个 app python manage.py startapp app注册 app project/settings # app名称.apps.app名称Config…

2023河南省赛vp题解

目录 A题&#xff1a; B题 C题 D题 E题 F题 G题 H题 I题 J题 K题 L题 A题&#xff1a; 1.思路&#xff1a;考虑暴力枚举和双hash&#xff0c;可以在O(n)做完。 2.代码实现&#xff1a; #include<bits/stdc.h> #define sz(x) (int) x.size() #define rep(i,z,…

头歌计算机算法设计与分析:随机化算法

第1关&#xff1a;硬币实验 任务描述 相关知识随机数 编程要求 测试说明任务描述 本关任务&#xff1a;计算机产生的伪随机数来模拟抛硬币试验。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.如何获取数组的长度&#xff0c;2.如何遍历数组。 随机数 随机…

基于 SpringBoot+WebSocket 无DB实现在线聊天室

0 项目说明 0.1 样例展示 0.2 源码地址 GitHub&#xff1a;https://github.com/ShiJieCloud/web-chat Gitee&#xff1a;https://gitee.com/suitbaby/web-chat GitCode&#xff1a;I’m Jie / web-chat GitCode 1 WebSocket 简介 1.1 HTTP 常用的 HTTP 协议是一种无状态…

【牛客刷题专栏】0x27:JZ29 顺时针打印矩阵(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转)&#xff0c;它登陆后会保存刷题记录进度&#xff0c;重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏&#xff1a;个人CSDN牛客刷题专栏。 题目来自&#xff1a;牛客/题库 / 在线编程 / 剑指offer&#xff1a; 目录 前言问…

2023年Pycharm安装教程,附详细图解

简介 PyCharm是一款Python IDE&#xff0c;其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&#xff0c;比如&#xff0c; 调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制等等。此外&#xff0c;该IDE提供了一些高级功能&a…

面向对象构造顺序与析构顺序详解

#include<bits/stdc.h> using namespace std;class animal{public:animal(){cout<<"调用animal构造"<<endl;}~animal(){cout<<"调用animal析构"<<endl;} };class verhical{public:verhical(){cout<<"调用verhica…

服装供应链管理包含哪些内容,如何选择服装供应链管理系统?

服装供应链管理是指对服装工厂的采购、生产、物流、仓储和销售等环节的管理&#xff0c;包括原材料的采购、成品的制造、配送、零售等多个环节。 选择合适的服装供应链管理系统&#xff0c;能够帮助服装工厂提高供应链管理的效率、优化库存管理、降低运营成本、保证服装生产的品…

TCP协议三次握手四次挥手详细分析

在学习TCP协议的时候&#xff0c;接触最多的就是TCP的三次握手和四次挥手。关于这个的介绍大多数都是文字和图示来分析的&#xff0c;但是具体到协议的内容时&#xff0c;有可能还是不清楚&#xff0c;下面我就通过具体协议来分析一下这个过程。 这里使用Wireshark网络分析工具…

【Linux】进程与文件系统(上)

由于这部分的知识很多很多&#xff0c;分成两回 目录 1.文件描述符 文件描述符 1.文件描述符 首先我们看一下几个小问题 1.你真的理解文件原理和操作了吗&#xff1f; 这不是语言的问题&#xff0c;而是操作系统的问题 2.是不是只有C/C有文件操作&#xff1f; 其他语…

【数据结构】结构最复杂实现最简单的双向带头循环链表

【数据结构】结构最复杂实现最简单的双向带头循环链表 一、前言二、目标三、实现1、初始化工作2、尾插2.1、图解思路2.2、代码实现 3、尾删3.1、图解思路3.2、代码实现 4、打印链表5、头插5.1、图解思路5.2、代码实现 6、头删6.1、图解思路6.2、代码实现 7、查找8、随机插入8.1…

数据结构与算法基础(青岛大学-王卓)(2)

第二弹火爆来袭中 这波是单链表的内容整理&#xff0c;废话不多说&#xff0c;上小龙虾呀(又到了龙虾季节了&#xff0c;哎&#xff0c;口水直流了~~) beautiful的分割线 文章目录 第二弹火爆来袭中这波是单链表的内容整理&#xff0c;废话不多说&#xff0c;上小龙虾呀(又到了…

【致敬未来的攻城狮计划】— 连续打卡第二十七天:瑞萨RA RA2E1 的 BTN触摸按键

文章目录 由于一些特殊原因&#xff1a; 系列文章链接&#xff1a;&#xff08;其他系列文章&#xff0c;请点击链接&#xff0c;可以跳转到其他系列文章&#xff09;或者参考我的专栏“ 瑞萨MCU ”&#xff0c;里面是 瑞萨RA2E1 系列文章。 24.RA2E1的 DMAC——数据传输 25.R…

DB2_sql_问题

db2新增字段指定顺序 这个是不能做到的&#xff0c;除非把表删除重新创建的&#xff01; 原理是这样子的&#xff1a;当你创建表时系统会记录下你的SEQ-ID,就是字段的顺序号&#xff0c;这个是根据字段先后顺序来生成的&#xff0c;系统默认显示的时候也是根据这个来的&#x…