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>
感谢大家观看,我们下次见