Vue3---监听器(watch),生命周期函数,Teleport(将组件插入到页面任何地方)

196 阅读2分钟

监听器(watch)

  • 与vue2.x中的watch配置功能一致

  • 注意

    • 监视reactive定义的响应式数据时,oldvalue无法正确获取,强制开始了深度监视(deep的配置失效)
    • 监视reactive定义的响应式数据的某一个值时:deep配置有效
<script setup>
import { ref, reactive, watch } from "vue";
let a = ref("111");
watch(a, (newvalue, oldvalue) => {
  console.log(newvalue, oldvalue, 11111);
})
function fn() {
  a.value = "2222"
}
let obj = reactive({ name: "dsl", sex: "man" })
function fn1() {
  obj.name = "zwq";
  obj.sex = "women"
}
watch(obj, (newvalue, oldvalue) => {
  console.log(newvalue, oldvalue, 2222);
})

</script>

<template>
  <div>
    <p>{{a}}</p>
    <button @click="fn">改变a的值</button>
    <p>name:{{obj.name}}</p>
    <p>sex:{{obj.sex}}</p>
    <button @click="fn1">换人</button>
  </div>
</template>

<style scoped lang="scss">

</style>

image.png

生命周期函数

Vue3生命周期

  • 什么是生命周期

    Vue中每个组件都是独立的,每个组件都有一个属于它的生命周期,从一个组件创建、数据初始化、挂载、更新、销毁、这就是一个组件所谓的生命中周期

  • Vue2.x中的生命周期

    beforeCreate   created
    beforeMount    mounted
    beforeUpdate  updated
    beforeDestroy  destroyed
    activated     
    deactivated   
    errorCaptured 
    
  • Vue3.x的生命周期

    在Vue3.x中,新增了一个setup生命周期函数,setup执行的时机是在beforeCreate生命函数之前执行,因为在这个函数中不能通过this来获取实例的;同时为了命名的统一,将beforeDestory改名为beforeUnmount,destoryed改名为unmounted

    beforeCreate(建议使用setup代替)created(建议使用setup代替)
    setup
    beforeMount     mounted
    beforeUpdate    updated
    beforeUnmount   unmounted
    

    vue3新增了生命周期钩子,我们可以通过在生命周期函数前加on来访问组件的生命周期

    Composition API 形式的生命周期钩子

    onBeforeMount  onMounted
    onBeforeUpdate  onUpdated
    onBeforeUnmount  onUnmounted
    onErrorCaptured
    onRenderTracked
    onRenderTriggered
    
    <script>
    import {
      onBeforeMount,
      onMounted,
      onBeforeUpdate,
      onUpdated,
      onBeforeUnmount,
      onUnmounted,
      ref
    } from 'vue'
     
    export default {
      setup () {
        // 其他的生命周期
        onBeforeMount (() => {
        console.log("App ===> 相当于 vue2.x 中 beforeMount")
        })
        onMounted (() => {
            console.log("App ===> 相当于 vue2.x 中 mounted")
        })
        
        // 注意,onBeforeUpdate 和 onUpdated 里面不要修改值
        onBeforeUpdate (() => {
            console.log("App ===> 相当于 vue2.x 中 beforeUpdate")
        })
        
        onUpdated (() => {
            console.log("App ===> 相当于 vue2.x 中 updated")
        })
        
        onBeforeUnmount (() => {
        console.log("App ===> 相当于 vue2.x 中 beforeDestroy")
        })
        
        onUnmounted (() => {
            console.log("App ===> 相当于 vue2.x 中 destroyed")
        })
       
        return {
        }
        
      }
    }
    </script>

    Teleport

Vue 鼓励我们通过将 UI 和相关行为封装到组件中来构建 UI。我们可以将它们嵌套在另一个内部,以构建一个组成应用程序 UI 的树。

然而,有时组件模板的一部分逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到 DOM 中 Vue app 之外的其他位置

模态弹框

to属性:放到指定位置

App.vue

<script setup>
import Box1 from './components/Box1.vue';
import Box2 from './components/Box2.vue'
</script>

<template>

  <Box1></Box1>
  <Box2></Box2>
  <div id="nav">
    <p>第二个弹窗插入到这里</p>

  </div>


</template>

<style scoped lang="scss">
#nav {
  width: 100%;
  height: 300px;
  background-color: red;
}
</style>

Box1.vue

<script setup>
import { ref } from "vue"
let msg = ref("hello")
let isshow = ref(false);
function fn() {
    isshow.value = true
}
function fn1() {
    isshow.value = false
}

</script>

<template>
    <div>
        <h1>{{msg}}</h1>
        <button @click="fn">点我有弹窗</button>
        <teleport to='body'>
            <div class="box" v-show="isshow">
                <p>模态弹窗</p>
                <button @click="fn1">关闭弹窗</button>
            </div>
        </teleport>
    </div>
</template>

<style  scoped lang="scss">
.box {
    width: 300px;
    height: 400px;
    background-color: skyblue;
}
</style>

Box2.vue

<script setup>
import { ref } from "vue"
let msg = ref("第二个弹窗")
let isshow = ref(false);
function fn() {
    isshow.value = true
}
function fn1() {
    isshow.value = false
}

</script>
    
<template>
    <div>
        <h1>{{msg}}</h1>
        <button @click="fn">点我有弹窗2</button>
        <!-- to表示要插入到父组件的哪里,填选择器 -->
        <teleport to='body'>
            <div class="nav" v-show="isshow">
                <p>模态弹窗</p>
                <button @click="fn1">关闭弹窗2</button>
            </div>
        </teleport>
    </div>
</template>
    
<style  scoped lang="scss">
.box {
    width: 150px;
    height: 200px;
    background-color: orchid;
}
</style>