目录

1.vue3带来的新变化(加+)

2.移除vue2中的某些语法(减-)

3.目录变化

4.组合式API和选项式API的区别

         5.组合API-setup函数

6 . 组合API-生命周期

         7.组合API-ref函数

         8.组合API-ref属性(注意上面是函数,这里是属性)

         9. 组合API-reactive函数

         10. 组合API-toRefs函数

         11.如何确定什么时候用ref和reactive

         12. 组合API-computed函数

         13. 组合API-computed的高级用法

         14. 组合API-watch函数

      14.1 侦听-开启立刻执行

      14.2 监听-复杂数据

      14.3侦听-复杂数据的指定属性

       15. 组合API-父子通讯

       16. vue3中的v-model语法糖

       18. 组合API-依赖注入-祖先传后代

       19. 组合API-依赖注入-后代改祖先

总结:


1.vue3带来的新变化(加+)


新的名词:Composition API(组合式API)

这是重点,它提供新的写代码的方式 

  三个点:

1.1 性能提升 

首次渲染更快,diff算法更快,内存占用更少,打包体积更小


1.2 更好的Typescript支持(在vue下写TS更方便了)


1.3 提供新的写代码的方式:Composition API


2.移除vue2中的某些语法(减-)


vue3.0兼容大部分2.0版本(之前是怎么写的,现在也正常写),但是也有一些破坏性的语法更新


2.1 移除了$on方法 (eventBus现有实现模式不再支持,可以使用三方插件替代)

2.2 移除过滤器选项 (插值表达式里不能再使用过滤器filter, 可以使用methods替代)

2.3 移除 .sync语法(v-bind时不能使用.sync修饰符了,现在它v-model语法合并了)


3.目录变化


主要看三个文件位置的变化:(不重要,了解即可)


 3.1 package.json文件中,版本变成3.0

"dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
}

 3.2  main.js文件中的变化

import { createApp } from 'vue'  +++
import App from './App.vue' // 根组件        之前是new Vue的形式
createApp(App).mount('#app')     +++

3.3  app.vue  中的变化

vue3.0的单文件组件中不再强制要求必须有唯一根元素(之前都被div包裹)

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
  <外面不用div标签包括了,可以一直写同级标签,更加随意了>
</template>

上面是开胃菜,重点是下面的东西


 

4.组合式API和选项式API的区别


vue2中的叫选项式API(options),vue3中的叫组合式API(Composition API )

这里也是介绍,了解即可


options API(Vue2)特点:

比如数据就写到data选项中,方法就写到methods中…


composition API(Vue3) 特点:

是特定功能相关的所有东西都放到一起维护,比如功能A相关的变量和方法放到一起


 vue3有点像js,对功能做了封装。不停的封装函数,不停的引用

 


 4.1 优缺点小结:


Vue2选项式API(option api):

优点:简单,各选项各司其职;

缺点:不方便功能复用;功能代码分散维护代码横跳


Vue3组合式API(composition api)

优点:

功能代码组合维护, 方便功能复用


4.2 Vue3组合式API (composition api) 【重点】

按照功能划分,在setup函数中写,每个功能里面变量和函数可以写在一起,如果功能扎堆代码量很大怎么办?拆解setup中的功能代码成一个一个函数


步骤:1.我们可以在.js文件定义方法,也可以在script标签里面写功能函数。

           2. 然后在setup函数中调用

           3.可以使用解构赋值的方式将函数里面的方法和变量取出来使用


注意:函数是一个独立的作用域,函数之间的变量互不干扰。

<script>
位置:<script>和export default之间。当然写在别的.js文件中也行
步骤1:定义函数,写逻辑(看位置,我是在这里写的,最后记得return出去)
       
function useShow() {
  function show() {
    showDivFlag.value = true
  }
  function hide() {
    showDivFlag.value = false
  }
//步骤1:将里面的函数和变量return出去,好给setup里面使用
  return { showDivFlag, show, hide } 
}

export default {
  name: 'App',
  setup() {
    // 功能一
    //步骤2 引入步骤1写的函数,并解构
    const { showDivFlag, show, hide } = useShow()  
  
    return { showDivFlag, show, hide, fontColor, changeRed, changeBlue }
  }      //步骤3:return 函数或者变量,目的是给模板使用
}
</script>

小结:我们通过定义功能函数,把两个功能相关的代码各自抽离到一个独立的小函数中,然后通过在setup函数中再把两个小功能函数组合起来,这样一来,我们既可以把setup函数变得清爽,又可以方便维护快速定位功能位置。


5.组合API-setup函数


5.1 特点:

  1. setup 函数是一个新的组件选项,作为组件中组合式API 的起点(类比data的作用)

  2. setup 中不能使用 this, this 指向 undefined(这个哥们执行时机太快了)

  3. setup函数只会在组件初始化的时候执行一次

  4. setup函数在beforeCreate生命周期钩子执行之前执行(执行时机)


 5.2 参数

 第1个参数为props。props为一个对象,内部包含了父组件传递过来的所有prop数据


第2个参数为一个对象context。context对象包含了attrs,slots, emit属性

如:子传父原来的写法是this.$(emit),而这里就不行了,因为this指向underfined

正确的写法 :context.emit(),当然也可把参数解构赋值setup(props,{emit})

setup(props, context) {
    console.log(props)
    context.emit('XXX',值) //注意格式,不能用this了
    return{XX}
}

 5.3 返回值

setup()返回一个对象,如果在data()中也定义了同名的数据,则以setup()中为准。


 5.4 小结

1.setup的执行时机?           比beforeCreate先执行

2. setup内部可以通过this访问到组件吗?             不能 结果是underfined

3. 它的返回值格式是?               对象


6 . 组合API-生命周期


vue2是8个,而vue3只有7个,将前面两个变成了setup

 `setup`            创建实例前
 `onBeforeMount`    挂载DOM前
 `onMounted`        挂载DOM后
 `onBeforeUpdate`   更新组件前
 `onUpdated`        更新组件后
 `onBeforeUnmount`  卸载销毁前
 `onUnmounted`      卸载销毁后

 小结:1.组合API(vue3)的生命周期钩子有7个,它们都是回调函数的格式。可以多次使用同一个钩子,执行顺序和书写顺序相同

            2.不建议vue2, vue3混合使用


7.组合API-ref函数


问题:在seup中的返回的数据不是响应式的 

作用:使用ref函数定义响应式数据

使用步骤:

  1. 从vue框架中导入ref函数

  2. 在setup函数中调用ref函数并传入数据(简单类型或者复杂类型)

  3. 在setup函数中把ref函数调用完毕的返回值以对象的形式返回出去

<template>
  公司:{{company}} //步骤4,在模板中使用
</template>
<script>
import { ref } from 'vue'  // 步骤1.引入ref
export default {
  setup () {
    // 步骤2.定义响应式对象
    const company = ref('DiDi')
   // 在代码中修改(或者获取)值时,需要补上.value
      salary.value *= 2
 
    return { company } //步骤3,导出数据
             
  }
}
</script>

小结:ref函数,用来定义响应式数据 ,在代码中修改(或者获取)值的时,需要补上.value ,模板中使用不需要加.value


8.组合API-ref属性(注意上面是函数,这里是属性)


问题:如何获取子组件(DOM)的引用?

作用:掌握使用ref属性绑定DOM或组件

步骤:

  1. 导入ref函数

  2. 使用ref函数传入null创建 ref对象 => const hRef = ref(null)【固定格式】

  3. setup中导出

  4. 模板中使用ref绑定

<template>
  <div class="container">
    <div ref="dom">我是box</div>
    <button @click="hClick"></button> // 步骤四:模板中使用
  </div>
</template>
<script>
import { onMounted, ref } from 'vue' //步骤1:导入ref函数
export default {
  name: 'App',
  setup () {
    // 步骤二:使用ref函数传入null创建ref对象
    const dom = ref(null)
    const hClick(()=>{
       console.log(dom.value)
    })
    
    return {dom, hClick}  //步骤三:导出
  }
}
</script>


小结:先导入ref,再申明ref响应式数据,返回给模板使用,通过ref绑定数据


9. 组合API-reactive函数


背景:ref函数定义的响应式数据在代码中使用要加.value,不是很方便。

作用:简化ref的写法(老是写xxx.value),它可以定义一个复杂数据类型,成为响应式数据。


使用步骤:

  1. 导入:从vue框架中导入reactive函数

  2. 调用:在setup函数中调用reactive函数并将对象数据传入

  3. 导出:在setup函数中把reactive函数调用完毕之后的返回值以对象的形式返回出去

演示代码:

<template>

  <p>姓名:{{stu.name}}, 公司:{{stupany}},月薪:{{stu.salary}}</p>
  <button @click="double">月薪double</button>  //步骤4,在模板使用
</template>

<script>
import { reactive } from 'vue' //步骤1:导入reactive
export default {
  setup () {
    const stu = reactive({ //步骤2:给reactive传入数据
      company: 'DiDi',
      name: '小王',
      salary:18000
    })

    const double = () => {
      stu.salary *= 2
      console.log('stu.salary', stu.salary)
    }
    return {  
      stu,            //步骤3:导出
      double
    }
  }
}
</script>


 小结:reactive用来定义响应式数据


10. 组合API-toRefs函数

作用:定义转换响应式中所有属性为响应式数据,通常用于解构|展开reactive定义对象, 简化我们的在模板中的使用

格式:

增强版的结构赋值:在解构对象的同时,保留响应式的特点。
// 响应式数据:{ 属性1, 属性2 }
let { 属性1, 属性2 } = toRefs(响应式数据)

代码举例:

<template>
  <p>{{name}}, {{company}}</p>
  <button @click="jumpToJD">jumpToJD</button>
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
  name: 'App',
  setup () {
    // 定义响应式对象
    const stu = reactive({
      company: 'DiDi',
      name: '小王'
    })
    let { name, company } = toRefs(stu)

    const jumpToJD = () => {
      company.value = 'JD'
      name.value = '老王'
      console.log('toJD', company)
    }
    return {  name, company, jumpToJD }
  }
}
</script>

10.1 toRefs与reactive配套使用。

在解构响应式数据时,还保持它的响应式特征。

const {p1, p2} = toRefs(reactive({p1, p2}))

11.如何确定什么时候用ref和reactive


定义响应式数据有两个方式:

  • ref函数,常用于将简单数据类型定义为响应式数据

    • 在代码中修改(或者获取)值时,需要补上.value

    • 在模板中使用时,可以省略.value 

 reactive函数,常用于将复杂数据类型为响应式数据


 

12. 组合API-computed函数


作用:根据已有数据生成新的响应式数据。(对数据做处理)

步骤:

  1. 从vue框架中导入computed 函数

  2. 在setup函数中执行computed函数,并传入一个函数,在函数中定义计算规则,并返回结果

  3. 把computed函数调用完的执行结果放到setup的return值对象中

格式:

import { computed } from 'vue'

const 计算属性名 = computed(() => {
  return 响应式数据相关计算
})

代码示例:


<template>
  <p>姓名:{{name}}, 公司:{{company}}, 月薪:{{salary}}, 年薪{{total}}</p>
  <button @click="double">月薪double</button>
</template>
<script>
import { ref, computed } from 'vue'   步骤1:导入computed
export default {
  name: 'App',
  setup () {
    // 定义响应式对象
    const company = ref('DiDi')
    const name = ref('小王')
    const salary = ref(18000)
    const double = () => {
      salary.value *= 2
    }
    const total = computed(() => 12 * salary.value) //步骤2 计算规则
    
    return {    步骤3 返回计算后的数据
      name, 
      company,
      total,
      salary,
      double
    }
  }
}
</script>

小结: vue3中的computed函数与vue2中的computed选项功能类似


13. 组合API-computed的高级用法


目标:掌握计算属性的高级用法:设置set属性, 会用v-model来绑定计算属性

格式:

const 计算属性 =  computed({
  get () {
    
  },
  set () {
    
  }
  
})

代码举例:

<template>
  <p>{{name}}, {{company}}, {{salary}}, {{total}}</p>
  <input type="text" v-model="total">
</template>
<script>
import { ref, computed } from 'vue'
export default {
  name: 'App',
  setup () {
    // 定义响应式对象
    const company = ref('DiDi')
    const name = ref('小王')
    const salary = ref(18000)
    const bonus = ref(20000)
    const double = () => {
      salary.value *= 2
    }
    const total = computed({
      set:(value) => {
        salary.value  = value / 12
      },
      get: () => {
        return 12 * salary.value
      }
    })
    return {  
      name, 
      company,
      total,
      salary,
      double
    }
  }
}
</script>

小结:

计算属性两种用法

  1. 给computed传入函数,返回值就是计算属性的值

  2. 给computed传入对象,get获取计算属性的值,set监听计算属性改变,做逻辑运算


14. 组合API-watch函数

是什么:监听,又叫侦听器

作用:监听响应式数据的变化,执行逻辑,和vue2差不多


步骤:

1.从vue框架中导入watch函数

2.在setup函数中执行watch函数开启对响应式数据的监听

3.watch函数接收三个常规参数

 3.1 第一个参数是:  

对象,要监听的响应式数据;

数组,每个元素是响应式数据函数,返回你要监听变化的响应式数据

函数,返回你要监听变化的响应式数据

3.2 第二个参数是:响应式数据变化之后要执行的回调函数

3.3 第三个参数是: 一个对象,在里面配置是否开启立刻执行或者深度监听


特点:可以侦听一个,也可以侦听多个,侦听多个的时候使用数组的形式


14.1 侦听-开启立刻执行

watch的效果默认状态下,只有监听的数据发生变化才会执行回调,如果你需要在一上来的时候就立刻执行一次

设置: immediate: true


14.2 监听-复杂数据


如果watch的第一个参数是响应数据的话,它会默认监听其下所有属性的变化。

当我们监听的数据(第一个参数)是通过回调返回的一个对象的时候,默认状态下,对象内部的属性发生变化是不会被侦听到的,如果想让对象下面所有属性都能得到监听,需要开启deep配置。

设置:deep:true


14.3侦听-复杂数据的指定属性


使用watch的时候,尽量详细的表明你到底要监听哪个属性,避免使用deep引起的性能问题,比如,仅只是想在stu对象的money属性的salary变化的时候执行回调,可以这么写 stu.money.salary

作用:watch用来侦听数据的变化。

格式:watch(数据|数组|get函数,(新值,旧值)=>{回调处理逻辑}, {immediate:true|false, deep: true|false})


15. 组合API-父子通讯


 区别不大。唯一不同的是子组件中的使用

父传子:在setup种使用props数据 setup(props){ // props就是父组件数据 }

子传父:触发自定义事件的时候emit来自 setup(props,{emit}){ // emit 就是触发事件函数 }

在vue3.0中 v-model.sync 已经合并成 v-model 指令


16. vue3中的v-model语法糖


 有点变化:

<Son v-model="msg" />
<!--vue3中 上面的写法等价于下边--------------->  
<Son :modelValue="msg"  @update:modelValue="val=>msg=val"/>`

小结: 

在setup的两个参数中获取props和emit

父传子 props: :modelValue

子传父 emit @update:modelValue


 

vue3 中可以使用多个v-model

<Son v-model:xxx="msg"/>
-----相当于下边------------  
<Son :xxx="msg"  @update:xxx="val=>msg=val"/>`


18. 组合API-依赖注入-祖先传后代


组件通信:可以实现跨越多个组件的数据传递,如爷孙组件的数据传递

注意:后代组件不能直接修改祖宗传过去的值,遵循的原则是谁提供的数据谁来改,可以让祖宗组件穿一个修改的方法

使用步骤:

  1. 祖先组件中提供数据: provide('数据名1', 数据名)

  2. 后代组件中使用数据: inject('数据名1')


小结: provide函数提供数据和函数给后代组件使

inject函数给当前组件注入provide提供的数据和函数

代码举例:

父组件:

<template>
  <div class="container">
    <h1>父组件 {{money}} <button @click="money=1000">发钱</button></h1>
    <hr>
    <Son />
  </div>
</template>
<script>
import { provide, ref } from 'vue'
import Son from './Son.vue'
export default {
  name: 'App',
  components: {
    Son
  },
  setup () {
    const money = ref(100)
    // 将数据提供给后代组件 provide
    provide('money', money)

    return { money }
  }
}
</script>
<style scoped lang="less"></style>

子组件: 

<template>
  <div class="container">
    <h2>子组件 {{money}}</h2>
    <hr>
    <GrandSon />
  </div>
</template>
<script>
import { inject } from 'vue'
import GrandSon from './GrandSon.vue'
export default {
  name: 'Son',
  components: {
    GrandSon
  },
  setup () {
    // 接收祖先组件提供的数据
    const money = inject('money')
    return { money }
  }
}
</script>
<style scoped lang="less"></style>

 孙子组件:

<template>
  <div class="container">
    <h3>孙组件 {{money}} <button @click="fn">消费20</button></h3>
  </div>
</template>
<script>
import { inject } from 'vue'
export default {
  name: 'GrandSon',
  setup () {
    const money = inject('money')

    return {money}
  }
}
</script>
<style scoped lang="less"></style>

19. 组合API-依赖注入-后代改祖先


步骤:

  1. 祖先组件中提供数据&操作数据的函数f: provide('函数f', 数据名)

  2. 后代组件中获取操作数据的函数f,并调用数据: inject('函数f')


为方便多年后来查找,做一个极简版的

总结:

1.setup()函数是一个新的组件选项,里面按照功能划分,变量函数可以在一起写。

2.生命周期由8变成7个,setup函数合并了之前的前两个,在组件创建前的钩子前执行(快)

3.ref函数,把数据变成响应式的,在代码中使用要加.value 。简单和复杂类型都能处理。推荐

4.reactive函数,作用是把复杂类型数据变成响应式,当明确知道对象有什么属性时,如表单数据

5.toRefs函数,转换响应式中所有属性为响应式,通常用于解构,展开对象,简化在模板的使用,增强版的解构赋值,解构的同时,保留响应式的特点

6puted函数,计算属性,注意使用格式(导入,定义,导出 )注意其高级用法(set、get),会用v-model来绑定计算属性

7.watch监听(也叫侦听),使用场景和vue2一样,注意他的三个参数和使用格式

8.父子通讯。注意子组件,setup(props,context)第一个参数代表父传子数据,第二个可以context.emit('',XX)进行子传父

9.v-model的语法糖。注意就是名字变了叫 :modelValue和 @update:modelValue事件

10 依赖注入。组件通信,祖宗传后代。祖先组件提供数据provide('数据名1', 数据名)。后代使用数据inject('数据名1')。如果后代想修改数据让祖宗传修改的方法。规则是谁提供的数据谁提供修改的方法

更多推荐

Vue3新特性和使用方法系统总结