前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue3 day4

vue3 day4

作者头像
花花522
发布2023-03-07 16:06:34
2480
发布2023-03-07 16:06:34
举报
文章被收录于专栏:花花爱咖啡

watchEffie

  • watch套路是:既要指明监视的属性,也要指明监视的回调
  • watchEffie的套路是:不用指明监视哪个属性,监视的回调中用到哪个,就监视哪个属性
  • watchEffie有点像computed
    • 但是computed注重计算出来的值(回调函数的返回值),所以必须写返回值
    • 而watchEffie更加注重的是过程(回调函数的函数体),所以不用写返回值
代码语言:javascript
复制
<template>
 <h1>求和结果是{{ sum }}</h1>
 <button @click="sum++">计算+1</button>
 <br>
 <h3>msg为{{ msg }}</h3>
 <button @click="msg+='!'">修改msg</button>

 <br>
 <h2>姓名:{{ person.name }}</h2>
 <h2>年龄:{{ person.age }}</h2>
 <h2>薪资:{{ person.job.j1.salary }}</h2>


 <button @click="person.age++">增加年龄</button>
 <button @click="person.name+='~'">增加姓名</button>
 <button @click="person.job.j1.salary++">涨薪</button>
 <button @click="person.job.j1.aaa[0] = 10 ">测试监听reactive中的数组</button>
</template>

<script>
import {reactive, ref, watchEffect} from "vue";

export default {
 name: "Demo",

 setup() {
   let sum = ref(0);
   let msg = ref("我是msg");
   let person = reactive({
     name: '花花',
     age: 20,
     job: {
       j1: {
         salary: 100,
         aaa: [1, 2, 3, 4]
      }
    }
  })

   //只要回调函数中用到的数据发生变化,就会自动执行回调
   //自带immediate:true
   watchEffect(() => {
     console.log(person.age)
     console.log(person.job.j1.salary)
     console.log("修改了")
  })


   return {
     sum, msg, person
  }
}
}
</script>

<style scoped>

</style>

生命周期

vue2的生命周期图

vue3的生命周期图‍

总结

vue3中依然可以使用v2的配置方式来定义生命周期钩子,但是有两个生命周期更改了名字

  • beforeDestroy改名为beforeUnmount
  • destroyed改名为unmounted

vue3也提供了composition api的形式的生命周期钩子,与vue2中钩子对应关系如下

  • beforeCreate=> setup()
  • created=> setup()
  • beforeMount => onBeforeMount
  • mounted => onMounted
  • beforeUpdate=>onBeforeUpdate
  • updated=> onUpdated
  • beforeUnmount=> onBeforeUnmount
  • unmounted=> onUnmounted

回顾vue2方式的生命周期写法

  • demo.vue
代码语言:javascript
复制
<template>

  <demo v-if="isShow">
  </demo>

  <button @click="isShow=!isShow">显示影藏</button>


</template>

<script>


import Demo from "@/components/Demo";
import {ref} from "vue";

export default {
  name: 'App',
  components: {Demo},
  setup(){

    let isShow = ref(true);
    return{
      isShow
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
  • app.vue
代码语言:javascript
复制
<template>
  <h1>标题</h1>
  <h2>{{age}}</h2>
  <button @click="age++">更改数据</button>
</template>

<script>

import {ref} from "vue";

export default {
  name: "Demo",

  beforeCreate() {
    console.log('---beforeCreate---')
  },
  created() {
    console.log('---created---')
  },
  beforeUpdate() {
    console.log('---beforeUpdate---')
  },
  updated() {
    console.log('---updated---')

  },
  beforeMount() {
    console.log('---beforeMount---')

  },
  mounted() {
    console.log('---mounted---')

  },
  beforeUnmount() {
    console.log('---beforeUnmount---')

  },
  unmounted() {
    console.log('---unmounted---')

  },

  setup() {
    return {
      age:ref(10)
    }
  }
}
</script>

<style scoped>

</style>

使用vue3写法写生命周期

  • 注意点 setup会最先执行
  • vue3写法执行会优先vue2
代码语言:javascript
复制
<template>
  <h1>标题</h1>
  <h2>{{ age }}</h2>
  <button @click="age++">更改数据</button>
</template>

<script>

import {onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated, ref} from "vue";

export default {
  name: "Demo",

  beforeCreate() {
    console.log('---beforeCreate---')
  },
  created() {
    console.log('---created---')
  },
  beforeUpdate() {
    console.log('---beforeUpdate---')
  },
  updated() {
    console.log('---updated---')

  },
  beforeMount() {
    console.log('---beforeMount---')

  },
  mounted() {
    console.log('---mounted---')

  },
  beforeUnmount() {
    console.log('---beforeUnmount---')

  },
  unmounted() {
    console.log('---unmounted---')

  },

  setup() {
    console.log("---setup---")

    onBeforeUpdate(() => {
      console.log("---onBeforeUpdate---")

    })

    onUpdated(() => {
      console.log("---onUpdated---")

    })

    onBeforeMount(() => {
      console.log("---onBeforeMount---")

    })


    onMounted(() => {
      console.log("---onMounted---")

    })

    onBeforeUnmount(() => {
      console.log("---onBeforeUnmount---")

    })

    onUnmounted(() => {
      console.log("---onUnmounted---")

    })


    return {
      age: ref(10)
    }
  }
}
</script>

<style scoped>

</style>

hook

需求,获取鼠标的点击位置

  • 基础代码实现
代码语言:javascript
复制
<template>
  <h2>测试hook</h2>
  <p>鼠标点击的坐标是 x:{{ point.x }} ,y:{{ point.y }}</p>
</template>

<script>

import {onMounted, onUnmounted, reactive, ref} from "vue";

export default {
  name: "Demo",

  setup() {

    let point = reactive({
      x: 0,
      y: 0
    })

    const clickFun = event => {
      point.x = event.pageX
      point.y = event.pageY
    };

    onMounted(()=>{
      window.addEventListener("click",clickFun )

    })

    onUnmounted(()=>{
      window.removeEventListener("click",clickFun )

    })
    return {
      age: ref(10),
      point
    }
  }
}
</script>

<style scoped>

</style>
  • hook代码实现

usePoint.js

代码语言:javascript
复制
import {onMounted, onUnmounted, reactive} from "vue";

export default function () {

    let point = reactive({
        x: 0,
        y: 0
    })

    const clickFun = event => {
        point.x = event.pageX
        point.y = event.pageY
    };

    onMounted(() => {
        window.addEventListener("click", clickFun)

    })

    onUnmounted(() => {
        window.removeEventListener("click", clickFun)

    })

    return point
}
  • 使用hook
代码语言:javascript
复制
<template>
  <h2>测试hook</h2>
  <p>鼠标点击的坐标是 x:{{ point.x }} ,y:{{ point.y }}</p>
</template>

<script>

import {ref} from "vue";
import usePoint from '../hooks/UserPoint'

export default {
  name: "Demo",

  setup() {

    const point = usePoint()
    return {
      age: ref(10),
      point
    }
  }
}
</script>

<style scoped>

</style>

自定义hook函数

  • 什么是hook? 本质是一个函数,把setup函数中使用到的composition api 进行了封装
  • 类似于vue2中的mixin
  • 自定义hook的优势,复用代码,让setup中的逻辑更清晰易懂

toRef

先看下原始代码

代码语言:javascript
复制
<template>
  <h2>测试toRef</h2>
  <h1>姓名{{ person.name }}</h1>
  <h2>年龄{{ person.age }}</h2>
  <h3>薪水{{ person.job.j1.salary }}</h3>

  <button @click="person.age++">年龄增长</button>
  <button @click="person.name+='~'">姓名修改</button>
  <button @click="person.job.j1.salary++">涨薪</button>

</template>

<script>


import {reactive} from "vue";

export default {
  name: "Demo",

  setup() {

    let person = reactive({
      name: '花花',
      age: 20,
      job: {
        j1: {
          salary: 300
        }
      }
  })

  return {
    person
  }
}
}
</script>

<style scoped>

</style>

存在的问题: 在模板中反复使用了person.来取值

  • 使用toRef简化操作
代码语言:javascript
复制
<template>
  <h2>测试toRef</h2>
  <h1>姓名{{ name }}</h1>
  <h2>年龄{{ age }}</h2>
  <h3>薪水{{ salary }}</h3>

  <button @click="age++">年龄增长</button>
  <button @click="name+='~'">姓名修改</button>
  <button @click="salary++">涨薪</button>

</template>

<script>


import {reactive, toRef} from "vue";

export default {
  name: "Demo",

  setup() {

    let person = reactive({
      name: '花花',
      age: 20,
      job: {
        j1: {
          salary: 300
        }
      }
    })

    return {
      name: toRef(person, 'name'),
      age: toRef(person, 'age'),
      salary: toRef(person.job.j1,'salary')
    }
  }
}
</script>

<style scoped>

</style>
  • 注意,这里不能使用Ref,因为Ref会生成新对象,不会修改原有的person

使用ToRefs简化ToRef

代码语言:javascript
复制
<template>
  <h2>测试toRef</h2>
  <h1>姓名{{ name }}</h1>
  <h2>年龄{{ age }}</h2>
  <h3>薪水{{ job.j1.salary }}</h3>

  <button @click="age++">年龄增长</button>
  <button @click="name+='~'">姓名修改</button>
  <button @click="job.j1.salary++">涨薪</button>

</template>

<script>


import {reactive, toRefs} from "vue";

export default {
  name: "Demo",

  setup() {

    let person = reactive({
      name: '花花',
      age: 20,
      job: {
        j1: {
          salary: 300
        }
      }
    })

    //这里对toRefs之后的对象进行了解构
    return {
      person,
      ...toRefs(person)
    }
  }
}
</script>

<style scoped>

</style>

总结

  • 作用: 创建一个ref对象,其value值指向另一个对象中的某个属性
  • 语法const name = toRef(person,'name')
  • 应用": 要将响应式数据中的某一个属性给外部使用
  • 扩展: toReftoRefs功能一致,但是可以批量创建多个ref对象,语法:toRefs(person)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 花花爱咖啡 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • watchEffie
  • 生命周期
  • hook
  • toRef
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档