Vue3组合式API(基础语法介绍)

setup概述

        setup() 接受 props 和 context 作为参数,主要用于设置组件的响应式数据、方法和计算属性等,它返回一个对象,这个对象包含了需要暴露给模板的属性。  

  • props,它是响应式的,当传入新的 prop 时,它将被更新。
  • context 是一个普通的 JavaScript 对象,它是一个上下文对象,暴露了其它可能在 setup 中有用的值。
  • setup() 函数在组件创建 created() 之前执行      
<script setup>
import { ref } from 'vue'
const sum = ref(1)
</script>

<template>
  <div>
    <h1>v3</h1>
    <h3>{{ sum }}</h3>
    <button @click="sum++">+1</button>
  </div>
</template>

 拓展:安装setup语法简写插件 语法糖

npm i vite-plugin-vue-setup-extend -D

然后在vite.config.ts中引入它

import VueSetupExtend from 'vite-plugin-vue-setup-extend'

最后添加一句调用,写完dev重启即可使用


ref () :声明响应式状态

        作用:定义响应式变量

        语法:let xxx=ref(初始值)

ref 接受一个值,返回一个响应式对象,一般用来处理简单数据类型的响应式,但如果传入的值是对象 ref 会求助 reactive,返回RefImpl的实例简称ref对象。

但若要在方法中修改ref创建的响应式数据,的写法是: state.value = xxx

  • JS中操作数据需要:xxx.value,但模板中不需要.value,直接使用即可
  • 对于let name=ref('张三') 来说,name不是响应式的,name.value是响应式的

ref 创建响应式对象

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  {{ count }}
  <button @click="count++">Count</button>
</template>

应用案例:

<template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">年龄+1</button>
    <button @click="showTel">点我查看联系方式</button>
  </div>
</template>

<script setup lang="ts" name="Person">
import { ref } from 'vue'

// 创建响应式数据
let name = ref('张三')
let age = ref(18)
// 非响应式 静态
let tel = '13888888888'
let address = '北京昌平区宏福苑·宏福科技园'

// 修改名字
function changeName() {
  name.value = 'zhang-san'
  console.log(name.value)
}

// 修改年龄
function changeAge() {
  age.value += 1
  console.log(age.value)
}

// 查看电话号码
function showTel() {
  console.log(tel)
}
</script>

reactive 创建基本类型的响应式函数

<script lang="ts" setup name="Person">
import {reactive} from 'vue'
//数据
let car = reactive({brand:'汽车',price:100})
let games=[
    {id:'a1',name:'王者'},
    {id:'a1',name:'原神'},
    {id:'a1',name:'三国'}
]

ref与reactive区别

ref创建的变量必须使用 .value(可使用volar插件自动添加.value)

car.value={brand:'宝马',price:1}

reactive有局限性,重新分配一个新对象时会失去响应式变成普通对象

function changeCar(){
//下面这个写法页面可以更新
Object.asssign(car,{brand:'宝马',price:1})
}

使用原则:

1.若需要一个基本类型的响应式数据,必须使用 ref
2.若需要一个响应式对象,层级不深,ref、 reactive 都可以
3.若需要一个响应式对象,且层级较深,推荐使用 reactive

toRefs与toRef

作用:将一个响应式对象中的每一个属性,转换为ref(响应式)对象。

           toRefs与toRef功能一致,但toRefs可以批量转换。


Computed计算属性

  • 只读的写法 :computed(() => xxxxxx)

  • 可读可写的写法: computed({ get: () => xxxx, set: (val) => { xxxx } })

计算属性只要数据发生变化就会重新计算

<template>
    <div class="person">
    //双向绑定v-model,单向绑定v-bind:value或:value
        姓:<input type="text" v-model="firstName"> <br>
        名:<input type="text" v-model="lastName"> <br>
        全名:<span>{{fullName}}</span> <br>    
    </div>
</template>

<script lang="ts" setup name="Person">
   import {ref,computed} from 'vue'

   let firstName = ref( 'zhang')
   let lastName = ref( 'san ')
// 这么定义的fullName是一个计算属性,可读可写
   let fullName = computed({
    get(){
        return firstName.value.slice(0,1).toUpperCase()+firstName.value.slice(1) + '-' + lastName.value
},
    set(val){
        const [str1,str2] = val.split('_')
        firstName.value = str1
        lastName.value = str2
    }
})
</script>

import {computed} from 'vue'
 
setup(){
    ...
	//计算属性——简写
    let fullName = computed(()=>{
        return person.firstName + '-' + person.lastName
    })
    //计算属性——完整
    let fullName = computed({
        get(){
            return person.firstName + '-' + person.lastName
        },
        set(value){
            const nameArr = value.split('-')
            person.firstName = nameArr[0]
            person.lastName = nameArr[1]
        }
    })
}

Vue2和3计算属性写法的区别:

不过上面3计算写法是只读的,不能修改,若修改可通过 gettersetter 来创建:


watch监听

  1. ref 定义的数据
  2. reactive 定义的数据
  3. 函数返回一个值(getter函数)
  4. 一个包含上述内容的数组

情况1:监视ref 定义的基本类型数据

(注:在监视ref数据的时候不写value,如上图sum(回调函数)后面不加value,建议安装volar插件自动添加。后面的"oldvalue"可省略,括号里可只写一个value)

如何解除监听(比如加个条件sum>10时解除监视):

        watch调用是有一个返回值的,我们可以在watch()前加变量接收它,然后添加方法来停止监视

情况2:监视ref 定义的对象类型数据

  1. 直接写数据名,监视的是对象的地址值
  2. 监视对象内部数据手动开启深度监视
  • 若修改的是ref 定义的对象中的属性,newValue oldValue是同一个对象,都是新值
  • 若修改的是ref 定义的对象,newValue是新值oldValu旧值,不是同一个对象了
<template>
    <div class="person">
        <h1>情况二:监视[ref] 定义的[对象类型]数据</h1>
        <h2>姓名: {{ person.name }}</h2>
        <h2>年龄: {{ person.age }}</h2>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="changePerson">修改整个人</button>
    </div>
</template>

<script lang="ts" setup name="Person">
    import { ref, watch } from 'vue'
    
    //数据
    let person = ref({
        name: '张三',
        age: 18
    })
    
    //方法
    function changeName() {
        person.value.name += '~'
    }
    function changeAge() {
        person.value.age += 1
    }
    function changePerson() {
        person.value = { name: '李四', age: 90 }
    }
    //深度监视
    watch(person, (newValue, oldValue) => {
        console.log('person变化了', newValue, oldValue)
    }, { deep: true })
</script>
watch(参数一:被监视的数据,......{

        ...... 参数二:监视的回调......

},{ 参数三:配置对象 deep监视深度为真/假,immediate是否立即监听 等... })
  • immediate是否开启立即监听,deep是否开启深度监听
  • flush回调的触发时机,onTrack / onTrigger用于调试的两个函数

情况3:监视reactive定义的对象类型数据 (且默认开启深度监视)

深度监听只能监听对象且无法关闭

ref和reactive区别

情况四:监视ref或reactive定义的对象类型数据中的某个属性

监视对象中的某个属性用函数式,监视对象是地址值 需手动开启深度监视

        1.若该属性值不是【对象类型】,需要写成函数形式

        2.若该属性值是依然是【对象类型】,可直接编,也可写成函数,不过建议写成函数

deep监视的是地址值,对象类型默认是地址值;

若要在地址值的基础上像关注细枝末节开启deep深度即可

情况五:监视上述的多个数据

watch监视的数据像数组一样 ‘数组’中写的类型分需求情况,newValue是这个数组的整体

watchEffect

立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。

  • 不需要手动传入依赖(不用指定监听对象)
  • 无法获取原始值,只能获取更新后的值
  • 立即执行(在onMounted前调用)
  • 一些异步操作放里面更加的合适

watch与watchEffect主要区别是追踪响应式依赖的方式:

  1. watch 需要明确指定要监视的数据源,而 watchEffect 则自动收集其使用的响应式数据,代码更简洁。
  2. watch 的回调函数可以获得旧值和新值的参数,而 watchEffect 的回调函数无法直接获取旧值和新值的参数。
  3. 当监听对象或数组时,watch 需要开启 deep 选项才能深度监听属性或元素的变化,而 watchEffect 会自动追踪响应式数据的依赖,并在赋值、方法调用等操作后重新执行回调函数。
import { watch, reactive } from 'vue';

const person = reactive({
  name: '张三',
  age: 18,
});

//使用watch实现
watch(
  () => person.age, // 监听 age 属性
  (newValue, oldValue) => {
    console.log(`age 从 ${oldValue} 变成了 ${newValue}`);
  }
);
//使用watchEffect实现
watchEffect(() => {
  console.log(`age 变成了 ${person.age}`);
});

可以看到,watch 需要明确指定要监听的数据源,而 watchEffect 则可以自动追踪响应式数据。并且,watch 的回调函数可以获得旧值和新值的参数,而 watchEffect 的回调函数则需要手动获取旧值和新值。


标签的ref属性

Vue3中ref 函数来创建一个响应式的引用,并将其分配给模板中的标签的 ref 属性。这样就可以通过引用来访问和操作对应的组件或元素。它允许我们在一个特定的 DOM 元素或子组件实例被挂载后,获得对它的直接引用。

注:使用 ref 创建的引用在访问其值时需要使用 .value

访问模板引用

为了通过组合式 API 获得该模板引用,我们需要声明一个同名的 ref:

<script setup>
import { ref, onMounted } from 'vue'

// 声明一个 ref 来存放该元素的引用
// 必须和模板里的 ref 同名
const input = ref(null)

onMounted(() => {
  input.value.focus()
})
</script>

<template>
  <input ref="input" />
</template>

如果不使用 <script setup>,需确保从 setup() 返回 ref:

export default {
  setup() {
    const input = ref(null)
    // ...
    return {
      input
    }
  }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值