Vue3笔记_<入门基础篇>

本文详细介绍了Vue3的Setup语法糖、ref、reactive、toRef、toRefs、计算属性、watchEffect函数、生命周期、获取DOM、Props以及自定义事件等核心概念。setup函数在初始化时执行一次,ref和reactive分别用于创建响应式数据,计算属性和watchEffect处理数据变化,Props和自定义事件则涉及到组件间的数据传递。
摘要由CSDN通过智能技术生成

目录

Setup语法糖

ref:定义一个数据的响应式

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

toRef()

toRefs()

计算属性

watchEffect函数

生命周期

Vue3获取Dom

Props

Vue3 自定义事件


Setup语法糖

setup是一个专门用于组合式API的特殊钩子函数,只在初始化时执行一次。

setup有两种返回值:

  1. 对象。 对象中的属性,方法在模板中都可以直接使用
  2. 函数。 自定义渲染内容,覆盖模板内容

 注:不要与Vue2配置混用

  • Vue2配置中:{data,methods,computer}中可以直接访问setup中的属性和方法
  • 在setup中不能访问Vue2的配置 { data , methods , compoter... }
  • 如果变量或函数出现重名,setup内的数据优先

注意

  • 在setup语法糖里面,this指向是undefined,this.任何变量都无法获取值。setup是一个独立的封装函数
  • steup简写语法里面,不需要自己写async,当出现await时会自动在setup内部出现,但是带有async setup()的组件必须嵌套在<suspense>中才能呈现。

 setup的细节

  1. setup(props,context) || setup(props,{attrs,slots,emit})
  2. props:值为对象,包含组件外部传递过来的,且组件内部声明接收了的属性。父给子传了参数,子没有接收就会报错。父没有传参数,子接收了就是undefined
  3. context:上下文对象,里面是三个值分别如下👇
  4. attrs:值为对象,包含组件外部传递过来的,但没有在props配置中声明的属性,相当于 this.$attrs。attrs就像vue2的$attrs是个捡漏的,传过来的参数没有被props接收,都会到attrs里面去
  5. emit:用来分发自定义事件的函数,相当于 this.$emit。用来触发父元素传给子元素的事件
  6. slots:收到的插槽内容,相当于 this.$slots

setup不能是一个async函数。一个函数如果被async修饰了,那么返回的就不再是一个普通对象,而是被promise包裹的对象,模板中看不到return对象中的属性


ref:定义一个数据的响应式

语法:
import ref from 'Vue'
const xxx = ref(initValue); RefImpl 引用的实现的实例对象

 说明

  • JS中操作数据:xxx.value
  • 模板中操作数据:不需要.value,因为浏览器解析的时候已经把value给解析了
  • 用ref包括的基本类型数据是RefImpl的实例对象

 注意

  • 在vue3中,想把普通的number,string,bollean编程响应式的数据,就必须要借助ref
  • ref定义对象类型的数据,底层原理是利用了ES6的proxy实现的响应式,而在vue3中,对proxy的操作封装在了一个叫reactive的新函数中。
  • Vue3中ref响应式仍然是通过 Object.defineProperty()的getter和settrer拦截来实现 .value

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

语法:
import { reactive } from 'vue'
const proxyObj = reative(obj);
接收一个普通对象或数组,然后返回一个响应式代理对象

说明

  • 定义的响应式数据是深层的:会影响对象内部所有嵌套的属性(递归深度响应式)
  • reactive响应式底层原理是基于ES6的proxy实现
  • reactive只能处理对象或数组,处理其他类型数据会报错

reactive与ref的区别

  1. ref:定义基本类型数据响应式,得到的是:RefImpl的实例,引用对象.value
  2. reactive:定义复杂类型响应式数据,得到的是Proxy的实例,代理对象:变量名.属性名(下标)即可
  3. ref处理对象或数组的时候,内部借助了reactive函数来实现响应

  4. reactive只能处理对象或数组,处理其他类型数据会报错

  5. reactive核心是对ES6的proxy进行了封装


toRef()

toRef是函数:转换响应式对象中某个属性为单独响应式数据,并且跟原来的数据的值是关联的

语法:
import toRef from 'vue'
第一个值是响应式对象,第二个值是在obj下需要独立出来的数据的属性名
let name = toRef(obj,'name')
独立出来的数据跟原来的对象是保持联系的,name发生了改变,obj里的name也会发生改变
toRef独立出来的数据类型是refImpl。改变数据的方法:name.value = '老铁'

toRefs()

toRefs是函数,转换响应式对象中所有属性为单独响应式数据,对象转为普通对象,并且值是关联的

<script>
import { ref, reactive,toRef,toRefs} from 'vue'
export default {
    setup() {
        let sub = {
            name: '张三',
            age: 18,
            english: 80,
            number: 20,
            a: {
                b: {
                    c: 1
                }
            },
            aobby: ['🦈', '🐋', '🐡']
        }
        let obj = reactive(sub)
        let reactiveObj=toRefs(obj)
        function sayHi() {
            obj.name = '李四'
            obj.age = 99
            console.log(sub.name);
            console.log(sub.name) //独立出来的属性改变时,对象内的属性也会发送改变
        }
        return { ...reactiveObj , sayHi }
    }
}
</script>

<template>
    <div>
        <div>{{ name }}</div> 
        <p>age:{{ age }}</p>
        <p> english :{{ english }} </p>
        <p> number :{{ number }} </p>
        <p> 测试 C :{{ a.b.c }} </p>
        <p> 海洋世界 :{{ aobby }} </p>
        <button @click="sayHi">hello</button>
    </div>
</template>

计算属性

Vue3的计算属性完全可以提取到单独的文件里去处理,处理完再引入

原理

<template>
    <div>
        <h2>vue3的特殊计算属性</h2>
        姓:<input type="text" v-model="user.firestName"><br>
        名:<input type="text" v-model="user.lastNamt"><br>
        计算属性:<input type="text" v-model="user.computed"><br>
    </div>
</template>
<script setup>
import { reactive,computed } from 'vue';
let user = reactive({
    firestName:"易烊",
    lastNamt:"千玺"
})
user.computed = computed({  
    //获取值时返回get里的方法,改变值时调用set的方法
    get(){
        return user.firestName+"——"+user.lastNamt
    },
    set(val){
        const arr = val.split('——')
        console.log(arr)
        user.firestName=arr[0]
        user.lastNamt=arr[1]
    }
})
</script>

使用与封装

在utils文件夹下
import { computed } from 'vue'
export function TextComputed(val){
    const str = computed(()=>{
        return val.split('').reverse().join('')
    })
    return str
}
<template>
    <div>
        <h2>Vue3</h2>
        <p>msg:{{ str }}</p>
        <p>翻转:{{ reverse }}</p>
        <p>翻转:{{ conment }}</p>
    </div>
</template>
<script setup>
import { ref,computed ,reactive } from 'vue'
    let str = ref('hello i am vue3')
    // const reverse = computed(()=>{
    //     return str.value.split('').reverse().join('')
    // })
import { TextComputed } from '../utils/computed'
    const reverse = TextComputed(str.value)
    let cmt = ref('hellotodo')
    // const conment = computed(()=>{
    //     return cmt.split('').reverse().join('')
    // })
    const conment = TextComputed(cmt.value)
</script>

watchEffect函数

watch的作用:即要指明监听的属性,也要指明监视的回调

watchEffect的作用:

  1. 不用指明监视哪个属性,监视的回调中用到哪个属性,就监视哪个属性
  2. 默认初始时就会执行第一次,从而可以收集需要监视的数据

类似计算属性

  1. 计算属性需要返回值
  2. watchEffect,没有返回值,是监视到变化之后,做说明逻辑处理
  3. 计算属性是注重计算结果,监听器是注重计算过程

watch函数:

<template>
    <div>
        <h2>Vue3监听器(ref定义的数据)</h2>
        <p>msg:{{ str }}</p>
        <p>num:{{ num }}</p>
        <p><input type="text" v-model="str"/></p>
        <p><input type="text" v-model="num"/></p>
    </div>
</template>

<script setup>
import { ref,computed ,reactive,watch } from 'vue'
let str = ref('hello')
let num = ref(0)
单变量的监听ref定义的数据,第一个值是监听的变量,第二个值是监听的回调函数,第三个值是监听器的配置
// watch(str,(newdata,olbdata)=>{
//     console.log('vue3',newdata,olbdata)   
// },{
//     immediate:true,
//     deep:true
// })
多变量的监听ref定义的数据,将需要监听的对象放入数组中
watch(
    [str,num],
    (n,l)=>{
        console.log(n,l)
    },
    {
        immediate:true,
        deep:true
    }
)
</script>

watchEffect函数:


import { ref , reactive ,watch,watchEffect } from 'vue'
watchEffect(()=>{
    const h = counst.value
    const n = number.value
    console.log('watchEffect 被调用了')
})

watch监听reactive的一些坑(很重要)

<template>
    <div>
        <h2>vue3的特殊计算属性</h2>
        名字:<input type="text" v-model="user.name"><br>
        年龄:<input type="text" v-model="user.age"><br>
        成绩:<input type="text" v-model="user.school.english.num"><br>
    </div>
</template>

<script setup>
import { reactive, computed, watch } from 'vue';
let user = reactive({
    name: '张三',
    age: '18',
    school: {
        english: {
            num: 85
        }
    }
})

1.监听reative数据时,无法获取正确的olbdata。因为reative数据是数组或对象,这些数据的键名都是指向某个内存地址。
2. deep深度监视默认开启,不是处理对象类型时无效
// watch(user, (newval, olbval) => {
//     console.log(newval, olbval)
// }, {
//     deep: false
// }
// )

4.监听器监听reactive的某个属性时报出错误:只能是ref类型,或响应式对象类型,或一个函数
// watch(()=>user.name, //所以我们需要通过一个函数的方式
//     (newval,olbval)=>{
//         console.log(newval,olbval)
//     }
// )

5.监听器监听reactive对象中的某个对象属性
// watch(()=>user.school,(newval,olbval)=>{
//     console.log(newval,olbval)
// },{
//     deep:true //深层监听,false就无法监听
// })

6.监听器监听reative定义的多个响应式数据 利用数组包裹
watch([()=>user.name,()=>user.age], 
(newval,olbval)=>{
    console.log(newval,olbval)
})
</script>

生命周期

注意: 

  1. 选项式API中出现两个同名钩子函数,后面的会覆盖前面的
  2. 组合式API中出现两个同名钩子不会覆盖会按顺序执行依次执行

Vue3获取Dom

<template>
    <div>
        <h2>Vue3的ref获取dom节点</h2>
        <div ref="boxs">321</div>
    </div>
</template>

<script setup>
import { onMounted , ref } from 'vue';
let boxs = ref(null)  //vue3中获取dom元素的方法是调用ref
                      //使用dom的时候因为是refimpl的响应数据所以要加.value
onMounted(() => {
   console.log(boxs.value)
   boxs.value.style.fontSize="40px"
   boxs.value.style.color="red"
})
</script>

Props

作用:子组件内使用defineProps来接收参数,不需要引入就可以使用

<template>
    <div>
        <h2>vue3的父组件</h2>
        <child :msgstr="msg" ></child>
    </div>
</template>

<script setup>
import  child  from './childer.vue'
import  { ref } from 'vue'
let msg = ref('msg number')
</script>
上面是父组件

下面是子组件
<template>
    <div>
        <h5>vue3的子组件{{ msgstr }}</h5>
        {{ mmg }}
    </div>
</template>

<script setup>
// let { msgstr } = defineProps(['msgstr']) //传过来的数据是对象,传递数据的名称:数据
// console.log(msgstr)
 defineProps({
    msgstr:{
        type:String, //定义数据类型
        default:'默认值'
    },
    mmg:{
        type:Number,
        default:100 //默认值
    }
})
</script>

Vue3 自定义事件

通过defineEmite宏来声明需要抛出的事件。和defineProps类似,defineEmits仅可用于<script setup>之中,并且不需要引入

<template>
    <div>
        <h2>vue3的父组件</h2>
        <child :msgstr="msg" @changeMsg="changeMsg" ></child>
    </div>
</template>
<script setup>
import  child  from './childer.vue'
import  { ref } from 'vue'
let msg = ref(true)
const changeMsg=(data)=>{
    msg.value=data
}
</script>
上面为父组件

下面为子组件
<template>
    <div>
        <h5>vue3的子组件{{ msgstr }}</h5>
        {{ mmg }}
        <button @click="changefather">自定义事件</button>
    </div>
</template>
<script setup>
let hh =  defineProps({ //设置返回值,方便函数内也可以调用传过来的参数
    msgstr:{
        type:Boolean, //定义数据类型
        default:true
    },
    mmg:{
        type:Number,
        default:100 //默认值
    }
})
const emit =  defineEmits(['changeMsg'])  //vue3组合式API的接收自定义事件的方式
const changefather = ()=>{
    console.log(hh.msgstr);
    emit('changeMsg',!hh.msgstr) //第一个值是事件名,第二个值是要传过去的参数
}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我的白银时代

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

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

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

打赏作者

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

抵扣说明:

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

余额充值