标签:Vue 哪些 看看 Vue3.0 API context 组件 ref setup
2020年10月,Vue 3.0终于发布了第一个beta版本,这个大版本更新相较于2.0的推出已经过去两三年了,在前端开发这个快速迭代的大环境下,这么长时间才更新一个大版本挺少见的。但是我得说,虽然三年没有更新大版本,但尤雨溪这三年可真没闲着,三年不开张,一开张就来了个大招。Vue3.0是一套组合拳,它带来的变化全面而繁杂。接下来的2021年,使用Vue2.0的小伙伴们又有新东西要学习了。
那么今天我们就来梳理一下,看看Vue3.0到底有哪些值得关注的改变。
一、Vue生态环境变化。
我们先从Vue的整个生态说起,除了Vue核心库,Vue周边配套也全都来了个大升级,VueRouter,Vuex都升级到了4.0,构建工具也有更新,尤大大自己开发了一个专门的构建工具,叫Vite。这个构建工具尤其值得一说,我认为它弄不好会是webpack的终结者。我们来看看作者的介绍:“Vite,一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个概念,服务器随起随用。同时不仅有 Vue 文件支持,还搞定了热更新,而且热更新的速度不会随着模块增多而变慢。针对生产环境则可以把同一份代码用 rollup 打包。虽然现在还比较粗糙,但这个方向我觉得是有潜力的,做得好可以彻底解决改一行代码等半天热更新的问题。”
设计目标。
说完生态,我们还是回到Vue核心库,我们最关心的,其实还是这个。先来看下 ** Vue3.0 的6个设计目标:**
-
更小:全局 API 和内置组件 / 功能支持 tree-shaking; 常驻的代码尺寸控制在 10kb gzipped 上下。
-
更快:基于 Proxy 的变动侦测,性能整体优于 getter / setter;Virtual DOM 重构;编译器架构重构,更多的编译时优化。
-
加强 API 设计一致性:3.0的api会更符合人的习惯,更友好
-
加强 TypeScript 支持:3.0 本身用 TypeScript 重写,内置 typing;支持TSX;但是不会影响不使用Typescript的用户。另外还有一件很重要的事情,Class API提案已经撤销了,使用TS开发Vue的小伙伴要注意下了。
-
提高自身可维护性
-
开放更多底层功能
总体的设计目标简单说就是更小更快更友好。。。
二、API变化。
Vue3.0的API变化,总的来说有以下几个需要注意的特点:
-
技能升级曲线平滑。掌握Vue 2的人应该可以很顺利的使用Vue 3
-
不能直接把项目从Vue 2升级到Vue 3,因为很多API细节有破坏性修改
-
Vue2的组件库不能直接给Vue3使用
-
浏览器兼容方面,只兼容到IE11+。呃,这样也好,希望能对IE退出历史舞台再出一份力。
-
模板语法的 99% 将保持不变。
-
现有的Options API没有大的变化。
下面我们看下API变化的几个主要方面(API变化很繁杂,此处我们仅列举较常用的API变化):
全局 API 的变化:
Vue 2.x 有许多全局 API 和配置,这些 API 和配置可以全局改变 Vue 的行为。例如,要创建全局组件,可以使用 Vue.component 这样的 API。虽然这种声明方式很方便,但它也会导致一些问题。从技术上讲,Vue 2 没有“app”的概念,我们定义的应用只是通过 new Vue() 创建的根 Vue 实例。从同一个 Vue 构造函数创建的每个根实例 共享相同的全局配置,因此它不利于测试,也不利于在全局多个app之间共享Vue副本。调用 createApp 返回一个应用实例,这是 Vue 3 中的新概念
import { createApp } from 'vue'
const app = createApp({})
任何全局改变 Vue 行为的 API 现在都会移动到
应用实例上,以下是当前全局 API 及其相应实例 API 的表:
2.x 全局 API | 3.x 实例 API ( app ) |
---|---|
Vue.config | app.config |
Vue.config.productionTip | removed |
Vue.config.ignoredElements | app.config.isCustomElement |
Vue.component | app.component |
Vue.directive | app.directive |
Vue.mixin | app.mixin |
Vue.use | app.use |
模板语法变化
-
Vue 3 中,组件现在正式支持多根节点组件
-
v-if 与 v-for 的优先级对比,两者作用于同一个元素上时, v-if 会拥有比 v-for 更高的优先级
-
过滤器。过滤器已删除,不再支持。建议用方法调用或计算属性替换它们
-
按键修饰符,不再支持使用数字 (即键码) 作为 v-on 修饰符,不再支持 config.keyCodes
新增的两个内置组件 Teleport 和 Suspense
Teleport(传入)Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件,从此后某个组件创建的Html将可能不在本组件内。想像一下,你要写一个弹窗组件,而你希望这个弹窗组件的html放在body下,那可以使用Teleport方便地实现它
<template>
<button @click="modalOpen = true">Open full screen modal! (With teleport!)</button>
<teleport to="body">
<div v-if="modalOpen" class="modal">
<div>
I'm a teleported modal! (My parent is "body")<button @click="modalOpen = false">
Close
</button>
</div>
</div>
</teleport>
</template>
<script>
export default {
data() {
return {
modalOpen: false,
};
},
};
</script>
Suspense
Suspense含义:悬念; 悬而未决,含糊不定; 焦虑,挂念; 中止,暂停,悬停
它是从React借鉴过来的一个概念,Suspense主要解决的就是网络IO问题。网络IO问题其实就是我们现在用Redux+saga等等一系列乱七八糟的库来解决的「副作用」问题。现在Vue3.0实现了Suspense组件,我们可以用它来处理一些异步问题。比如,我们可以用它来处理异步组件的加载状态显示。看下边的例子
<template>
<div id="app">
<div v-if="error">{{ error }}</div>
<Suspense v-else>
<template #default>
<User />
</template>
<template #fallback> Loading... </template>
</Suspense>
</div>
</template>
<script>
import User from '@/components/User.vue';
import { one rrorCaptured, ref } from 'vue';
export default {
components: {
User,
},
setup() {
const error = ref(null);
one rrorCaptured((e) => {
error.value = e;
// 不对错误进行拦截
return true;
});
return { error };
},
};
</script>
三、新增的Composition API
我认为Vue3.0核心库变化最大的就是这个Composition API了。它翻译为组合API,组合API是相对于Vue2.x的选项API而言的。
Composition API的设计目的,是为了更好的实现组件间的代码复用。在Vue中,实现页面中代码复用的工具是组件,但用了组件后,你会发现组件间其实也有大量的代码是重复的(比如多个组件都需要相同的权限校验逻辑),需要抽离出来做个封装以便复用。在Vue2.x中,官方给出的解决方案就是Mixins,但Mixins也有很多缺点,比如当你在组件中调用了Mixins中的方法时,你不容易找到这个方法的来源。因此在Vue3.0中,官方给出了一个全新的解决方案,就是Composition API。它最主要的特点是使用功能来组织代码,而不是以选项来组织代码,使用它可以让我们方便的把一个功能相关的所有代码(包括data、methods、computed、watch、生命周期函数等)封装在一个类文件中。
那么接下来我们来看一下,如何把原来选项api中的所有内容,写在一个功能文件中。 Composition API使用起来也并不复杂,你只需要注意以下几个部分:
setup 组件选项,一个可以实际使用Composition API的地方,关于它你只需知道以下三点:
-
它实际上是Vue一个新的生命周期函数,在beforeCreate和created之间执行。
-
在setup中this无法使用。由于在执行 setup 时尚未创建组件实例,因此在 setup 选项中没有 this 。这意味着, 除了 props 之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。
-
可以使用setup函数的两个参数props, context来替代this的使用。
export default {
props: {
msg: {
type: String,
default: () => { }
}
},
setup(props, context) {
console.log(props) // 此处返回props定义的属性
// setup()的第二个参数是一个上下文对象,这个上下文对象大致包含了这些属性
context.attrs
context.slots
context.parent
context.root
context.emit
context.refs
// Attribute (非响应式对象)
console.log(context.attrs)
// 插槽 (非响应式对象)
console.log(context.slots)
// 触发事件 (方法)
console.log(context.emit)
}
}
响应式变量 ref 或 reactive
reactive是用来创建一个响应式对象,等价于2.x的Vue.observable,
ref()函数用来给定的值创建一个响应式的数据对象,ref()的返回值是一个对象,这个对象上只包含一个.value属性。看下边创建一个响应式数据的例子:
import { ref } from 'vue';
export default {
setup () {
const value = ref(1);
return {
value,
msg: 'hello world!'
};
}
};
<template>
<p>
{{ value }} {{ msg }}
</p>
</template>
watch 响应式更改
就像我们如何使用 watch 选项在组件内的 user property 上设置侦听器一样,我们也可以 使用从 Vue 导入的 watch 函数执行相同的操作。它接受 3 个参数:
-
一个响应式引用或我们想要侦听的 getter 函数
-
一个回调
-
可选的配置选项
下面是一个例子
import { ref, watch } from 'vue'
const counter = ref(0)
watch(counter, (newValue, oldValue) => {
console.log('The new counter value is: ' + counter.value)
})
与 ref 和 watch 类似,也可以使用从 Vue 导入的 computed 函数在 Vue 组件外部创建计算属性。
生命周期钩子
你可以通过在生命周期钩子前面加上 “on” 来访问组件的生命周期钩子。
下表包含如何在 setup () 内部调用生命周期钩子:
选项 API | Hook inside setup |
---|---|
beforeCreate | Not needed |
created | Not needed |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。
这些函数接受一个回调函数,当钩子被组件调用时将会被执行:
export default {
setup() {
// mounted
onMounted(() => {
console.log('Component is mounted!')
})
}
}
标签:Vue,哪些,看看,Vue3.0,API,context,组件,ref,setup 来源: https://blog.csdn.net/weixin_52911883/article/details/111600713
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。