Vue 3.0 学习笔记

这篇具有很好参考价值的文章主要介绍了Vue 3.0 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Vue 3 学习笔记

一、初识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实现,通过代理对象操作源对象内部数据都是响应式的

Vue 3.0 学习笔记

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
    

    效果:

    Vue 3.0 学习笔记

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

      Vue 3.0 学习笔记

    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的生命周期对比

Vue 3.0 学习笔记

2.生命周期对应
vue 2.0 vue 3.0 对应setup中组合api 备注
setup -无 setup是3.0提出的
beforeCreate beforeCreate 被setup取代 创建前
created created 被setup取代 创建
beforeMount beforeMount onBeforeMount() 挂载前
mounted mounted onMounted() 挂载
beforeUpdate beforeUpdate onBeforeUpdate() 更新前
updated updated onUpdated() 更新
beforeDestroy beforeUnmount(改名) onBeforeUnmoun() 卸载前(2.0的钩子被改名)
destroy unmounted(改名) 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

Vue 3.0 学习笔记

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

  • 使用:父组件利用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里修改 。

Vue 3.0 学习笔记Vue 3.0 学习笔记

2.Composition API 的优势

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

Vue 3.0 学习笔记Vue 3.0 学习笔记

五、新的组件

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进行垂直水平居中

    Vue 3.0 学习笔记

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)上

      Vue 3.0 学习笔记

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” 的假设,这不仅有学习成本,而且有实现成本!建议用方法调用或计算属性去替换过滤器。文章来源地址https://www.toymoban.com/news/detail-438678.html

到了这里,关于Vue 3.0 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3学习笔记

    源码升级 Vue2是通过Object.defineProperty实现响应式,Vue3是通过 Proxy 实现响应式 重写虚拟DOM的实现和Tree-Sharking 1.1 使用Vue-cli创建 官方文档:Vue-cli 1.2 使用Vite创建 官方文档:V3 vite官网:Vite 什么是vite?—— 官网定义是下一代前端构建工具。 优势如下: 开发环境中,无需打包操

    2024年02月12日
    浏览(31)
  • 【Vue】初识Vue,Vue简介及Vue Devtools配置

    1. Vue是什么 关于这个问题官方给了我们答案: 一套用于 构建用户界面 的 渐进式 JavaScript框架 渐进式框架是指我们可以在项目中一点点来引入和使用Vue,而不一定需要全部使用Vue来开发整个项目; 2020年9月18日Vue3.0.0正式发布别名 One Piece (没错就是海贼王)。 2. Vue的特点

    2024年02月15日
    浏览(31)
  • 「Vue3面试系列」Vue 3.0中Treeshaking特性有哪些?举例说明一下?

    Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination 简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码 如果把代码打包比作制作蛋糕,传统的方式是把鸡蛋(带壳)全部丢进去搅拌,然后放入烤箱,最后把(没有

    2024年02月01日
    浏览(28)
  • Vue3学习笔记(9.6)

    Vue3混入 混入(mixins)定义了一部分可复用的方法或者计算属性。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。 选项合并 当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。 比如,数据对象在内

    2023年04月09日
    浏览(27)
  • [Vue3]学习笔记-customRef

    概念 按照文档中的说明:customRef 可以用来创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track 和trigger函数作为参数,并且应该返回一个带有 get 和 set 的对象。 其实大致意思就是,我们可以按照自己的业务需求去自定义

    2024年02月12日
    浏览(26)
  • vue3组件通信学习笔记

    父组件 子组件 父组件 子组件 子组件1 子组件2 父组件 子组件 父组件 子组件 父组件 子组件 父组件 子组件 父组件 子组件 孙子组件 1、选择式写法 1、info.js 2、在组件1中使用 3、在组件2中使用 2、组合式API写法 1、在modules文件夹下新建todo.js 2、在组件1中使用 3、在组件2中使

    2024年02月09日
    浏览(31)
  • 学习笔记之Vue3(七)

    一、Vue3简介 2020年9月18日,Vue.js发布3.0版本, 代号: One Piece (海贼王) 耗时2年多、2600+次提交、 30+个RFC、 600+次PR、 99位贡献者 github 上的tags地址: https://github.com/vuejs/vue-next/releases/tag/v3.0.0 二、Vue3带来了什么 1.性能的提升 打包大小减少41%; 初次渲染快55%,更新渲染快133%; 内存

    2024年02月07日
    浏览(27)
  • 【Vue3】学习笔记-生命周期

    Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名: beforeDestroy 改名为 beforeUnmount destroyed 改名为 unmounted Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下: beforeCreate === setup() created ======= setup() beforeMount === onBeforeMount mounted ======= onMo

    2024年02月11日
    浏览(35)
  • VUE3 学习笔记(八)引入 EasyUI for Vue

      目录 一、什么是 EasyUI? 二、安装EasyUI for Vue3 1. 使用NPM安装 2. 导入EasyUI 三、安装完成出现问题解决 easyui是一个基于jQuery、Angular、Vue和React的用户界面组件的集合。 easyui为构建现代的、交互式的、javascript应用程序提供了基本功能。 使用easyui,你不需要写很多javascript代码,

    2023年04月21日
    浏览(24)
  • 【Vue3】学习笔记-新的组件

    在Vue2中: 组件必须有一个根标签 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中 好处: 减少标签层级, 减小内存占用 什么是Teleport?—— Teleport 是一种能够将我们的 组件html结构 移动到指定位置的技术。 等待异步组件时渲染一些额外内容,让应

    2024年02月16日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包