Vue3-Composition-API-学习笔记
CSDN/ab2019发表于:2024-05-12 23:56:41浏览:122次
01.Setup函数的体验
App.vue
<template>
<div>
<h2>当前计数:{{ counter }}</h2>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template>
<script>
import useCounter from './hooks/useCounter'
export default {
setup(){
// const { counter,increment,decrement } = useCounter()
// return { counter,increment,decrement }
return {
...useCounter()
}
}
}
</script>
<style scoped>
</style>
useCounter.js
import { ref } from 'vue'
export default function useCounter(){
const counter = ref(100)
const increment = () => {
counter.value++
console.log(counter.value)
}
const decrement = () =>{
counter.value--
}
return {
counter,
increment,
decrement
}
}
02.Setup定义数据
App.vue
<template>
<div>
<form action="">
账号:<input type="text" v-model="account.username">
密码:<input type="password" v-model="account.password">
</form>
</div>
</template>
<script>
import { reactive,ref } from 'vue';
export default{
setup(){
// 定义相应式数据:reactive
const info = ref({})
console.log(info.value)
// 1. reactive的应用场景
// 1.1 条件1:reactive的应用场景
// 1.2 条件2:多个数据之间是有关系/联系的(聚合的数据,组织在一起会有特定的数作用)
const account = reactive({
username:"coderwhy",
password:"123456"
})
return {
account
}
}
}
</script>
<style scoped>
</style>
App1.vue
<template>
<div>
<h2>message:{{ message }}</h2>
<button @click="changeMessage">修改message</button>
<hr>
<h2>账号:{{ account.username }}</h2>
<h2>密码:{{ account.password }}</h2>
<button @click="changeAccount">修改账号</button>
<hr>
<!-- 默认清空下在template中使用ref时,vue会自动进行千层解包(取出value) -->
<h2>当前计数:{{ counter }}</h2>
<button @click="increment">+1</button>
<hr>
<!-- 使用的时候 -->
<h2>当前计数:{{ info.counter }}</h2>
<!-- 修改的时候需要写.value -->
<button @click="info.counter.value++">+1</button>
</div>
</template>
<script>
import { reactive,ref } from 'vue';
export default {
setup(){
// 1.定义普通的数据
// 缺点:数据不是响应式的
let message = "Hello World"
// 2.定义响应式数据
// 2.1 reactive函数:定义复杂类型数据
const account = reactive({
username:"coderwhy",
password:"123456"
})
function changeAccount(){
account.username = "kobe"
}
function changeMessage() {
message = "你好啊,李焕英"
console.log(message)
}
// 2.2 counter定义响应式数据
// ref函数:定义简单类型的数据
const counter = ref(0)
// const counter = reactive({
// counter:0
// })
function increment(){
counter.value++
}
// 3.ref是浅层解包
const info = {
counter
}
return {
message,
changeAccount,
changeMessage,
counter,
account,
increment,
info
}
}
}
</script>
<style scoped>
</style>
03.setup其他函数
App.vue
<template>
<div>
<h2>App</h2>
<ShowInfo @change_name="change_name" :reinfo="reinfo" @change_rename="change_rename" :info="info"></ShowInfo>
</div>
</template>
<script>
import { reactive,readonly } from 'vue';
import ShowInfo from './ShowInfo.vue';
export default {
components:{
ShowInfo
},
setup(){
const info = reactive({
name:'kebo',
age:18,
sex:'男'
})
const reinfo = readonly(info)
function change_name(eve){
info.name = eve
}
function change_rename(reeve){
info.name = reeve
}
return {
info,
change_name,
reinfo,
change_rename
}
},
}
</script>
<style scoped>
</style>
ShowInfo.vue
<template>
<div>
<h2>info: {{ info }}</h2>
<button @click="change_name">改变info.name</button>
<hr>
<h2>reinfo:{{ reinfo }}</h2>
<!-- <button @click="reinfo.name='hahaha'">修改reinfo.name</button> -->
<button @click="change_rename">修改reinfo.name</button>
</div>
</template>
<script>
export default {
props:{
info:{
type:Object,
default:() => ({})
},
reinfo:{
type:Object,
default:() => ({})
},
},
emits:['change_name','change_rename'],
setup(props,context){
function change_name(){
context.emit("change_name",'why')
}
function change_rename(){
context.emit("change_rename",'tom')
}
return {
change_name,
change_rename
}
},
methods:{
}
}
</script>
<style scoped>
</style>
04.Setup中toRefs
App.vue
<template>
<div>
<div>info:{{ info.name }} -- {{ info.age }}</div>
<div>name:{{ name }}---age:{{ age }}</div>
<button @click="age++">age+1</button>
<hr>
<div>height:{{ height }}</div>
<button @click="height++">height++</button>
</div>
</template>
<script>
import { reactive,toRefs,toRef } from "vue";
export default {
setup(){
const info = reactive({
name:'tom',
age:18,
height:188
})
// reactive被结构将会编程普通的数据,失去响应式
const { name,age } = toRefs(info)
const height = toRef(info,"height")
return {
info,
name,
age,
height
}
}
}
</script>
<style scoped>
</style>
05.Setup中computed
App.vue
<template>
<div>
<div>fullname:{{ fullname }}</div>
<button @click="setFullname">设置fullname</button>
<div>scoreLevel:{{ scoreLevel }}</div>
</div>
</template>
<script>
import { ref,reactive,computed } from 'vue'
export default {
setup(){
// 1.定义数据
const names = reactive({
firstName:"kobe",
lastName:"bryant"
})
// const fullname = computed(()=>{
// return names.firstName +" "+ names.lastName
// })
const fullname = computed({
set:function(newValue){
const tempNames = newValue.split(" ")
names.firstName = tempNames[0]
names.lastName = tempNames[1]
},
get:function(){
return names.firstName + " " + names.lastName
}
})
console.log(fullname)
function setFullname(){
fullname.value = "coder why"
console.log(names)
}
// 2.定义score
const score = ref(89)
const scoreLevel = computed(()=>{
return score.value >= 60 ? "及格" : "不及格"
})
return {
names,
fullname,
scoreLevel,
setFullname
}
}
}
</script>
<style scoped>
</style>
06.Setup中ref引入元素
App.vue
<template>
<div>
<!-- 1.获取元素 -->
<h2 ref="titleRef"> 我是标题 </h2>
<button ref="btnRef">按钮</button>
<ShowInfo ref="ShowInfoRef"></ShowInfo>
<button @click="getElements">获取元素</button>
</div>
</template>
<script>
import { ref,onMounted } from 'vue'
import ShowInfo from './ShowInfo.vue'
export default {
// mounted(){
// console.log(this.$refs.title)
// console.log(this.$refs.btn)
// }
components:{
ShowInfo
},
setup(){
const titleRef = ref()
const btnRef = ref()
const ShowInfoRef = ref()
// mounted的生命周期函数
onMounted(()=>{
console.log(titleRef.value)
console.log(btnRef.value)
console.log(ShowInfoRef.value)
ShowInfoRef.value.ShowInfoFoo()
})
function getElements(){
console.log(titleRef.value)
}
return {
titleRef,
getElements,
btnRef,
ShowInfoRef
}
}
}
</script>
<style scoped>
</style>
ShowInfo.vue
<template>
<div>
<div>ShowInfo</div>
</div>
</template>
<script>
export default {
// methods:{
// function ShowInfoFoo(){
// console.log("showInfo foo function")
// }
// },
setup(){
function ShowInfoFoo(){
console.log("showInfo foo function")
}
return {
ShowInfoFoo
}
}
}
</script>
<style scoped>
</style>
07.Setup生命周期函数
App.vue
<template>
<div>
</div>
</template>
<script>
import { onMounted } from 'vue'
export default {
// created(){
// },
// beforeMount(){
// },
// mounted(){
// },
// beforeUpdate(){
// },
// updated(){
// }
setup(){
// 在执行setup函数的过程中,你需要注册别的生命周期函数
onMounted(()=>{
console.log("onmounted")
})
}
}
</script>
<style scoped>
</style>
08.Setup-Provide-Inject
App.vue
<template>
<div>
<div>App:{{ name }} --</div>
<ShowInfo></ShowInfo>
</div>
</template>
<script>
import ShowInfo from './ShowInfo.vue';
import { provide,ref } from 'vue'
export default {
components:{
ShowInfo
},
setup(){
const name = ref("why")
provide("name",name)
provide("age",18)
return {
name,
}
}
}
</script>
<style scoped>
</style>
ShowInfo.vue
<template>
<div>
<div>showInfo:{{ name }} -- {{ age }}</div>
<button @click="name = 'kobe'">app btn</button>
</div>
</template>
<script>
import { inject } from 'vue';
export default {
setup() {
const name = inject("name");
const age = inject("age");
return {
name,
age
};
},
}
</script>
<style scoped>
</style>
09.Setup-侦听数据变化
App.vue
<template>
<div>
<div>当前计数 {{ counter }}</div>
<button @click="counter++">+1</button>
<button @click="change_name">修改name</button>
</div>
</template>
<script>
import { ref,watchEffect } from 'vue'
export default {
setup(){
const counter = ref(0);
const name = ref('why');
// 1.watchEffect传入的函数默认会直接被执行
// 2.在执行过程中,会自动的收集依赖(以来那些响应式的数据)
const stopWatch = watchEffect(()=>{
console.log("------",counter.value,name.value)
// 判断counter.value > 10
if(counter.value >= 10){
stopWatch()
}
})
function change_name(){
name.value='kobi'
}
return {
counter,
change_name,
name
}
}
}
</script>
<style scoped>
</style>
App-watch.vue
<template>
<div>
<h2>message:{{ message }}</h2>
<button @click="change_message">修改message</button>
<button @click="change_info">修改info</button>
</div>
</template>
<script>
// import { watch } from 'fs'
import { ref,watch,reactive } from 'vue'
export default {
setup(){
const message = ref('hello');
const info = reactive({
name:'tom',
age:18,
friend:{
name:"kobe"
}
})
function change_message(){
message.value = '你好!'
}
function change_info(){
info.name = 'hhhhh'
}
// 2.侦听变化
watch(message,(newValue,oldValue)=>{
console.log(newValue,oldValue)
})
// watch(info,(newValue,oldValue)=>{
// console.log(newValue,oldValue)
// console.log(newValue == oldValue)
// },{
// immediate:true // 深度侦听
// })
// 3.监听reactive数据变化后,获取普通对象
watch(()=>({ ...info }),(newValue,oldValue)=>{
console.log(newValue,oldValue)
},{
immediate:true,
deep:true
})
return {
change_message,
message,
info,
change_info
}
}
}
</script>
<style scoped>
</style>
10.Setup-Hooks练习
App.vue
<template>
<div>
<div>App:{{ counter }}</div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="index_tab('首页-热门')">首页-热门</button>
<button @click="index_tab('首页-流行')">首页-流行</button>
<button @click="index_tab('首页-歌单')">首页-歌单</button>
<hr>
<HomeCom></HomeCom>
<hr>
<AboutCom></AboutCom>
</div>
</template>
<script>
import HomeCom from './views/HomeCom.vue';
import AboutCom from './views/AboutCom.vue';
import useCounter from './hooks/useCounter';
import useTitle from './hooks/useTitle';
export default {
components: {
HomeCom,
AboutCom
},
setup() {
const title = useTitle("首页")
function index_tab(eve){
title.value = eve
}
return {
index_tab,
...useCounter()
}
}
}
</script>
<style scoped></style>
AboutCom.vue
<template>
<div>
<div>About:{{ counter }}</div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="change_title">修改title</button>
</div>
</template>
<script>
import useCounter from '../hooks/useCounter';
import useTitle from '../hooks/useTitle';
export default {
setup(){
const title = useTitle("首页")
// 监听事件点击
function change_title(){
title.value = '关于';
}
return {
change_title,
...useCounter()
}
}
}
</script>
<style scoped>
</style>
HomeCom.vue
<template>
<div>
<div>Home:{{ counter }}</div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>
</template>
<script>
import useCounter from '../hooks/useCounter';
export default {
setup(){
return {
...useCounter()
}
}
}
</script>
<style scoped>
</style>
useCounter.js
import { ref,onMounted } from 'vue'
export default function useCounter(){
const counter = ref(0)
function increment(){
counter.value++
}
function decrement(){
counter.value--
}
onMounted(()=>{
setTimeout(()=>{
counter.value = 989
},1000)
})
return {
counter,
increment,
decrement
}
}
useTitle.js
import { watch,ref } from "vue"
export default function useTitle(titleValue){
// document.title = title
// 定义ref的引入数据
const title = ref(titleValue)
// 监听title的改变
watch(title,(newValue)=>{
document.title = newValue
},{
immediate:true // 第一次不执行
})
// 返回ref值
return title
}
11.script_setup语法
App.vue
<template>
<div>
<div>App</div>
<button @click="changeMessage">修改message</button>
<show-info ref="showInfoRef" @info-btn-click="infoBtnClick" name="why" :age="18"></show-info>
<!-- <ShowInfo></ShowInfo>
<ShowInfo></ShowInfo>
<ShowInfo></ShowInfo> -->
</div>
</template>
<script setup>
// 1. 所以定义在顶层中的代码,都是默认暴露给template可以使用
import { onMounted,ref } from 'vue';
import ShowInfo from './ShowInfo.vue';
// 2. 定义响应式数据
const message = ref("hello world")
console.log(message)
// 3. 定义绑定的函数
function changeMessage(){
message.value = "你好,世界"
}
function infoBtnClick(eve){
console.log("监听到infoBtnClick内部的info",eve)
}
// 4. 获取组件实例
const showInfoRef = ref();
onMounted(()=>{
showInfoRef.value.foo()
console.log("showInfoRef.value.message",showInfoRef.value.message)
})
</script>
<style scoped>
</style>
ShowInfo.vue
<template>
<div>
message:-- {{ name }} --- {{ age }}
<button @click="showInfoBtnClick">showinfo</button>
</div>
</template>
<script setup>
import { defineProps,defineEmits,defineExpose } from 'vue';
const message = "hello world"
// console.log(message)
// 定义props const props =
defineProps({
name:{
type:String,
default:"默认值"
},
age:{
type:Number,
default:0
}
})
// 绑定函数,并发出事件
const emits = defineEmits(["infoBtnClick"])
function showInfoBtnClick(){
emits("infoBtnClick","showInfo内部发生了点击")
}
// 定义foo的函数
function foo(){
console.log("foo function")
}
defineExpose({
foo,
message
})
</script>
<style scoped>
</style>
感谢大家观看,我们下次见