Vue3 学习

1 创建vue3项目(首先要确保@vue/cli版本在4.5.0以上)

vue --version     ## 检查版本

vue install -g @vue/cli  ## 全局安装vue脚手架

vue create vue_test (项目名)  ## 创建项目

2 相较于vue2的变化

  1. 不再引入Vue构造函数,而是引入一个叫做createApp的工厂函数

  2. template中不再需要根标签

3 SetUp

  1. setup的执行时机:在beforeCreate之前执行一次,this是undefined
  2. setup的参数:
  • props:值为对象,包括组件外部传递过来,且组件内部声明接受了的属性
  • context:上下文对象 - attrs 相当于 this.$attrs,props中没有接受的属性都会放到attrs中

                                         - slots 收到的插槽内容,相当于this.$slots

                                         - emit 相当于 this.$emit

4 ref函数(类似react中的UseState)

直接在setup中定义的数据不能响应式的改变,我们需要将数据交给ref

  • 作用: 定义一个相应式的数据
  • 语法: const xxx = ref(initValue)
  • js中操作数据 xxx.value
  • 响应式依靠Object.defineProperty()中的get和set完成

5 reactive函数

  • 作用:类似于ref作用是定义一个对象类型的响应式数据类型
  • 语法: const xxx = reactive(源对象)
  • 可以处理深层对象数据
  • 相应式基于ES6的Proxy实现,通过代理队形操作源对象内部数据进行操作。

!! 有一点需要注意,reactive定义的数组和对象直接赋值[],和{}是没有作用的,数组将length设为0,对象暂时没有什么好办法,循环delete所有项是可以或者用ref定义也可以删

6 computed函数

与vue2中的computed功能一致,并且可以在vue3中继续使用computed配置项,但是不推荐使用。

let fullName = computed(() => {
    return persion.firstName + '-' + persion.lastName
})

7 watch函数

有三个参数,

  • 第一个参数代表要监控的值
  • 第二个参数是回调值变化之后调用的回调函数,回调函数也有两个参数第一个是新值,第二个是旧值
  • 第三个参数是watch的配置项
  1. 监控的是一个ref定义的数据时
    watch(num,(newValue, oldValue)=>{
          console.log(newValue, oldValue)
        })
  2. 监控多个ref定义的数据时,将第一个参数写为一个数组
    watch([num1, num2],(newValue, oldValue)=>{
          console.log(newValue, oldValue)
        })

    回调函数的参数得到的值也是一个数组

  3. 监控reactive定义的数据时
    watch(persion, (newValue, oldValue) => {
          console.log(newValue, oldValue)
        })
    // 监控的是reactive定义的数据时,oldvalue无法正常获取,
    // 并且强制开启深度监控,即deep配置失效
    watch(() => persion.firstName, (newValue, oldValue) => {
          console.log(newValue, oldValue)
        })
    // 监控reactive定义的数据的某个属性时,可以正常获取oldValue,但是参数要写成函数的形式

8 watchEffect函数

类似watch,但是不需要知名监控的属性,也不需要指定监控的回调,代码中含有的属性变化时就执行回调,有点像computed,但时watch注重的时过程不需要写返回值。

watchEffect(() => {
      console.log(num.value)
    })

9 生命周期钩子

beforeCreate ===> setup()

created          ===> setup()

beforeMount  ===> onBeforeMount

mounted        ===> onMounted

beforeUpdate ===> onBeforeUpdate

updated          ===> onUpdated

beforeUnmount==> onBeforeUnmont   // 原beforeDestroy

unmounted     ===> onUnmounted       // 原destroyed

10 自定义hooks函数

类似于vue2中的mixin,将setup中的代码封装起来,之后其他的文件调用这些代码时,使用自定义hooks。

11 toRef

  • 作用: 创建一个ref对象,其value值指向另一个对象中的某个属性
  • 语法: const name = toRef(person, 'name')
  • 应用:将响应式的对象单独提供给外部使用
    setup () {
        let person = reactive({
            firstName: '张',
            lastName: '三'
        })
        return {  // 如果想要使用person中的数据通常需要把person返回出去
            firstName: toRef(person, 'firstName') // 使用toRef可以直接返回内部的数据
        }
    }

12 shallowReactive 与 shallowRef

  • shallowReactive: 只处理对象最外层属性的相应式(浅响应式)
  • shallowRef:只处理基本数据类型的响应式,不仅行对象的响应式的处理

13 readonly 与 shallowReadonly

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

14 toRaw 与 markRaw

  • toRaw: 将reactive生成的响应式的的对象转为普通对象
  • markRaw: 标记一个对象时其用于不会再成为相应式的对象(提高性能和复杂第三方库使用)

15 customRef

创建一个自定义的ref,并对其以来项跟踪和更新触发进行显式控制(不懂。。。)

16 provide 与 inject

实现祖孙组件间的通信

  • 祖先组件通过provide传递数据,子孙组件通过inject接收数据
// 祖先组件

setup () {
    provide('msg', 100)
    ...
}
// 子孙组件
setup () {
    const msg = inject('msg')
    return {
        msg
    }
}
  • 子孙组件向祖先组件传值
// 祖先组件
setup () {
    const handleMsg = (value) => {
        console.log('孙子传递的数据', value)
    }
    provide('handleMsg', handleMsg)
    ...
}
// 子孙组件传值
setup () {
    const handleMsg = inject('handleMsg')
    const Fn = () => {
        handleMsg(100)
    } 
}

17 响应式判断

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

18 Teleport

能将html结构移动到指定位置,使用to属性指定


1 setup script

vue的语法糖

通常我们使用composition API的时候需要使用 setup 钩子,然后还要把页面上要使用的变量return返回出去,例如:

<template>
  <div>{{name}}{{age}}{{persion}}</div>
  <button @click="sayHello">说话</button>
  <div>computed: {{ persion.fullName }}</div>
  <div>{{ num }}</div>
  <button @click="add">加1</button>
  <div>{{ num2 }}</div>
  <button @click="change">添-</button>
</template>

<script>
import { ref, reactive, computed } from 'vue'
export default {
  name: 'HelloWorld',
  setup() {
    let name = ref('lyk')
    let age = ref(18)
    let num = ref(1)
    let num2 = ref(2)
    let persion = reactive({
      firstName: '张',
      lastName: '三'
    })
    persion.fullName = computed(() => {
      return persion.firstName + '-' + persion.lastName
    })
    function sayHello() {
      alert(`我叫${name.value},我${age.value}岁了,
      ${persion.firstName}---${persion.lastName}`)
    }
    function add() {
      num.value++
      num2.value++
    }
    function change() {
      persion.firstName += '-'
      persion.lastName += '+'
    }
    return {
      name,
      age,
      persion,
      sayHello,
      num,
      num2,
      add,
      change
    }
  }
}
</script>

<style scoped>
</style>

使用起来很麻烦。

<template>
  <div>{{name}}{{age}}{{persion}}</div>
  <button @click="sayHello">说话</button>
  <div>computed: {{ persion.fullName }}</div>
  <div>{{ num }}</div>
  <button @click="add">加1</button>
  <div>{{ num2 }}</div>
  <button @click="change">添-</button>
</template>

<script setup>
import { ref, reactive, computed } from 'vue'
const name = ref('lyk')
const age = ref(18)
const num = ref(1)
const num2 = ref(2)
const persion = reactive({
  firstName: '张',
  lastName: '三'
})
persion.fullName = computed(() => {
  return persion.firstName + '-' + persion.lastName
})
const sayHello = () => {
  alert(`我叫${name.value},我${age.value}岁了,
  ${persion.firstName}---${persion.lastName}`)
}
const add = () => {
  num.value++
  num2.value++
}
const change = () => {
  persion.firstName += '-'
  persion.lastName += '+'
}
</script>

<style scoped>
</style>

这样就简单很多了。

现在来详细的说一下优点

  1. 组件不需要在components里注册,引入之后直接在页面上使用即可
  2. 属性方法不需要人return返回
  3. 新增了defineProps、defineEmit和useContext,但是useContext后来又被弃用了,用useSlots和useAttrs来代替,总共四个新的api,顾名思义defineProps充当props接受父组件的参数,defineEmit充当$emit自定义事件来给父组件传参,useSlots用于获取插槽数据,useAttrs可以获取到attrs的数据
    // 首先是defineProps,父组件跟vue2完全没区别
    // 子组件:
    import { defineProps } from 'vue'
    const props = defineProps({
        xxx: {
            type: xxx,
            required: true/false
        }
    })
    // 然后是defineEmits 父组件同样没区别
    // 子组件:
    import { defineEmits } from 'vue'
    const emit = defineEmits('fn') // 先定义一个事件
    const click = () => {
        emit('fn', '参数') // 然后触发这个事件
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值