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(){// 定义相应式数据:reactiveconst 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.定义scoreconst 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 > 10if(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>
感谢大家观看,我们下次见