Vue2和Vue3生命周期的区别
- 两变:最直观的是两个名称的改变
Vue2 | Vue3 |
---|---|
beforeDestory | beforeUnmount |
Destoryed | unmounted |
- 两删:
created和beforeCreate
被删掉了,因为有setup了 - 加一个on:其他的都是加上了一个on,比如
mounted---> onMounted
,当然这些加on的也可以用原来的,在这里2.x和3.x是兼容的
注意:3.x里面的生命周期都是组合API,不用像2.x中一样写成option,3.x直接写回调,很爽的!
简称221,还有就是,3.x的生命周期比2.x要快!
自定义hook函数
- 自定义hook的作用类似于vue2中的mixin技术
- 自定义Hook的优势:很清楚复用功能代码的来源,更清楚易懂
获取鼠标位置
- 举个例子:用户在页面中点击页面,把点击得位置得横纵坐标收集起来并展示出来(我们写成一个hook)
我们写一个hookuseMousePosition.ts
/*
* @Author: 41
* @Date: 2021-12-15 20:49:45
* @LastEditors: 41
* @LastEditTime: 2021-12-15 21:00:01
* @Description:
*/
import { onBeforeUnmount, onMounted, ref} from 'vue'
export default ():any=>{
const x=ref(-1)
const y=ref(-1)
const clickHandler= (event:MouseEvent)=>{
x.value=event.pageX
y.value=event.pageY
}
onMounted(()=>{
window.addEventListener('click',clickHandler)
})
onBeforeUnmount(()=>{
window.removeEventListener('click',clickHandler)
})
return {
x,
y
}
}
- 然后在需要用的时候直接引入就好了
<!--
* @Author: 41
* @Date: 2021-12-07 17:12:43
* @LastEditors: 41
* @LastEditTime: 2021-12-15 20:54:21
* @Description:
-->
<template>
<h2>自定义hook</h2>
<h2>x:{{x}},y:{{y}}</h2>
</template>
<script lang="ts">
import {defineComponent} from 'vue'
import useMousePosition from './hooks/useMousePosition'
export default defineComponent({
name:'App',
// 需求1:用户在页面中点击页面,把点击得位置得横纵坐标收集起来并展示出来
setup(){
const {x,y}=useMousePosition()
return {
x,
y
}
}
})
</script>
封装axios的hook
- 准备数据如下:
// a.json
{
"id":1,
"address":"华为手机30",
"distance":"1000m"
}
// b.json
[
{
"id":"001",
"title":"华为手机30",
"price":3219
},
{
"id":"002",
"title":"小米手机30",
"price":1982
}
]
- < T>根据数据改变参数类型,但不能是null 取的时候也要是泛型
- 我们先写一个useRequest.ts的hook如下
/*
* @Author: 41
* @Date: 2021-12-15 21:08:35
* @LastEditors: 41
* @LastEditTime: 2021-12-15 22:25:52
* @Description:
*/
// 引入axios
import {ref} from 'vue'
import axios from 'axios'
export default function <T>(url:string){
const loading=ref(true)
const data=ref<T|null>(null)
const errorMsg=ref('')
axios.get(url).then(response=>{
loading.value=false
data.value=response.data
}).catch(error=>{
loading.value=false
errorMsg.value=error.message || '未知错误'
})
return {
loading,
data,
errorMsg
}
}
- 在父组件使用,注意,对象和数组的使用方法不一样
<!--
* @Author: 41
* @Date: 2021-12-07 17:12:43
* @LastEditors: 41
* @LastEditTime: 2021-12-15 22:24:19
* @Description:
-->
<template>
<h2>自定义hook</h2>
<h2>x:{{x}},y:{{y}}</h2>
<h3 v-if="loading">正在加载中...</h3>
<h3 v-else-if="errorMsg">错误信息:{{errorMsg}}</h3>
<!-- 这里查询结果是对象 -->
<ul v-else>
<li>id:{{data.id}}</li>
<li>address:{{data.address}}</li>
<li>distance:{{data.distance}}</li>
</ul>
<!-- 查询结果是数组 -->
<ul v-for="item in data" :key="item.id">
<li>id:{{item.id}}</li>
<li>address:{{item.title}}</li>
<li>distance:{{item.price}}</li>
</ul>
</template>
<script lang="ts">
import {defineComponent} from 'vue'
import useMousePosition from './hooks/useMousePosition'
import useRequest from './hooks/useRequest'
export default defineComponent({
name:'App',
// 需求1:用户在页面中点击页面,把点击得位置得横纵坐标收集起来并展示出来
setup(){
const {x,y}=useMousePosition()
// const {loading,data,errorMsg}=useRequest('/data/a.json')
const {loading,data,errorMsg}=useRequest('/data/b.json')
return {
x,
y,
loading,
data,
errorMsg
}
}
})
</script>
如果我们要加一个监听呢?
- 在setup中加一个监听,会有报错!
watch(data,()=>{
if(data.value){
console.log(data.value.length);
}
})
我们在使用hook请求的时候,要指定接口的数据类型
interface ProdictsData{
id:string;
title:string;
price:number;
}
const {loading,data,errorMsg}=useRequest<ProdictsData[]>('/data/b.json')
这样就可以了
完整代码如下:
<!--
* @Author: 41
* @Date: 2021-12-07 17:12:43
* @LastEditors: 41
* @LastEditTime: 2021-12-15 22:40:03
* @Description:
-->
<template>
<h2>自定义hook</h2>
<h2>x:{{x}},y:{{y}}</h2>
<h3 v-if="loading">正在加载中...</h3>
<h3 v-else-if="errorMsg">错误信息:{{errorMsg}}</h3>
<!-- 这里查询结果是对象 -->
<ul v-else>
<li>id:{{data.id}}</li>
<li>address:{{data.address}}</li>
<li>distance:{{data.distance}}</li>
</ul>
<!-- 查询结果是数组 -->
<ul v-for="item in data" :key="item.id">
<li>id:{{item.id}}</li>
<li>address:{{item.title}}</li>
<li>distance:{{item.price}}</li>
</ul>
</template>
<script lang="ts">
import {defineComponent, watch} from 'vue'
import useMousePosition from './hooks/useMousePosition'
import useRequest from './hooks/useRequest'
// 定义接口,约束对象的类型
interface IAddressData{
id:number;
address:string;
distance:string;
}
interface ProdictsData{
id:string;
title:string;
price:number;
}
export default defineComponent({
name:'App',
// 需求1:用户在页面中点击页面,把点击得位置得横纵坐标收集起来并展示出来
setup(){
const {x,y}=useMousePosition()
// const {loading,data,errorMsg}=useRequest('/data/a.json')
const {loading,data,errorMsg}=useRequest<ProdictsData[]>('/data/b.json')
watch(data,()=>{
if(data.value){
console.log(data.value.length);
}
})
return {
x,
y,
loading,
data,
errorMsg
}
}
})
</script>