day12vue3的生命周期函数、组件通信、使用ref

一、生命周期函数

1.创建期

创建(实例化)期 , 会自动执行 且只会执行一次

vue2中的实例化期 的方法 beforeCreate 和 created 被 setup 代替了

2.挂载期

挂载期 , 会自动执行 且只会执行一次。可以在这里发送网络请求,创建定时器,监听事件

//挂载期
  onBeforeMount(()=>{
    console.log('onBeforeMount 挂载前');
  })
  onMounted(()=>{
    console.log('onMounted 挂载完成');

3.更新期

更新期的方法可以反复执行

//更新期
  onBeforeUpdate(()=>{
    console.log('onBeforeUpdate 更新前');
  })
  onUpdated(()=>{
    console.log('onUpdated 更新完成');
  })

4.卸载期

卸载期的方法只会执行一次

//卸载期
  onBeforeUnmount(()=>{
    console.log('onBeforeUnmount 卸载前');
    //可以在这里取消发送网络请求,销毁定时器,取消事件监听
  })
  onUnmounted(()=>{
    console.log('onUnmounted 卸载完成');
  })

5.捕获来自子组件的错误

可以在 errorCaptured() 中更改组件状态来为用户显示一个错误状态。

二、组件通信

1.父向子传值

  1.父组件在子组件身上通过自定义属性传值,

  2.子组件内部通过defineProps接收值

父组件
<template>
  <div class="app">
    <child :count="count"/>----在父组件内部渲染的子组件身上通过自定义属性money传值给外部的子组件
  </div>
</template>
<script setup>
import {ref} from 'vue'
import Child from './components/Child.vue'---导入子组件
var count = ref(100)
</script>
子组件
<template>
  <div class="child">
    <h3>child子组件 - {{count}}</h3>
  </div>
</template>
<script setup>
import { defineProps} from 'vue'
var {count} = defineProps({----defineProps接收值,并且defineProps中的数据是只读的值( 不能直接修改 )    
        count: Number,
    })
</script>
<style>
</style>

2.子向父传值

  1.父组件在子组件身上绑定自定义事件并设置回调函数

  2.子组件内部通过defineEmits获取emit方法, 调用emit方法触发事件并传值.

父组件
<template>
  <div class="app">
    <!-- 渲染子组件 -->
    <child @msg="getMsg"/>---在子组件身上绑定自定义事件msy并指定一个回调函数getMsy
  </div>
</template>
<script setup>
import child from './components/child.vue'----导入子组件
let getMsy=(data)=>{
    console.log('从子组件传来的值:',data);
}
</script>
<style>
</style>
子组件
<template>
  <div class="child">
    <h3>child 组件  {{str}} <button @click="haneleClick">传值</button> </h3>
  </div>
</template>
<script setup>
    import {ref} from 'vue'
    import {provide} from 'vue'
    var str = ref("vue3 composition api")
    var emit = defineEmits(['msg']);---获取emit
    var haneleClick = ()=>{
    emit('msg',8888);---触发事件并传值
    }    
</script>
<style>
</style>

3.跨级传值

  1.外层组件通过provide方法传值,

  2.内层组件通过inject方法接收值.

外层组件
<template>
  <div class="app">
    <childx />
  </div>
</template>
<script setup>
    import childx from './components/childx.vue'----导入内层组件
    import {ref} from 'vue'
    provide('money',6666);---传值
</script>
内层组件
<template>
  <div class="c">
    <h3>c组件 - {{money}}</h3>
  </div>
</template>
<script setup>
    import { inject } from "vue";
    var money = inject('money')---接收值
</script>

4.兄弟组件传值

  1.先实例化一个公共的通信对象(mitt),

  2.其中一个组件提前在mounted中用on监听事件并设置一个回调函数,

  3.另外一个兄弟组件通过emit去触发事件并传值.

与vue2兄弟组件传值一致

兄组件:传递值
<template>
  <div class="childa">
    <h3>childa组件</h3>
    <button @click="handleClick">传值给b组件</button>
  </div>
</template>
<script>
import mitt from '../utils/eventbus'---------导入通信对象
export default {
    methods:{
      handleClick(){
        mitt.emit('trandferdata','我喜欢你!')-------mitt.emit触发事件并传值
      }
    }
}
</script>
<style>
</style>
公共的通信对象
前提:下载mitt(npm i mitt)

import mitt from 'mitt'
export default mitt()----实例化 通信对象 并导出
弟组件:接收值
<template>
  <div class="childb">
    <h3>childb组件</h3>
  </div>
</template>
<script>
import mitt from '../utils/eventbus'---------导入通信对象
export default {
  methods:{
    getdata(data){
      console.log('接收到a组件传来的值:',data);
    }
  },
  mounted(){
    mitt.on('trandferdata',this.getdata)--------监听事件并设置一个回调函数
  },
  beforeUnmount(){
    mitt.off('trandferdata',this.getdata)-------防止内存泄漏取消监听
  }
}
</script>
<style>
</style>

三、使用ref

1.获取dom节点

  1.在标签身上定义一个ref属性,

  2.在组件实例化时定义一个ref变量 变量的名称必须和标签身上的ref属性值相同

  3.在组件挂载完成后就可以通过ref变量获取标签的dom节点

<template>
  <div class="app">
    <input ref="inputbox" type="text" placeholder="搜索商品">---标签身上定义一个ref属性
  </div>
</template>
<script setup>
import {onBeforeMount, onMounted,ref} from 'vue'
var inputbox = ref(null)---定义一个ref变量 变量的名称必须和标签身上的ref属性值相同
onBeforeMount(()=>{
    console.log('onBeforeMount 挂载前');
  })
onMounted(()=>{
console.log('onMounted 挂载完成');
console.log( inputbox.value );
})
</script>

2.获取子组件实例

  1.子组件身上定义一个ref属性

  2.在组件实例化时定义一个ref变量 变量的名称必须和标签身上的ref属性值相同

  3.在组件挂载完成后就可以通过ref变量获取子组件的实例

注意: 子组件内部必须使用defineExpose暴露对应的方法, 父组件才可以获取子组件的实例并调用子组件的方法

父组件
<template>
  <div class="app">
    <Dialog ref="dialogcom" />---子组件身上定义一个ref属性
  </div>
</template>
<script setup>
import {onBeforeMount, onMounted,ref} from 'vue'
import Dialog from './components/Dialog.vue'----导入子组件
var dialogcom = ref(null)----定义一个ref变量 变量的名称必须和标签身上的ref属性值相同
onBeforeMount(()=>{
    console.log('onBeforeMount 挂载前');
  })
onMounted(()=>{
console.log('onMounted 挂载完成');
console.log( dialogcom.value );----获取到子组件的实例,但是并不能使用子组件的数据或者方法,因为子组件的方法的方法被私有化,使用前需要子组件内部先暴露
})
</script>


子组件 :在子组件中, 所有的状态变量, 方法 都被私有化了, 其他组件想要调用子组件的方法, 子组件内部必须暴露对应的方法.
<script setup>
    import { ref,defineExpose } from "vue";
    var isvisiable = ref(false);
    var show = ()=>{
        console.log('show');
        isvisiable.value = true;
    }
    var hide = ()=>{
        isvisiable.value = false;
    }
    defineExpose({----对外暴露一些方法
        show
    })
</script>

四、pinia

Pinia 是 Vue 的专属状态管理库,允许跨组件或页面共享状态。目的是设计一个拥有组合式 API 的 Vue 状态管理库。

步骤:

  1.defineStore() 定义一个数据模块( 负责管理一部分数据 )

    参数一: 模块名

    参数二: 回调函数, 回调函数当中的代码决定了该模块管理了哪些数据, 以及如何管理这些数据

  2.实例化数据模块并导出

  3.暴露模块内的数据和方法

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'---------1.定义一个数据模块
export const usetlStore = defineStore('tl', () => {------2.实例化usetlStore并导出  
  定义状态
  var tasklist = ref([]);  
  定义计算方法
  var totalCount = computed(()=>{
    return tasklist.value.length;
  })
  var finishedCount = computed(()=>{
    return tasklist.value.filter(item=>item.status).length;
  })
  var unfinishedCount = computed(()=>{
    return tasklist.value.filter(item=>!item.status).length;
  })
  var addTask = (name)=>{---------------------新增任务
    //1.构造一个新的任务对象
    var obj = { id: tasklist.value.length+1 ,name ,status:false };
    //2.添加任务对象到任务列表中
    tasklist.value.push(obj);
  }
  var changeTaskStatus = (id)=>{--------------更改任务状态
    //1.查找id对应的任务
    var task = tasklist.value.find(item=>item.id == id);   
    //2.更改找到的任务对象的状态
    if( task ){
      task.status = !task.status;
    }
  }
  var deleteTask = (id)=>{--------------------删除任务
    //1.查找id对应的任务
    var i = tasklist.value.findIndex(item=>item.id == id);    
    //2.删除对应的任务
    if( i != -1 ){
      tasklist.value.splice(i,1);
    }
  }
 3.暴露模块内的数据和方法
  return {
    tasklist,
    totalCount,
    finishedCount,
    unfinishedCount,
    addTask,
    changeTaskStatus,
    deleteTask
  }
  
})

五、路由

步骤:

  1.导入userRouterimport { useRouter } from 'vue-router'

  2.实例化router:var router = useRouter()

<template>
  <div class="tasklist">
    <!-- 动态渲染任务列表( 从tl模块 ) -->
    <div class="task" v-for="(item,index) in tl.tasklist" :key="index">
        <div class="left">
            <input type="checkbox" :checked="item.status" @click="handleClick(item.id)">
            <span>{{item.name}}</span>
        </div>
        <span @click="handleReview(item.id)">查看</span>
        <span @click="handleDelete(item.id)">删除</span>
    </div>   
  </div>
</template>
<script setup>
import { usetlStore } from '../stores/tl'---导入usetlStore
import { useRouter } from 'vue-router' ------------------1.导入tl模块
var tl = usetlStore();------实例化tl模块
var router = useRouter()---------------------------------2.实例化router
var handleClick = (id)=>{
    tl.changeTaskStatus( id );-----更改任务状态
};
var handleReview = (id)=>{
   router.push({ path:'/detail',query:{id} });----------3.跳路由到详情页
};
var handleDelete = (id)=>{
    tl.deleteTask(id);---------删除任务
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3引入了一些新的生命周期函数,并且对一些旧的生命周期函数进行了调整和重命名。下面是Vue 3中常用的生命周期函数及其使用方法: 1. `beforeCreate`:在实例初始化之后,数据观测和事件配置之前被调用。在这个阶段,实例的属性和方法还未被初始化。 ```javascript beforeCreate() { // 在这里无法访问到 data、methods 等属性 } ``` 2. `created`:实例创建完成后被调用。在这个阶段,可以访问到 data、methods 等属性。 ```javascript created() { // 可以访问到 data、methods 等属性 } ``` 3. `beforeMount`:在挂载开始之前被调用。在这个阶段,模板编译已完成,但尚未将挂载的元素替换为实例的模板。 ```javascript beforeMount() { // 模板已编译完成,但尚未挂载 } ``` 4. `mounted`:在挂载完成后被调用。在这个阶段,实例已经挂载到DOM上,可以访问到DOM节点。 ```javascript mounted() { // 实例已经挂载到DOM上 } ``` 5. `beforeUpdate`:在数据更新之前被调用,发生在虚拟DOM重新渲染之前。 ```javascript beforeUpdate() { // 数据更新前的操作 } ``` 6. `updated`:在数据更新完成后被调用,发生在虚拟DOM重新渲染之后。 ```javascript updated() { // 数据更新后的操作 } ``` 7. `beforeUnmount`:在卸载组件之前被调用。 ```javascript beforeUnmount() { // 组件卸载前的操作 } ``` 8. `unmounted`:在卸载组件之后被调用。 ```javascript unmounted() { // 组件卸载后的操作 } ``` 这些是Vue 3中常用的生命周期函数,通过在组件中定义这些函数,可以在不同的阶段执行相应的操作。请注意,在Vue 3中已经移除了一些旧的生命周期函数,比如`beforeDestroy`和`destroyed`,可以使用`beforeUnmount`和`unmounted`来替代。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值