网站首页 > 技术文章 正文
一、setup函数的特性以及作用
可以确定的是 Vue3.0 是兼容 Vue2.x 版本的 也就是说我们再日常工作中 可以在 Vue3 中使用 Vue2.x 的相关语法 但是当你真正开始使用 Vue3 写项目时 你会发现他比 Vue2.x 方便的多
vue 2.0 生命周期对比 3.0 生命周期
| 2.0 周期名称 | 3.0 周期名称 | 说明 |
| beforeCreate | setup | 组件创建之前 |
| created | setup | 组件创建完成 |
| beforeMount | onBeforeMount | 组件挂载之前 |
| mounted | onMounted | 组件挂载完成 |
| beforeUpdate | onBeforeUpdate | 数据更新,虚拟 DOM 打补丁之前 |
| updated | onUpdated | 数据更新,虚拟 DOM 渲染完成 |
| beforeDestroy | onBeforeUnmount| 组件销毁之前 |
| destroyed | onUnmounted | 组件销毁后 |
Vue3 的一大特性函数 ---- setup
1、
beforeCreate:表示组件刚刚被创建出来,组件的data和methods还没有初始化好
setup
Created:表示组件刚刚被创建出来,并且组件的data和methods已经初始化好
2、setup函数是 Composition API(组合API)的入口
3、在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用
二、setup函数的注意点:
1、由于在执行 setup函数的时候,还没有执行 Created 生命周期方法,所以在 setup 函数中,无法使用 data 和 methods 的变量和方法
2、由于我们不能在 setup函数中使用 data 和 methods,所以 Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined
3、setup函数只能是同步的不能是异步的
用法1:结合ref使用
<template>
<div id="app">
{{name}}
<p>{{age}}</p>
<button @click="plusOne()">+</button>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
name:'app',
data(){
return {
name:'北京'
}
},
setup(){
//名字
const name =ref('小李')
//年纪
const age=ref(18)
// 方法
function plusOne(){
age.value++ //想改变值或获取值 必须.value
}
//必须返回 模板中才能使用
return {
name,age,plusOne
}
}
}
</script>
用法2:代码分割
Options API 和 Composition API
Options API 约定:
我们需要在 props 里面设置接收参数 在setup中没有this
我们需要在 data 里面设置变量
我们需要在 computed 里面设置计算属性
我们需要在 watch 里面设置监听属性
我们需要在 methods 里面设置事件方法
你会发现 Options APi 都约定了我们该在哪个位置做什么事,这反倒在一定程度上也强制我们进行了代码分割。现在用 Composition API,不再这么约定了,于是乎,代码组织非常灵活,我们的控制代码写在 setup 里面即可。
setup函数提供了两个参数 props和context,重要的是在setup函数里没有了this,在 vue3.0 中,访问他们变成以下形式:this.xxx=》context.xxx
我们没有了 this 上下文,没有了 Options API 的强制代码分离。Composition API 给了我们更加广阔的天地,那么我们更加需要慎重自约起来。
对于复杂的逻辑代码,我们要更加重视起 Composition API 的初心,不要吝啬使用 Composition API 来分离代码,用来切割成各种模块导出。
我们期望是这样的:
importuseAfrom'./a'
importuseBfrom'./b'
importuseCfrom'./c'
exportdefault{
setup (props) {
let{ a, methodsA } = useA()
let{ b, methodsB } = useA()
let{ c, methodsC } = useC()
return{ a, methodsA, b, methodsB, c, methodsC }
}
}
3:data() 变为 setUp()
1、生命周期的函数只能写在setUp中
2、provide/inject 只能写在setUp
就算 setup 内容代码量越来越大,但是始终围绕着大而不乱,代码结构清晰的路子前进。
总结:
首先,在 vue 3.0 中,生命周期是从 vue 中导出的,我们需要用到哪些,就导出哪些。
vue 提供这么多的生命周期,有几个是我们常用的?在大多数的组件中,我们用不到生命周期。即便是页面级别的应用,可能用到最多的是 onMounted 即可。
当然,那些绑定时间的操作会用到解绑,因此会用到 onUnmounted。其它的生命周期,正常情况下是基本用不到的。
所以,通过引入使用的这种设定,可以减少我们的最终编译的项目的体积。而且,这样的引入使用,更加的逻辑清晰。
其次,除 setup 之外,其他的生命周期函数,都是在 setup 里面直接书写函数即可。
ref函数
ref 是一个函数,它接受一个参数,返回的就是一个神奇的 响应式对象 。我们初始化的这个 0 作为参数包裹到这个对象中去,在未来可以检测到改变并作出对应的相应。
<template>
<h1>{{count}}</h1>
<h1>{{double}}</h1>
<button @click="increase">+1</button>
</template>
<script lang="ts">
import { computed, ref, reactive, toRefs } from 'vue'
interface DataProps {
count: number
double: number
increase: () => void
}
export default {
name: 'App',
setup() {
const data:DataProps = reactive({
count: 0,
increase: () => { data.count++ },
double: computed(() => data.count * 2)
})
const refData = toRefs(data)
return {
...refData
}
}
}
</script>
reactive函数
reactive函数
import { ref, computed, reactive, toRefs } from 'vue'
interface DataProps {
count: number;
double: number;
increase: () => void;
}
setup() {
const data: DataProps = reactive({
count: 0,
increase: () => { data.count++},
double: computed(() => data.count * 2)
})
const refData = toRefs(data)
return {
...refData
}
}
使用 ref 还是 reactive 可以选择这样的准则
第一,就像刚才的原生 javascript 的代码一样,像你平常写普通的 js 代码选择原始类型和对象类型一样来选> 择是使用 ref 还是 reactive。
第二,所有场景都使用 reactive,但是要记得使用 toRefs 保证 reactive 对象属性保持响应性。
侦测变化 - watch函数
watch文档
<template>
<h1>{{ count }}</h1>
<h1>{{ double }}</h1>
<button @click="increase">+1</button>
<button @click="updateGreeting">updateGreeting</button>
</template>
<script lang="ts">
import { computed, ref, reactive, toRefs, watch } from 'vue'
interface DataProps {
count: number
double: number
increase: () => void
}
export default{
name: 'app',
setup() {
const data: DataProps = reactive({
count: 0,
increase: () => { data.count++ },
double: computed(() => data.count * 2)
})
const greetings = ref('')
const updateGreeting = () => {
greetings.value += 'Hello'
}
watch([greetings, () => data.count ], ( newValue, oldValue ) => {
console.log(newValue)
console.log(oldValue)
document.title += 'updated' + greetings.value
})
const refData = toRefs(data)
return {
...refData,
greetings,
updateGreeting
}
}
}
</script>
watch 简单应用
watch(data, () => {
document.title = 'updated ' + data.count
})
// watch 的两个参数,代表新的值和旧的值
watch(refData.count, (newValue, oldValue) => {
console.log('old', oldValue)
console.log('new', newValue)
document.title = 'updated ' + data.count
})
// watch 多个值,返回的也是多个值的数组
watch([greetings, data], (newValue, oldValue) => {
console.log('old', oldValue)
console.log('new', newValue)
document.title = 'updated' + greetings.value + data.count
})
// 使用 getter 的写法 watch reactive 对象中的一项
watch([greetings, () => data.count], (newValue, oldValue) => {
console.log('old', oldValue)
console.log('new', newValue)
document.title = 'updated' + greetings.value + data.count
})
结尾
人懒,不想配图,望能帮到大家
公众号:小何成长,佛系更文,都是自己曾经踩过的坑或者是学到的东西
有兴趣的小伙伴欢迎关注我哦,我是:何小玍。 大家一起进步鸭
猜你喜欢
- 2024-11-11 eat、have和take表达“吃”有区别吗?
- 2024-11-11 字节二面:谈谈你对JS中的this指向的理解!
- 2024-11-11 你知道JS的“三座大山”吗?带你初识前端JavaScript经典内容
- 2024-11-11 ThreeJS 给全景图片添加标注 threejs 360全景
- 2024-11-11 cheap date可不是“便宜的约会”,这些date你了解吗?
- 2024-11-11 js利用WebSocket链接后端并获取数据的方法
- 2024-11-11 JavaScript 内的 this 指向 js中this指针
- 2024-11-11 丝滑般 Vue 拖拽排序树形表格组件Vue-DragTreeTable
- 2024-11-11 5 年,只为了一个更好的校验框架 农行网银显示此内容不能显示在一个框架中
- 2024-11-11 this 指向问题,全网最全最简单口诀
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-