vue3学习(1)vite、创建vue3项目的两种方式、vue2响应式和vue3响应式的区别、computed、watch、wacthEffect、生命、hooks函数、toRef

vite

vite是新一代前端构建工具。

优势:

  • 开发环境中,无需打包操作,可快速的冷启动
  • 轻量快速的热重载(HMR)
  • 真正的按需编译,不再等待整个应用编译完成
    传统构建工具:
    在这里插入图片描述
    vite:
    在这里插入图片描述

创建vue3项目的两种方式

vue-cli

vue-cli需要达到4.5.1以上版本。以下为创建步骤:
1:vue create 项目名
2:选择vue3
3:cd 项目文件夹
4:npm run serve

vite

1:npm init vite-app 项目名
2:cd 项目文件夹
3:npm run dev

初始化工程

main.js

引入了createApp这个工厂函数

App.vue

可以不用一个根标签div

Composition API

setup

  • vue3中的一个新的配置项,值为一个函数。
  • setup是所有Composition API“表演的舞台”
  • 组件中所有的数据、方法等等都要配置在setup中。
  • 如果setup返回的是一个对象,那么返回的对象的属性、方法可在模板中直接使用;如果返回的是一个渲染函数可以自定义渲染内容。
<template>
  <h1>{{name}}</h1>
  <button @click="sayHi">点击</button>
</template>

<script>
export default {
  name: 'HelloWorld',
  setup(){
    let name = '小李'
    function sayHi(){
      alert(`哈喽,我叫${name}`)
    }
    return {
      name,
      sayHi
    }
  }
}
</script>

vue2的配置项可以拿到vue3的setup内的数据和方法,但是vue3的setup不能拿到vue2的数据和方法,如果两者重名vue3优先,所以不建议混合使用。

  • setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return都对象中的属性。

setup的注意点

  • setup的执行时期:是在beforeCreate之前执行一次,this是undefined。
  • setup的参数:1、props,即父组件传给子组件的数据,可以在setup里面拿到。2、context,即上下文对象,其中包含attrs(父组件通过props传的数据)、 emit(自定义事件对象)、 slots(插槽,命名建议使用v-slot:name)。

ref

让数据变成响应式数据,需要将数据用ref()包裹,让数据变成引用实现对象,这里利用的是get、set实现,所以在更改数据的值时需要利用.value。注意,ref需要引入进来才能使用。

<template>
  <h2>{{age}}</h2>
  <button @click="changeAge">长大</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'HelloWorld',
  setup(){
    let age = ref(1)
    function changeAge(){
      age.value += 1
    }
    return {
      age,
      changeAge
    }
  }
}
</script>

如果.value的值还是一个对象,他使用的是proxy来处理。

<template>
  <h2>{{job.type}}</h2>
  <h2>{{job.money}}</h2>
  <button @click="changeWork">改变</button>
</template>

<script>
import {ref} from 'vue'
export default {
  name: 'HelloWorld',
  setup(){
    let job = ref({
      type:'前端',
      money:'30K'
    })
    function changeWork(){
      job.value.type = 'ui'
    }
    return {
      job,
      changeWork
    }
  }
}
</script>

reactive

将对象类型转换响应式数据,其他基本数据类型仍然使用ref,它接收了该对象之后返回的是一个proxy代理对象,通过代理对象操作源对象内部数据进行操作,并且reactive定义的响应式数据是深层次的。

<template>
  <h2>{{job2.type}}</h2>
  <h2>{{job2.money}}</h2>
  <button @click="changeWork2">改变2</button>
</template>

<script>
import {reactive} from 'vue'
export default {
  name: 'HelloWorld',
  setup(){
    let job2 = reactive({
      type:'前端',
      money:'30K'
    })
    function changeWork2(){
      job2.type = 'ui'
    }
    return {
      job2,
      changeWork2
    }
  }
}
</script>

vue2响应式和vue3响应式的区别

vue2

实现原理:

  • 对象类型: 通过 object.defineProperty() 对属性的读取、修改进行拦截(数据劫持)
  • 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包惠)

存在问题:

  • 新增属性或是删除属性界面不会更新(利用$set 或 $delete来新增或删除)
  • 直接根据下标修改页面不会更新(利用数组的方法进行修改)
vue3

解决了以上vue2存在的两个问题,可以直接新增、删除、下标修改。
实现原理:
将接收到的对象返回成一个代理对象,再使用代理对象中的get 和 set进行对数据读取、修改、新增的捕获。实现删除的利用的是deleteProperty对对象的某一属性进行删除。

Reflect

在windows中的对象Reflect也可以获取并且对其进行修改属性等操作。Object中进行对对象的某些操作时,如果存在错误操作时,代码会停止运行,但是如果是在Reflect中操作时会返回true或false,而不让整个代码停止运行。在vue3中的修改、添加等操作就是在Reflect中使用。

computed

在vue2中作为一个配置项,在vue3中是一个函数,

//简写
    person.all = computed(()=>{
      return person.job.j1.money
    })
//完整
    person.all = computed({
      get(){
        return person.job.j1.money
      },
      set(value){
        return value
      }
    })

watch

在vue2中,watch是作为一个配置项,使用方法如下:

  watch:{
    sum:{
      immediate:true,
      deep:true,
      handler(newVal,oldVal){
        console.log('sum的值发生改变了',newVal,oldVal)
      }
    }
  },

但在vue3中,它被作为一个组合式api来使用,所以在vue3中可以多次调用watch这个函数,这个函数的参数分别是,监视的值、执行的函数、其他配置项。
仅监视一个ref定义的值:

  watch:{
    sum:{
      immediate:true,
      deep:true,
      handler(newVal,oldVal){
        console.log('sum的值发生改变了',newVal,oldVal)
      }
    }
  },

当监视的是多个ref定义的数据时,使用数组存放数据,并且newValue和oldValue也是数组存放对应的数据:

    let sum = ref(0)
    let sum2 = ref(1)
    watch([sum,sum2],(newVal,oldVal)=>{
      console.log(newVal,oldVal)
    },{immediate:true})//[1, 1] [0, 1]

当监视的是reactive定义的一个响应式数据时的区别:

  • 目前有的版本oldValue拿不到;
  • 并且使用reactive定义的数据无论有多少层都强制开启了深度测试,deep:fasle无效;
  • 如果想要监视的是对象中的某一个属性时,需要写成函数将该属性返回,此时可以拿到oldValue;
  • 如果想要监视的是对象中的某一些属性时,需要返回的属性放在一个数组中。
  • 如果监视的是对象的一个属性,deep:true有效,当监视的是一个对象中的对象,更改的是对象中对象的某一个属性时,需要开启深度监听。
  • 当监听ref所定义的对象时,需要监听的是对象的value,该value就是借助reactive所定义的对象,或者是可以加上深度监视。
    let person = reactive({
      age:12,
      sex:'女'
    })
    watch(person,(newVal,oldVal)=>{
      console.log(newVal,oldVal)
    })
        watch(()=>person.age,(newVal,oldVal)=>{
      console.log(newVal,oldVal)
    })
    watch([()=>person.age,()=>person.sex],(newVal,oldVal)=>{
      console.log(newVal,oldVal)
    })
    watch(()=>person.job,(newVal,oldVal)=>{
      console.log(newVal,oldVal)
    },{deep:true})

wacthEffect

wacthEffect进行监视时,不需要指明监视的属性,监视的回调中用到哪个属性就监视哪些属性。
wacthEffect与computed相似,但是computed注重的是返回的值,即computed所依赖的值变了,所返回的值也变了。wacthEffect更注重的是过程,只要用到的值改变了,监视的回调函数就重新执行,不需要写返回值。

    watchEffect(()=>{
      let x1 = person.job.j1.money
      console.log('有属性发生改变',x1)
    })

生命周期函数

在vue3中可以以配置项的形式写也可以以组合式API的形式写,必须在使用之前引入,并且在使用组合式API这种方式时,setup都相当于beforeCreate以及create,所以beforeCreate以及create没办法以这种方式写。

    onMounted(()=>{
      console.log('----onMounted---')
    })

同时使用时,除了setup、beforeCreate以及create,组合式API的比配置项的快一点,但是建议不要同时使用。

hooks函数

当写了一个功能的方法,其中包含数据、方法等内容,为了可以让多个组件可以使用这个方法,就可以在src文件夹内新建一个hooks文件夹,再在里面新建js文件,将跟功能相关的数据、方法等放入js文件夹的一个函数中,再将有用的数据return出来,如果想要在其他地方使用这个功能,就可以直接引入即可。

toRef

对于一个对象,使用p.name拿一个对象中的属性时,该属性的内容不是响应式的,但是当使用toRef去设置这个属性值时,所拿到的属性就会是响应式的。它有两个参数,第一个参数是一个对象,第二个参数是对象中的某一属性。
toRef只能处理一个属性,但是toRefs可以批量处理一个对象里的所有属性,无需指定属性,返回的将是该对象中的所有属性。

money:toRef(person.job.j1,'money')
...toRefs(person)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小婵婵不怕鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值