一、组件内的 data 为什么总是函数形式?

我们试着先做一个计数器案例,把 data 的返回形式修改成一个对象。具体的代码如下:

<template>
<div>
<button @click="num++">+</button>
{{num}}
<button @click="num--">-</button>
</div>
</template>
<script>
const retData = {
num:0
}
export default {
data(){
return retData
}
}
</script>

运行结果,看着是正常的,并无异常。但我们都知道,vue 项目中,之所以采用组件形式,就是为了重复多次使用,所以我们多次使用我们的组件试试。

神奇的效果发生了,当我们改变第一个组件的数值时,第二个组件的数据也被修改。修改第二个组件的时候,第一个组件的数据也同步更新。

原因:同一个组件被复用多次,会创建多个实例,如果data是一个对象的话,这些实例用的是同一个构造函数,指针指向的就会是同一个地方,就导致了两个组件的数据会同时更新。

为了保证组件内的数据各自独立,不会相互影响,要求每个组件的data必须是函数形式,目的就是把数据放入一个新对象内,这样就不会出现上述问题了。

说这的主要意义就是告诉我们,在 Vue3.x 中的 data 选项总是为函数形式,返回响应式数据。

Vue2.x VS Vue3.x 实例创建

二、函数式组件的变化

在Vue3.x中,functional:true 组件选项被移除。vue3.x 不推荐使用函数式组件。

有些小伙伴就会惊叹,妈呀,俺都不知道函数式组件是啥,你说得再简单我也不懂呐,所以就讲讲函数式组件干啥的,原来的 functional 属性放哪?

2.1、在Vue2.x中的函数式组件:

函数式组件也是组件的一种类型,主要用来定义那些没有响应数据,也不需要任何生命周期钩子函数,只 props 来接收传递来的数据。

类型1:基于模板的函数式组件

<template functional >
<div>
函数式组件内容
</div>
</template>

类型2:组件注册

Vue.componenet('fun-comp':{
functional:true,
props:{
msg:{
type:String,
default:'组件数据'
}
},
render:(h,context)=>{
return h('div',['组件内容','++',context.props.msg])
}
})

类型3:中间件实现 render 方法

// FunComps.js 文件代码
export default {
functional:true,
props:{
render:{
type:Function
},
params:{}
},
render:(h,ctx)=>{
return ctx.props.render(h,ctx.props.params)
}
} //组件调用
<fun-comp :render="renderHandle" :params="['111','222']" />

renderHandle 这个函数,在外层可以任意控制,这样不但节省开销,而且复用性也很高。

2.2、在Vue3.x中的函数式组件:

在 SFC 中不能使用 functional 特性声明是函数式组件,移除了 functional:true 特性。

// 新建一个 FunComp.vue 文件
<script>
import { h } from "vue"
function Footer(props,context){
return h(`h${props.level}`,context.attrs , context.slots )
}
Footer.props = ['level']
export default Footer
</script> //使用函数式组件
<template>
<FunComp level="1.0.0" >Vue3.x函数式组件内容</FunComp>
</template>
<script >
import FunComp from '../../components/FunComp.vue'
export default{
component:{
FunComp
},
}
</script>

这下应该清楚到底移除的属性在哪了!接着看看异步组件有什么改变。。。

三、异步组件的变化

Vue3.x 异步组件要求使用 defineAsyncComponent 方法创建。

由于 Vue3 中函数式组件必须定义为纯函数,所以异步组件有如下变化:

  1. 必须明确地使用 defineAsyncComponent 方法包裹
  2. component 选项已经被重命名为 loader
  3. loader 函数不再接收 resolve 和 reject 回调方法 。且必须返回一个 Promise 对象 。

3.1、不带配置的异步组件对比

在 Vue2.x中异步组件使用:

{
path:'/',
component: ()=> import("@/view/home/index")
}

在 Vue3.x 中异步组件使用:

import { defineAsyncComponent } from 'vue'

{
path:"/",
component:defineAsyncComponent(()=>{ import("@/view/home/index.vue") })
}

3.2、带配置的异步组件

const asyncPageWithOptions = defineAsyncComponent({
loader:()=> import("../view/index/index.vue"),
delay:200,
timeout:3000,
errorComponent:ErrorComponent,
loadingComponent:LoadingComponent
})

loader 选项是以前的 component 选项。

四、自定义组件白名单的变化

Vue3.x中,自定义元素检测发生在模板编译时,如果要添加 vue 之外的自定义元素,需要在编译器选项中设置 isCustomElement 选项。
使用构建工具时,模板都会用 vue-loader 预编译,在 vite.config.js 中配置它提供的 vueCompilerOption 即可:

import { defineConfig,vueCompilerOption } from 'vite'
import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
vueCompilerOptions:{
isCustomElement:tag => tag==='pie-chart'
}
})

此时遇到 pie-chart 元素时,直接跳过,不对其进行编译。

五、动态组件

vue3.x 中设置动态组件时,is 属性只能用于 component 标签上。

使用方法:

<component :is="currentView"></component>
//currentView 是一个表达式

让多个组件使用同一个挂载点,并动态切换组件。

5.1、动态组件的缓存

好多时候多个组件来回切换时,组件的实例都是重新创建的,而我们需要保存它的状态,此时就需要缓存动态组件。

在Vue2.x中:

<keep-alive>
<component :is="currentView"></component>
</keep-alive>

在 Vue3.x中:keep-alive 必须使用在 router-view内部

<router-view>
<keep-alive>
<component :is="currentView"></component>
</keep-alive>
</router-view>

Vue3.x 关于组件的那些变化(新手必看篇)的更多相关文章

  1. 新手必看】Highcharts的100个基础问答

    新手必看]Highcharts的100个基础问答 2014-12-2 10:59| 发布者: Mr.Zhang| 查看: 2749| 评论: 3|来自: Highcharts中文论坛   摘要: 1. ...

  2. k8s新手必看

    转载自https://juejin.im/post/6844903840139968520 Kubernetes零基础快速入门!初学者必看! 起源 Kubernetes 源自于 google 内部的服 ...

  3. 新手必看,老鸟绕道–LAMP简易安装

    导读 LAMP是企业中最常用的服务,也是非常稳定的网站架构平台.其中L-指的是Linux,A-指的是Apache,m-指的是mysql或者marriDB,p-php.相信大家对这些都已经非常熟悉了,但 ...

  4. 120条Photoshop新手必看技巧

    Photoshop越来越强大了!试图掌控它的全部特性是不现实的(更何况有那么多隐藏的功能!),那么我们不妨收藏一下大神们总结的这120个PS技巧,偶尔翻看一下,让自己的设计更强大更高效! 这120款技 ...

  5. 常用Java开源库(新手必看)

    Jakarta common: Commons LoggingJakarta Commons Logging (JCL)提供的是一个日志(Log)接口(interface),同时兼顾轻量级和不依赖于具 ...

  6. iOS-上架APP之启动页设置(新手必看!)

    今天自己做的小作品准备提交,就差一个启动页,各种百度,各种搜,结果还好最后终于出来了,和大家分享一下,这个过程中遇到的各种小问题.(注XCode版本为7.2) 1.启动页一般都是图片,因为苹果有4,4 ...

  7. [转]Web.config配置文件详解(新手必看)

    本文转自:http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.html 花了点时间整理了一下ASP.NET Web.config配 ...

  8. 转:Web.config配置文件详解(新手必看)

    转:http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.html 花了点时间整理了一下ASP.NET Web.config配置文件 ...

  9. Web.config配置文件详解(新手必看)

    花了点时间整理了一下ASP.NET Web.config配置文件的基本使用方法.很适合新手参看,由于Web.config在使用很灵活,可以自定义一些节点.所以这里只介绍一些比较常用的节点. <? ...

随机推荐

  1. html2canvas实现截取指定区域或iframe的区域

    官网文档: http://html2canvas.hertzen.com/ 使用的是 jquery 3.2.1   html2canvas 1.0.0-rc.7 截取根据id的指定区域: var ca ...

  2. dede图片集关联的数据库用表:

    如果在本地的环境中,安装目录不在根目录,搬到外网上的时候,就需要对数据库里的图片路径数据进行字段替换: dede图片集关联的数据库用表:1.dede_addonimages 2.dede_arctin ...

  3. mumu模拟器使用

    连接mumu模拟器 启动mumu模拟器 执行命令:adb connect 127.0.0.1:7555(windows系统推荐使用gitbash) 安装app Gitbash下执行:adb insta ...

  4. P5363-[SDOI2019]移动金币【阶梯博弈,dp,组合数学】

    正题 题目链接:https://www.luogu.com.cn/problem/P5363 题目大意 \(1\times n\)的网格上有\(m\)个硬币,两个人轮流向前移动一个硬币但是不能超过前一 ...

  5. 如何一次性add library to classpath

    前言:导入项目时,时常需要手动导包,提示"add library to classpath",需要一个个找报红的类 点击添加本地项目包

  6. python-matplotlib学习(1)

    1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 x=np.linspace(-1,1,50) 5 y=2*x+1 6 plt.pl ...

  7. Kettle学习笔记(一)— 环境部署及运行

    目录 Kettle学习笔记(一)-环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 Kettle简介 Ket ...

  8. Springboot在有锁的情况下如何正确使用事务

    1. 概述 老话说的好:想要赚钱,就去看看有钱人有什么需求,因为有钱人钱多,所以赚的多. 言归正传,在Java项目的研发中,"锁"这个词并不陌生,最经典的使用场景是商品的超卖问题. ...

  9. JVM学习笔记——堆

    堆 Heap 一个 JVM 只有一个堆,堆也是 Java 内存管理的核心区域.在 JVM 启动时堆被创建,同时大小在启动时已设定好,堆是 JVM 管理最大的一块内存空间,其大小可以调节. 堆的内存空间 ...

  10. Hadoop面试题总结(三)——MapReduce

    1.谈谈Hadoop序列化和反序列化及自定义bean对象实现序列化? 1)序列化和反序列化 (1)序列化就是把内存中的对象,转换成字节序列(或其他数据传输协议)以便于存储(持久化)和网络传输. (2) ...