# 快速上手

在Vue3中使用所有Vue内置函数都需要引入,如refcomputedonMountedreactive

# setup

  • setup 是一个新的组件选项,(它充当在组件内部使用 Composition API 的入口点。)
  • 在 beforeCreate 之前,全局只调用一次。
  • 使用setup语法糖后所有函数都不需要return

# setup 用法

<script setup></script>

# 使用ref定义基本响应式数据

js部分

<script setup>
    import {ref} from "vue";
    let name = ref('李四')
</script>

# 使用reactive定义响应式对象

<script setup>
    import {reactive} from "vue";
    let people = reactive({
    name: '张三',
    age: '18',
    sex: '男'
})
</script>

# 计算属性

<script setup>
    import {computed} from "vue";
    //定义属性
    let computedname = reactive({
    firstname: '',
    lastname: ''
})
    //基本使用
    const fillname = computed(() => {
    return computedname.firstname + computedname.lastname
})
    //定义在对象中 不考虑值被修改的情况(不考率写的情况)
    computedname.name = computed(() => {
    return computedname.firstname + computedname.lastname
})
</script>

# 监听器的使用

# 监视ref定义的一个响应式数据

watch 接收三个参数

  1. 要监视谁
  2. 监视的回调
  3. 监视的配置

# 示例代码

import {watch} from "vue";

let count = ref(0)
let msg = ref('张三')
watch(count, (newvalue, oldvalue) => {
    console.log(`count变化了,新值是${newvalue},旧值是${oldvalue}`)
}, {
    //开启立即监视
    immediate: true,
    //开启深度监视
    deep: true
})

# 立即监视 immediate: true

开启后页面加载或页面刷新,将立即监视一次

# 开启深度监视 deep: true

开启后将对数据进行深层监视,任意孩子发生变化,函数将执行一次

# 监视ref定义的多个响应式数据

import {watch} from "vue";

let count = ref(0)
let msg = ref('张三')
watch([count, msg], (newvalue, oldvalue) => {
    console.log(`count变化了,新值是${newvalue},旧值是${oldvalue}`)
})

# 监视reactive定义的数组或对象(全部数据)

import {watch} from "vue";

let watchpeople = reactive({
    name: '王五',
    age: 50,
    job: {
        jon1: {
            money: 20
        }
    }
})
//此处无法正确获取oldvalue
//强制开启了深度监听 无法关闭
watch(watchpeople, (newvalue, oldvalue) => {
    console.log(`watchpeople变化了,旧值是`, newvalue, oldvalue)
}, {
    deep: false
}) //此处的deep配置无效

# 监视reactive定义的数组或对象中的某一个数据(需写成函数)

import {watch} from "vue";

let watchpeople = reactive({
    name: '王五',
    age: 50,
    job: {
        jon1: {
            money: 20
        }
    }
})

watch(() => watchpeople.name, (newvalue, oldvalue) => {
    console.log(`watchpeople.name变化了,新值是${newvalue},旧值是${oldvalue}`)
})

# 监视reactive定义的数组或对象中的某些数据(需写成数组函数)

import {watch} from "vue";

let watchpeople = reactive({
    name: '王五',
    age: 50,
    job: {
        jon1: {
            money: 20
        }
    }
})

watch([() => watchpeople.name, () => watchpeople.age], (newvalue, oldvalue) => {
    console.log(`watchpeople.name或age变化了,新值是${newvalue},旧值是${oldvalue}`)
})

# 监视对象中的对象(需要开启深度监听)


import {watch} from "vue";

let watchpeople = reactive({
    name: '王五',
    age: 50,
    job: {
        jon1: {
            money: 20
        }
    }
})

watch(() => watchpeople.job, (newvalue, oldvalue) => {
    console.log(`watchpeople.job变化了,新值是${newvalue},旧值是${oldvalue}`)
}, {
    deep: true //此处由于监视的是reactive中定义的某个属性所以必须开启深度监听
})

# storeToRefs()监听pinia里的数据变化

  • 在使用pinia获取数据时,ES6解构出来的数据是有问题的,已经丢失了响应式,也就是一次性的,之后对数据的修改Vue是无法监测到数据变化的。
  • 解决办法:使用Pinia为我们提供的storeToRefs()API,这就类似Vue3中的toRefs()。
  • 在使用storeToRefs()包裹的数据时需要加value,类似ref()
//导入
import {storeToRefs} from 'pinia'
//初始化
const {currentInstitution} = storeToRefs(useIntStore())
//使用
console.log(currentInstitution.value)

# 使用监听器监听pinia里的数据变化

注意

如果开启立即监听 将会在页面挂载前就监听一次,如果使用onload传递页面参数,监听器会在onload函数调用前监听一次

    //监听当前医院选择的变化
watch(currentInstitution, (newvalue, oldvalue) => {
    getlist(currentInstitution.value.id)
}, {
    immediate: true//开启立即监听
})

`

# watchEffect监听(用到谁监听谁)

  • watchEffect刚开始就会立即执行,并且会自动收集依赖,当其中的依赖项发生改变,都会执行回调函数。
  • 并且能够分别多层的对象
import {watchEffect} from "vue";

let watchpeople = reactive({
    name: '王五',
    age: 50,
    job: {
        jon1: {
            money: 20
        }
    }
})

watchEffect(() => {
    const num = watchpeople.age
    console.log('watchEffect所指定的回调函数执行了')
})

# watchEffect副作用函数

watchEffect接收一个副作用函数

watchEffect(onInvalidate => {
    console.log(`${sum.person.age} 的值变化了!`)
    onInvalidate(() => {
        console.log('清除副作用函数执行了!')
    })
})
//打印结果 
//18 的值变化了!	
//清除副作用函数执行了!
//19 的值变化了!

# onInvalidate清除副作用函数注意点

  • 该函数总是在watchEffect执行的时候再次执行
  • 当组件被销毁的时候该函数再次执行
  • 该函数总是优先于watchEffect中的同步/异步代码执行
  • Promize函数的执行应该在该函数下面
# 清除副作用函数的执行时机由flush控制
watchEffect(onInvalidate => {
    console.log(`${sum.person.age} 的值变化了!`)
    onInvalidate(() => {
        console.log('清除函数执行了!')
    })
}, {
    //'pre' 在组件更新更新前运行,默认为'pre'
    //'post'在组件更新更新后运行
    //'sync'强制效果始终同步触发。然而,这是低效的,应该很少需要。
    flush: 'post'
})
//打印结果 
//18 的值变化了!
//清除函数执行了!
// 19 的值变化了!

# watchEffect停止监听

watchEffect选项中返回的函数是停止监听函数。

import {watchEffect} from "vue";

let watchpeople = reactive({
    name: '王五',
    age: 50,
    job: {
        jon1: {
            money: 20
        }
    }
})

const cancel = watchEffect(() => {
    const num = watchpeople.age
    console.log('watchEffect所指定的回调函数执行了')
    if (age >= 50) cancel()
})

# watchEffect侦听器调试

watchEffect(() => {
    console.log(`${sum.person.age} 的值变化了!`)
}, {
    onTrack(e) { //追踪其依赖的时候触发,只能在开发者模式下使用
        console.log(e.target)
    },
    onTrigger(e) {  //依赖项被改变的时候触发,只能在开发者模式下使用
        console.log(e.target)
    }
})

# 其他类型的watchEffect

  • watchPostEffect 带有 flush: ‘post’ 选项。
  • watchSyncEffect 带有 flush: ‘sync’ 选项。

# 生命周期的使用

import {shallowReactive, onMounted} from "vue";

let list = shallowReactive({
    arr: []
})

onMounted(() => {
    list.arr = [{
        id: 0,
        name: '张三'
    },
        {
            id: 1,
            name: '李四'
        },
        {
            id: 2,
            name: '王五'
        }
    ]
})

# hooks的使用 与mixin 同理

vue3里面可以自定义hook 主要是用来存储一些复用的逻辑、变量的封装。相当于vue2里面的minins

# 既然vue2有minins为什么vue3提出了Hook?

minins缺点:

  • 组件的data、methods、filters会覆盖mixins里的同名data、methods、filters。
  • 变量不好找,可读性不好,维护起来比较复杂 不同于mixin, hook是函数,这样就可以帮助我们提高代码的复用性, 让我们能在不同的组件中都利用 hooks 函数

# 定义hook(建议新建hooks文件夹)

export default () => {
    let point = reactive({
        pagex: 0,
        pagey: 0
    })
    //获取鼠标位置的处理函数
    const getpoint = (event) => {
        point.pagex = event.pageX
        point.pagey = event.pageY
    }
    //页面挂载时为win对象添加点击事件
    onMounted(() => {
        window.addEventListener('click', getpoint)
    })
    //页面卸载时移除点击事件
    onBeforeUnmount(() => {
        window.removeEventListener('click', getpoint)
    })
    return point
}

# hook的使用


<template>
    <view class="title">动态获取鼠标位置</view>
    <span>x:{{point.pagex}}</span>
    <hr>
    <span>y:{{point.pagey}}</span>
</template>
<script setup>
    //引入
    import Getpoint from '../../hooks/point.js'
    //定义
    const point = Getpoint()
</script>

# 组件中v-model的实现

  • 实现v-model组件中需要两个数据
    1. props
    2. emits

注意

  • props和emits命名名称必须相同
  • emits传入的函数声明必须使用 update前缀

<template>
  <view>
    <template
        v-for="(item, index) in props.data"
        :key="index">
      <view

          @click="change(item)">
        {{ item.name }}
      </view
      >
    </template>
  </view>
</template>
<script setup>
  import {defineProps} from 'vue'

  const props = defineProps({
    data: [],
    value: {}//emits中使用 update:value
  })
  const emits = defineEmits(['update:value'])
  const change = (item) => emits('update:value', item)
</script>

# 父组件使用


<template>
  <TextModelValue
      v-model:value="currentValue"
      :data="dataList"/>
</template>
上次更新: 2/27/2024, 10:41:46 AM