首页 > 其他分享 >Vue3-Composition-API-学习笔记

Vue3-Composition-API-学习笔记

时间:2023-12-06 10:04:21浏览次数:26  
标签:info vue const name counter API Vue3 ref Composition


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>

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


标签:info,vue,const,name,counter,API,Vue3,ref,Composition
From: https://blog.51cto.com/u_15565664/8699751

相关文章

  • Vue3的手脚架使用和组件父子间通信-插槽(Options API)学习笔记
    VueCLI安装和使用全局安装最新vue3npminstall@vue/cli-g升级VueCLI:如果是比较旧的版本,可以通过下面命令来升级npmupdate@vue/cli-g通过脚手架创建项目vuecreate01_product_demoVue3父子组件的通信父传子父组件<template><div><divclass="item"v-for="(item,in......
  • Flask-Restful-Api
    restful属于一种快速构建api的一种工具,和django的还是不相同的安装pipinstallflask-restful可以和django一样进行定义类视图的方式但是falskrestful中可以直接返回字典格式,它自动转换为json格式给客户端基本的使用fromflaskimportFlaskfromflask_restfulimp......
  • Cplex学术版申请及Python API环境配置
    当使用Cplex时弹出下面错误:CPLEXError1016:CommunityEdition.Problemsizelimitsexceeded.Purchaseathttp://ibm.biz/error1016.不出意外,是因为使用了社区版的Cplex无法求解大规模问题。这时候就需要申请学术版Cplex了。在我寻找Cplex学术版下载教程中,找遍全网都没......
  • [GraphicBufferSource](id:5cd400000003,api:1,p:1674,c:23764) cancelBuffer: Buffer
    开发中遇到的问题,这个问题吧属于我们公司开发使用的RSR然后我们做好的app就是一个录屏软件将视频推到RSR当中去,可是推送的同时只会在RSR中出现一下我查看日志文件输出的信息唯一出现爆红的地方就是GraphicBufferSourcecancelBuffer:BufferQueuehasbeenabandoned这个,有没有经......
  • vue3使用虚拟化表格自定义表格并动态生成表头
    elementPlus的虚拟化表格用的是lang=tsx,先安装cnpmi@vitejs/plugin-vue-jsx然后去vite.config.ts里加配置importvueJsxfrom'@vitejs/plugin-vue-jsx'plugins:[vue(),vueJsx(),]再去tsconfig.json中加东西//不要把compilerOptio......
  • Native API在HarmonyOS应用工程中的使用指导
    HarmonyOS的应用必须用js来桥接native。需要使用ace_napi仓中提供的napi接口来处理js交互。napi提供的接口名与三方Node.js一致,目前支持部分接口,符号表见ace_napi仓中的libnapi.ndk.json文件。开发流程在DevEco Studio的模板工程中包含使用Native API的默认工程,使用File->New->Cr......
  • Scope api1 not found in store. IdentityServer4.Validation.TokenRequestValidator:
    看明白了这个报错,说是scopeapi在授权服务器没有定义,但是一直不知道哪出错,我寻思也定义了这个资源来着但其实并没有,说的是scope不是说的resource,所以需要再定义一个Scope  ......
  • [转]vue3+tsx开发语法详解
    原文地址:vue3+tsx开发语法详解-知乎很多组件库都使用了TSX的方式开发,主要因为其灵活性比较高,TSX和SFC开发的优缺点就不介绍了,这里主要说一下将SFC项目改造为TSX的过程。安装JSX库pnpminstall@vitejs/plugin-vue-jsx-D安装完之后在vite.config.ts进行插件使用,代码如下......
  • 学习Vue3 第六章(认识Ref全家桶)
    ref接受一个内部值并返回一个响应式且可变的ref对象。ref对象仅有一个 .value property,指向该内部值<template><div><button@click="changeMsg">change</button><div>{{message}}</div></div></template><......
  • Native API在HarmonyOS应用工程中的使用指导
     HarmonyOS的应用必须用js来桥接native。需要使用ace_napi仓中提供的napi接口来处理js交互。napi提供的接口名与三方Node.js一致,目前支持部分接口,符号表见ace_napi仓中的libnapi.ndk.json文件。开发流程在DevEco Studio的模板工程中包含使用Native API的默认工程,使用File-......