vue3前端学习

本文详细介绍了Vue3中的组合式API,包括reactive函数处理响应式数据、ref函数的使用、computed进行计算属性、watch的监听功能,以及生命周期函数、父子组件间的通信和template引用。还讨论了provide和inject用于跨层数据与方法传递的重要性。
摘要由CSDN通过智能技术生成

基础知识学习

组合式API reactive和ref函数

reactive函数 

传入对象类型的参数 变量接收

<script setup>
import {reactive} from 'vue'
const state=reactive({
  count:0
})

const setCount = ()=>{
  state.count++
}
</script>

<template>
  <div>
    <button @click="setCount">{{ state.count }}</button>
  </div>
</template>

ref函数

接受简单类型和对象类型 返回响应式数据

<script setup>
import { ref } from 'vue';
const count=ref(0)
console.log(count);
const setCount = ()=>{
//脚本区域修改ref产生响应式数据 必须通过.value属性进行++
  count.value++
}
</script>

<template>
  <div>
    <button @click="setCount">{{ count }}</button>
  </div>
</template>

组合式API computed函数

核心步骤:

1.导入computed函数

2.执行函数 在回调参数中return基于响应式数据作计算的值,用于变量的接收

<script setup>
import {ref} from 'vue'
import { computed } from 'vue';
const list = ref([1,2,3,4,5,6])
const computedList = computed(()=>{
  return list.value.filter(item => item>2)
})

setTimeout(() => {
  list.value.push(9,10)
}, 3000);
</script>

<template>
  <div>
    原始数据-{{ list }}
  </div>
  <div>
    计算后的数据-{{ computedList }}
  </div>
</template>

组合式API watch函数

watch侦听单个数据源

两个参数,第一个参数是响应式数据,第二个参数是回调

<script setup>
import { ref,watch } from 'vue'
const count=ref(0)
const setCount = ()=>{
  count.value++
}

// watch侦听单个数据源
// 在watch中ref对象不需要加.value
watch(count,(newValue,oldValue)=>{
  console.log('count变化了',newValue,oldValue);
})

</script>

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

</template>

watch侦听多个数据源

传参的时候变为数组的多个参数

<script setup>
import {ref,watch} from 'vue'
const count=ref(0)
const setCount = ()=>{
  count.value++
}

const name=ref('cp')
const changeName = ()=>{
  name.value = 'pc'
}

//watch侦听多个数据源
watch([count,name],(
  [newCount,newName],
  [oldCount,oldName]
)=>{
  console.log('count或name变化了',[newCount,newName],
  [oldCount,oldName]);

})
</script>

<template>
  <div>
    <button @click="setCount">修改count--{{ count }}</button>
  </div>
  <div>
    <button @click="changeName">修改name--{{name}}</button>
  </div>
</template>

immediate

在侦听器创建时立即触发回调,响应式数据变化之后继续执行回调

<script setup>
import { ref,watch } from 'vue'
const count=ref(0)
const setCount = ()=>{
  count.value++
}

// watch侦听单个数据源
// 在watch中ref对象不需要加.value
watch(count,()=>{
  console.log('count变化了');
},{
  immediate:true
})

</script>

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

</template>

watch中三个参数,增加immediate后,先执行回调函数一次。

deep

默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项。

<script setup>
import {ref,watch} from 'vue'
const state=ref({count:0})
const changeStateByCount = ()=>{
  state.value.count++
}

// watch深度监听
watch(state,()=>{
  console.log('count变化了');
},{
  deep:true
})
</script>

<template>
  <div>
    <button @click="changeStateByCount">{{state.count}}--修改count</button>
  </div>
</template>

deep有性能损耗 尽量不开启deep

精确侦听

<script setup>
import {ref,watch} from 'vue'
const state=ref({
  name:'zhangsan',
  age:20
})

const ChangeName = ()=>{
  state.value.name = 'lisi'
}

const ChangeAge = ()=>{
  state.value.age=18
}

//精确侦听某个具体属性
watch(
  ()=>state.value.age,
  ()=>{
    console.log('age变化了');
  }
)
</script>

<template>
  <div>
  <div>
    <div>当前姓名{{ state.name }}</div>
    <div>当前年龄{{ state.age }}</div>
    </div>
<div>
  <button @click="ChangeName">修改name</button>
  <button @click="ChangeAge">修改age</button>
</div>
</div>
</template>

不开启deep,想在某个层次比较深的属性变化时执行回调:

可以把第一个参数写成函数的写法,返回要监听的具体属性。

组合式API 生命周期函数

vue3的生命周期API(选项式 VS 组合式)

选项式API组合式API
beforeCreate/createdsetup
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeUnmountonBeforeMount
unmountedonUnmounted

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

onMounted(()=>{
  console.log('组件挂在完毕1');
  // 好多逻辑
})

onMounted(()=>{
  console.log('组件挂在完毕2');
  // 补充逻辑
})

</script>

<template>
  
</template>

组合式API 父子通信

父传子

基本思想:

1.父组件给子组件绑定属性

2.子组件内部通过props选型接收

vue3中子组件内部通过编译器宏函数接收:defineProps(传入对象类型的数据)

App.vue

<script setup>
// setup语法糖下局部组件无需注册即可使用
import {ref} from 'vue'
import SonCom from './son-com.vue'

const count = ref(100)
setTimeout(()=>{
  count.value=200
},3000)
</script>

<template>
  <div class="father">
    <h2>父组件App</h2>
    <!--1.绑定属性 -->
    <SonCom :count='count' message="father message"/>
  </div>
  
</template>

<style scoped>

</style>

son-com.vue

<script setup>
// 2. defineProps接收数据
const props = defineProps({
    message:String,
    count:Number
})
console.log(props);

</script>

<template>
    <div class="son">
        <h3>子组件Son</h3>
    <div>
        父组件传入数据-{{ message }}-{{ count }}
    </div>
    </div>
</template>

<style scoped>

</style>

子传父

基本思想:

1.父组件中给子组件标签通过@绑定事件

2.子组件内部通过$emit方法触发事件

vue3中通过defineEmits编译器宏生成emit方法

App.vue

<script setup>
// 引入子组件
import sonComVue from './son-com.vue'
const getMessage = (msg)=>{
  console.log(msg);
}
</script>

<template>
  <!-- 1.绑定自定义事件 -->
  <sonComVue @get-message = "getMessage"/>
</template>

son-com.vue

<script setup>
// 2.通过 defineEmits编译器宏生成emit方法
const emit=defineEmits(['get-message']) //传入数组格式的参数,原因是要求将当前组件触发的所有的自定义事件都放过来
const sendMsg = ()=>{
    // 3.触发自定义事件,并传递参数
    emit('get-message','this is son msg')
}
</script>

<template>
    <button @click="sendMsg">sendMsg</button>
</template>

组合式API 模板引用

模板引用的概念:

通过ref标识获取真实的dom对象或组件实例对象

如何使用(以获取dom为例 组件同理)

1.调用ref函数生成一个ref对象

2.通过ref标识绑定ref对象到标签

<script setup>
import { onMounted } from 'vue'
import {ref} from 'vue'
// import TestCom from './test-com.vue'

// 1.调用ref函数 -> ref对象(可以把它看作容器)
const h1Ref = ref(null)

// 组件挂载完毕之后才能获取
onMounted(()=>{
  console.log(h1Ref.value);
})
</script>



<template>
  <!-- 2.通过ref标识绑定ref对象 -->
  <h1 ref="h1Ref">我是dom标签h1</h1> 
  <!-- 已经将h1 dom对象存入到h1Ref.value -->
  <!-- <TestCom/> -->
</template>

defineExpose()

默认情况下在<script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性和方法允许访问

test-com.vue

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

const name = ref('test name')
const setName = ()=>{
    name.value = 'test new name'
}

defineExpose({
    name,
    setName
})

</script>

<template>
    <div>我是test组件</div>
</template>

总结问题:

1.获取模板引用的时机是什么?

组件挂载完毕

2.defineExpose编译宏的作用是什么?

显示暴露组件内部的属性和方法

组合式API provide和inject

作用和场景:

顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信

跨层传递普通数据

1.顶层组件通过provide函数提供数据

2.底层组件通过inject函数获取数据

App.vue

<script setup>
import RoomMsgItem from './room-msg-item.vue'
import roomMsgComment from './room-msg-comment.vue';
import roomPage from './room-page.vue';
// 组件嵌套关系
// RoomPage -> RoomMsgItem -> RoomMsgComment

</script>

<template>

    <div>
    <roomPage />
  </div>

    
</template>

<style scoped>

</style>

room-page.vue

<script setup>
import { provide,ref } from 'vue';
import RoomMsgItem from './room-msg-item.vue'
// 组件嵌套关系
// RoomPage -> RoomMsgItem -> RoomMsgComment

// 1.顶层组件提供数据
provide('data-key','this is room data')

// 传递响应式对象
const count = ref(0)
provide('count-key',count)
setTimeout(()=>{
    count.value=100

},3000)

</script>

<template>
    <div class="page">
        顶层组件
        <RoomMsgItem />
    </div>
    
</template>

<style scoped>

</style>

room-message-item.vue

<script setup>
import roomMsgComment from './room-msg-comment.vue';

</script>

<template>
    <div class="item">
        中间组件
        <roomMsgComment />

    </div>
</template>

<style scoped>

</style>

room-msg-comment.vue

<script setup>
import { inject } from 'vue';
// 2.接收数据
const roomData = inject('data-key')

const countData = inject('count-key')

</script>

<template>
    <div class="comment">
        底层组件
    <div>
        来自顶层组件中的数据为:{{ roomData }}
    </div>

    <div>
        来自顶层组件中的响应式数据:{{ countData }}
    </div>

    </div>
    
</template>

<style scoped>

</style>

跨层传递方法

顶层组件可以向底层组件传递方法 底层组件调用方法修改顶层组件中的数据

在顶层组件通过传递方法,在底层组件调用这个方法。目的是不破坏单向数据流的前提下,在底层组件中可以修改顶层组件中的数据。

在开发过程中需要遵守的一条原则:

谁的数据谁负责修改

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值