【Vue3】快速入门Vue3 -上篇

简介: 【Vue3】快速入门Vue3 -上篇

001.setup的配置


setup为vue3的配置项,可以再其中写vue2的数据,方法等。该函数的返回值为一个对象,返回的对象可以使用于模板解析


也可以在vue3中使用vue2中的配置项,但vue2可以访问vue3配置的数据,而vue3中不能访问vue2的数据。


且在数据名相同的情况下,模板解析以vue3的为先


<script>
export default {
  name: 'App',
  setup(){
    let name = 'su'
    let age = 21;
    let num = 1;
    function add(){
      alert(`${name},${age},${num}`)
    }
    return {
      name,
      age,
      num,
      add
    }
  }
}
</script>


002.ref函数与reactive函数


  • ref定义一个响应式的数据,语法const name = ref('su') , 这样su就为一个响应式的数据了,而name则变成了一个refimpl(应用实现的实例对象 - 简称:引用对象) 通过name.value可以修改name的值。且为响应式的数据。


  • 在模板中只需要调用{{name}}即可,vue3会自动在模板中给我们调用.value属性。


  • ref函数接收的数据可以为:基本类型/对象。基本类型仍然通过object.defineProperty的get和set来实现。对象类型则通过vue3中的reactive函数来实现数据响应式。


  • reactive 函数: 定义一个对象类型的响应式数据。


  • 语法const 代理对象 = reactive(源对象)/数组 返回的是一个代理对象(proxy)


reactive定义的响应式数据是深层次的。内部基于es6的Proxy实现,通过代理对象操作源对象内部数据进行操作。


003.vue3响应式原理


回顾vue2响应式实现原理:


<script>
let person = {
    name :'su',
    age:21
}
let p = {};
// 模拟vue2中的响应式 - 只有数据被读取或修改时为响应式,添加和删除时不为响应式。
Object.defineProperty(p,'name',{
    get(){
        console.log('数据被读取!!');
        return person.name;
    },
    set(value){
        console.log('数据被修改!!');
        person.name = value;
    }
})
</script>


vue3实现响应式原理:


<script>
let person = {
    name :'su',
    age:21
}
 //模拟vue3中的响应式
let p = new Proxy(person,{
     // 读取p的属性时调用
     // target - 代理的源对象, propName - 读取/修改的属性
     get(target,propName){
         console.log('数据被读取!');
         return Reflect.get(target,propName)
     },
     // 添加 / 修改 p的属性时 调用
     set(target,propName,value){
         console.log('数据被修改');
         Reflect.set(target,propName,value)
     },
     // 删除p的属性时调用
     deleteProperty(target,propName){
         console.log('数据被删除!');
         return Reflect.deleteProperty(target,propName);
     },
 })
</script>


  • 通过proxy(代理)拦截对象中任意属性的变化 - 属性的增删改查等


  • 通过Reflect(反射)对被代理对象的属性进行操作


reactive对比ref


  • 从定义角度:ref用来定义基本数据类型。reactive用于定义对象/数组类型数据


  • 实现响应式原理:ref通过object.defineProperty的get和set来实现响应式(数据劫持)。reactive通过使用Proxy来实现,并通过Reflect操作源对象内部的数据。


  • 从使用角度来说: ref操作数据需要用.value。读取时则直接使用。reactive在操作或读取数据时都不需要.value


004.setup的两个注意点


  • setup的执行时期:在beforcreate之前执行,this为undefined


  • setup的参数:


  1. 第一个参数 - props:值为对象,包含组件外部传递进来且组件内部声明接收的数据。


  1. 第二个参数 - context:上下文对象。attrs:值为对象,包含组件外部传递且在组件内部没有声明接收的数据,相当于vc身上的this.$attrs。slots:收到的插槽内容。相当于this.$slots。emit:分发自定义事件的函数,用于触发自定义事件并传递数据,相当于this.$emit


005.vue3中的计算属性


与reactive函数一样,vue3中的计算属性函数也需要引入。import {reactive,computed} from 'vue'


<script>
    setup(){
      let data = reactive({
        firstName:'三',
        lastName:'张'
      })
      // vue3 的计算属性 - 接收一个回调函数 返回值 - 简写
      // let fullName = computed(()=>{
      //   return `${data.lastName} - ${data.firstName}`
      // })
      //  vue3 的计算属性 - 接收一个回调函数 返回值 - 完整写法
      let fullName = computed({
        get(){
          return `${data.lastName}-${data.firstName}`
        },
        set(value){
          let arrName = value.split('-');
          data.lastName = arrName[0];
          data.firstName = arrName[1]
        }
      })
      return {
        data,
        fullName
      }
    }
</script>


  1. 简写形式:在computed中传递一个回调函数,返回一个值作为声明变量的值。此时的计算属性只能读,不能改


  1. 完整形式:与vue2中的计算属性写法一致。有get和set。此时的计算属性可读可改


006.监视ref定义的数据


  1. 与reactive函数一样,watch同样在vue3中也是一个暴露出来的函数。在setup中直接调用即可;


watch可以接收三个参数:


  • 第一个参数:要监听的数据


  • 第二个参数:回调函数,接收两个参数,一个为监听的数据的新值,一个为旧值。


  • 第三个函数:配置是否进行立即监听/深度监听。


<script>
    setup(){
      let sum = ref(0);
      let msg = ref('你好')
      function add(){
        sum.value = sum.value +1;
      }
      // vue3中的监视 - 第一个参数:监视的数据 第二个参数:回调函数 第三个参数:其余配置项-如immediate,deep等配置
      //  监视一个数据时
      // watch(sum,(newValue,oldValue)=>{
      //   console.log(`新值:${newValue},旧值:${oldValue}`);
      // },{immediate:true})
      // 监视两个数据时
      watch([sum,msg],(newValue,oldValue)=>{
        console.log(`新值:${newValue},旧值:${oldValue}`);
      },{immediate:true})
      return {
        sum,
        msg,
        add
      }
    }
</script>


007.监视reactive定义的数据


  • 监听reactive定义的数据时


  1. 在vue3中监听reactive定义的数据时,当其中的数据发生改变,vue3不监听到旧的数据(oldValue无法正确读取)



  1. 强制开启了深度监视(配置deep:false无效)


  • 监听reactive中的其中某个值时


需要将值写为一个回调函数,返回值为监听的属性值。监视多个值同理写在一个数组里


  • 特殊情况


监听reactive中的属性值仍为一个对象时,需要开启深度监视,且oldValue仍无法正确读取。


<script>
    setup(){
      let sum = ref(0);
      let msg = ref('你好')
      let person = reactive({
        name:'zhangsan',
        age:21,
        job:{
          j1:{
            salary:12
          }
        }
      })
      // vue3监听reactive定义的数据 -vue3中当数据改变时无法监听到旧的数据。 -强制深度监视
      watch(person,(newValue,oldValue)=>{
        console.log('新值:',newValue,'旧值:',oldValue);
      })
      // 监视reactive中的某个属性值 - 第一个参数写成一个回调函数,返回值为需要监视的数据,多个值写在一个数组里
      watch(()=>person.age,(newValue,oldValue)=>{
        console.log('新值:',newValue,'旧值:',oldValue);
      })
      // 监视reactive中的一个属性,且改属性仍为一个对象 - 需要开启深度监视 ,但oldValue仍无法正确读取
      watch(()=>person.job,(newValue,oldValue)=>{
        console.log('新值:',newValue,'旧值:',oldValue);
      },{deep:true})
      return {
        sum,
        msg,
        person
      }
    }
</script>


008.watchEffect函数


与watch不同的是,watchEffect函数不用指明监视哪个属性,监视中的回调用到了哪个属性就监视哪个属性。且默认开启立即监视。


  • watchEffect与computed有点类似。


所依赖的数据发生改变时,就会重新调用函数。


不同的是:computed更注重计算出来的值(函数的返回值),因此必须写返回值。而watchEffect更注重过程(函数的回调),因从不需要写返回值。


<script>
  setup(){
      let sum = ref(0);
      let msg = ref('你好')
      let person = reactive({
        name:'zhangsan',
        age:21,
        job:{
          j1:{
            salary:12
          }
        }
      })
      // 不用声明监视哪个数据,用到哪个数据就监视哪个。当数据发生改变时,重新执行该函数。默认开启立即监视
      watchEffect(()=>{
        let a = sum.value;
        let b = person.job.j1.salary;
        console.log('数据发生了改变!');
      })
      return {
        sum,
        msg,
        person
      }
    }
</script>


009.vue3中的生命周期


vue3的生命周期对比vue3的生命周期基本相同。最大的不同就是vue2中的销毁在vue3中变为了卸载。


其次是vue2中是创建实例之后即为生命周期的开始。在创建完毕之后才挂载元素。在vue3中是一切准备就绪后才进入生命周期。


vue2生命周期官方图示:



vue3生命周期官方图示:



在vue3中使用生命周期钩子有两种方式:


  1. 使用配置项,用法与vue2相同。


<script>
  import {ref} from 'vue'
  export default {
    name: 'App',
    setup(){
      let sum = ref(0);
      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');
    },
    beforeUnmount(){
      console.log('beforeUnmount');
    },
    unmounted(){
      console.log('unmounted');
    }
  }
  </script>


  1. 使用组合式api,使用就引用,接收一个回调函数。在回调函数内写业务逻辑。


 <script>
  import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
  export default {
    name: 'App',
    setup(){
      let sum = ref(0);
      //使用组合式 API
      onBeforeMount(()=>{
        console.log('onBeforeMount');
      }),
      onMounted(()=>{
        console.log('onMounted');
      }),
      onBeforeUpdate(()=>{
        console.log('onBeforeUpdate');
      }),
      onUpdated(()=>{
        console.log('onUpdated');
      }),
      onBeforeUnmount(()=>{
        console.log('onBeforeMount');
      }),
      onUnmounted(()=>{
        console.log('onUnmounted');
      })
      return {
        sum
      }
    },
  }
  </script>


010.自定义hook函数


在src目录下创建一个hooks文件夹,在该文件下写hook函数,当其他组件想使用时引入即可。即做到代码复用的效果。


  • 本质为一个函数,把setup中的使用的组合式API进行封装。如:


import {reactive,onMounted,onBeforeUnmount} from 'vue'
export default function(){
    // 获取坐标点相关的数据
    let point = reactive({
        x:0,
        y:0
    })
    //  获取坐标点相关的方法
    function savePoint(event){
        point.x = event.clientX;
        point.y = event.clientY
    }
    // 获取坐标点相关的生命周期钩子
    onMounted(()=>{
        window.addEventListener('click',savePoint)
    })
    onBeforeUnmount(() => {
        window.removeEventListener('click',savePoint)
    })
    return point
}


封装好之后在任意一个组件中都可以使用。如:


  <template>
    <span>{{sum}}</span> <br>
    <button @click="sum++">+1</button>
    <hr>
    <h2>当前鼠标坐标:X:{{point.x}},Y:{{point.y}}</h2>
  </template>
  <script>
  import {ref} from 'vue'
  import usePoint from '../hooks/usePoint'
  export default {
    name: 'App',
    setup(){
      let sum = ref(0);
      let point = usePoint()
      return {
        sum,
        point
      }
    },
  }
  </script>
  <style>
  </style>


  • 类似于vue2中的mixin


  • 自定义hook的优势:复用代码,让setup中的逻辑更清晰。


011.toRef和toRefs


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


用法:


toRef


<script>
import {reactive,toRef,toRefs} from 'vue'
export default {
  name: 'App',
  setup(){
    let person = reactive({
      name:'zhangsan',
      age:21,
      job:{
        j1:{
          salary:12
        }
      }
    })
    return {
      name:toRef(person,'name'),
      age:toRef(person,'age'),
      salary:toRef(person.job.j1,'salary')
    }
  }
}
</script>


toRefs


<script>
import {reactive,toRef,toRefs} from 'vue'
export default {
  name: 'App',
  setup(){
    let person = reactive({
      name:'zhangsan',
      age:21,
      job:{
        j1:{
          salary:12
        }
      }
    })
    return {
      ...toRefs(person)
    }
  }
}
</script>


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


扩展:toRefs与toRef的功能一致,但可以批量创建多个ref对象。

目录
相关文章
|
1天前
|
存储 JavaScript 开发者
Vue 3 组件通信方式总结
Vue 3 组件通信方式总结
|
1天前
|
JavaScript
在 Vue 3 组件通信方式中,Provide / Inject 与 Vuex 的区别是什么?
在 Vue 3 组件通信方式中,Provide / Inject 与 Vuex 的区别是什么?
|
1天前
|
存储 JavaScript
Vue 3 组件通信方式
Vue 3 组件通信方式
|
23小时前
|
JavaScript 前端开发 API
vue3的传送门teleport究竟有多神奇?suspense发起异步请求有多简约?
该文章介绍了Vue3中新特性Teleport和Suspense的使用方法,演示了如何使用Teleport进行DOM节点的非父子关系传送,以及Suspense在处理异步组件加载时的优雅展示和错误处理技巧。
|
1天前
|
JavaScript
particles 粒子背景插件在vue3中的使用
本文介绍了如何在Vue 3项目中使用`particles.vue3`库来创建粒子背景特效。文章提供了粒子背景插件的概述、安装步骤、配置参数说明,并展示了粒子特效的实现效果。同时,提供了在main.js中进行全局配置、在Vue组件中使用粒子背景组件的示例代码,以及完整代码的下载链接。
|
1天前
|
缓存 JavaScript 算法
卷不动也得继续学!紧跟vue3的步伐,再来get一波进阶新特性!
该文章深入讲解了Vue3的进阶新特性,包括`watchEffect`的使用、性能优化策略、Vite构建工具的优势以及全局API的变化等内容,帮助开发者更好地掌握Vue3的开发技巧。
卷不动也得继续学!紧跟vue3的步伐,再来get一波进阶新特性!
|
1天前
vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy
该文章对比了Vue2与Vue3在响应式原理上的不同,重点介绍了Vue3如何利用Proxy替代Object.defineProperty来实现更高效的数据响应机制,并探讨了这种方式带来的优势与挑战。
vue2的响应式原理学“废”了吗?继续观摩vue3响应式原理Proxy
|
23小时前
|
JavaScript 前端开发 UED
组件库实战 | 用vue3+ts实现全局Header和列表数据渲染ColumnList
该文章详细介绍了如何使用Vue3结合TypeScript来开发全局Header组件和列表数据渲染组件ColumnList,并提供了从设计到实现的完整步骤指导。
|
23小时前
|
JavaScript API
模块化妙用!用vue3实现一个鼠标追踪器和异步加载组件
该文章展示了如何使用Vue3的Composition API实现鼠标追踪器功能,并介绍了创建异步加载组件的方法,利用TS泛型增强了组件的灵活性与可维护性。
|
1天前
|
JavaScript API
卷死了!再不学vue3就没有人要你了!速来围观vue3新特性
该文章强调了学习Vue3的重要性,并详细介绍了Vue3相较于Vue2的新特性与改进,包括Composition API、响应式系统的变化以及其他API的更新等内容。