Vue3-Composition-API-学习笔记
  Ogq95wqcVuiC 2023年12月06日 21 0


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>

感谢大家观看,我们下次见


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月06日 0

暂无评论

推荐阅读
Ogq95wqcVuiC