Vue3 ~

2023-09-19 00:01:13

变动

  • 实例
const app = new Vue({})
Vue.use()
Vue.mixin()
Vue.component()
Vue.directive()
const app = Vue.createApp({})
app.use()
app.mixin()
app.component()
app.directive()
  • createApp 代替 new Vue

在这里插入图片描述

  • 允许多个根标签

在这里插入图片描述

  • createStore 代替 Vue.use(Vuex)

在这里插入图片描述

  • createRouter 代替 Vue.use(VueRouter)

在这里插入图片描述

  • 动画
 - v-enter --- v-enter-from
 - v-leave-to  --- vl-eave-to 
 - v-leave  ---  v-leave-from
 - v-enter-to  --- v-enter-to
  • 移除过滤器 filter、keyCode、v-on.native

新特性

  • 组合式 API :定义的数据和使用一并进行处理,达到易读,更便捷、更好的代码组织效果
  • **** options api 对应 react class component
  • **** composition api 对应 react hooks,setup 只会调用一次,hooks 可多次调用
  • 响应式变更:使用 Proxy 代替 Object.defineProperty
  • 全新的全家桶:vue-router、vuex、pinia 等周边库更新
  • TypeScript 支持
  • Vite 支持:依赖于 es module 导致无法直接对 commonJS 的模块化方式进行支持。必须采用依赖预构建

setup

  • options api 中的 data methods computed… 可以发访问setup中的属性和方法
  • setup中不能访问options api中的 data methods computed…
  • 返回一个对象或渲染函数(render 函数)、两个参数:props:参数、context:上下文( attrs, slots, emit )
setup(props, { attrs, slots, emit }) {
	return {}
}
  • thisundefined ,通过 getCurrentInstance 获取实例
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()

生命周期

  • beforeDestroy —> beforeUnmount
  • destroyed —> unmounted
  • setup 等于 beforeCreate 和 created
import {
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from 'vue'

ref、reactive

  • reference对象:创建一个包含响应式的引用对象,接受类型可以是基本类型,也可以是对象类型,除了 template 和reactive,需通过.value修改其值;
  • 响应式实现:基本类型依赖于Object.defineProperty,对象依赖于proxy
<template>
  <p ref="elemRef">文字</p>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const elemRef = ref(null)
onMounted(() => {
  console.log(elemRef.value)
})
</script>
  • reactive:定义一个引用类型响应式数据,不能使用基本类型,解构 reactive 的值会失去响应式
import { ref, reactive } from 'vue'
const nameRef = ref('张三')
const state = reactive({
  name: nameRef
})
</script>

toRef、toRefs

  • toRef:针对一个响应式对象(reactive封装)的属性,创建一个ref类型并且两者保持引用关系;
<script setup>
import { toRef, reactive } from 'vue'
const state = reactive({
  age: 20,
  name: '张三'
})
const ageRef = toRef(state, 'age')
</script>
  • toRefs:将响应式对象(reactive封装)转换为普通对象,对象中的每个属性都是ref,两者保持引用关系
<script setup>
import { toRefs, reactive } from 'vue'
function useFeatureX() {
  const state = reactive({
    x: 1,
    y: 2
  })
  return toRefs(state)
}
const { x, y } = useFeatureX()
</script>

emits

  • 自定义事件需要进行声明
<HelloWorld @onSayHello="sayHello" />
export default {
  emits: ['onSayHello'],
  setup(props, { emit }) {
    emit('onSayHello', '内容')
  }
}
  • 多事件
<button @click="one($event) two($event)">click</button>

watch、watchEffect

  • watch:监听值、处理函数、配置项
  • ref 类型 newValue, oldValue 不需要 .value
  • 引用类型数据设置深度监视无法正确的获取 oldValue
  • reactive 使用函数形式
import { watch } from 'vue'

watch(
  data, // 监听一个基本类型
  // [data1,data2], // 监听多个 ref 基本属性
  // objdata, // ref 引用类型
  (newValue, oldValue) => {},
  { immediate: true } // 初始化监听
)

watch(
  () => obj.xx, // 监听一个 reactive
  // [ () => obj1.xx, () => obj2.xx ], // 监听多个 reactive
  (newValue, oldValue) => {},
  // { immediate: true , deep: true} // 引用类型设置深度监视
)
  • watchEffect:不用指明监视属性,回调中用到什么属性即监视什么属性,默认开启 immediate:true
import { watchEffect } from 'vue'
watchEffect(() => {
  // ...
})

v-model 自定义

  • 父组件
<my-input v-model="val" />
const val = ref('hello')
  • 子组件
props: {
  modelValue: String
},
const handler = (e: Event) => {
  const targetValue = (e.target as HTMLInputElement).value
  context.emit('update:modelValue', targetValue) // 相当于自定义modal $emit
}

.sync

  • vue2.x
<myComponent v-bind:age.sync="age"></myComponent>
  • vue3.x
<template>
  <p>{{ age }}</p>
  <user-info v-model:ageRef="age"></user-info>
</template>

<script>
import { reactive, toRefs } from 'vue'
import UserInfo from './UserInfo.vue'

export default {
  name: 'VModel',
  components: { UserInfo },
  setup() {
    const state = reactive({
      age: '20'
    })
    return toRefs(state)
  }
}
</script>
<template>
  <input :value="ageRef" @input="$emit('update:ageRef', $event.target.value)" />
</template>

<script>
export default {
  name: 'UserInfo',
  props: {
    ageRef: String
  }
}
</script>

异步组件

vue2.x

components:{
	'my-component':() => import('./xx.vue')
}

vue3.x

import { defineAsyncComponent } from 'vue'
components:{
	AsyncComponent: defineAsyncComponent(() => import('./xx.vue'))
}

Teleport

直接将元素插入到某个节点之中

<teleport to="body">
	...
</teleport>

Suspense

用于实现异步,组件内部有两个插槽。

<Suspense>
	<template>
		<AsyncComponent/>
	</template>
	<template #fallback>
		<span>loading...</span>
	</template>
</Suspense>

Vue3.3

  • defineModel

before:

// 1
defineProps({
  modelValue: {
    type: Number,
    required: true,
    default: 0
  }
})
// 2
defineProps(['modelValue']) 

now:

const modelValue = defineModel<number>({ default: 0 })
  • defineEmits

before:

const emits = defineEmits<
  SE<{
    clickCount(num: number): void
  }>
>()
const emits = defineEmits<{
  (e: 'clickCount', num: number): void
}>()

now:

const emits = defineEmits<{
  clickCount: [num: number]
}>()

Vue3为何更快

  • Proxy 响应式
  • PatchFlag:编译模板时动态节点会做标记,标记分为不同类型,diff 算法可以区分静态节点以及不同类型的动态节点;
<div>
  <span>hello</span>
  <span>{{ name }}</span>
  <span :class="blue">张三</span>
  <span :id="zhangsan">张三</span>
  <span :id="lisi" :class="black">{{ obj.name }}</span>
</div>
import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("div", null, [
    _createElementVNode("span", null, "hello"),
    _createElementVNode("span", null, _toDisplayString(_ctx.name), 1 /* TEXT */),
    _createElementVNode("span", {
      class: _normalizeClass(_ctx.blue)
    }, "张三", 2 /* CLASS */),
    _createElementVNode("span", { id: _ctx.zhangsan }, "张三", 8 /* PROPS */, ["id"]),
    _createElementVNode("span", {
      id: _ctx.lisi,
      class: _normalizeClass(_ctx.black)
    }, _toDisplayString(_ctx.obj.name), 11 /* TEXT, CLASS, PROPS */, ["id"])
  ]))
}

以上TEXT 、PROPS 、CLASS 则为标记的不同类型,只会去比较有标记的区域,静态则不会进行对比。

在这里插入图片描述

  • hoistStatic:静态节点的定义提升到父作用域进行缓存,多个相邻的静态节点会被合并起来,拿空间换时间;
  • cacheHandler:缓存事件
  • SSR 优化
  • tree-shaking:模板编译会根据不同情况引入不同的API
更多推荐

网页游戏如何开发网页游戏类型有哪些?

随着互联网的普及和技术的发展,网页游戏已经成为娱乐和休闲活动的重要组成部分。无需安装任何应用程序,只需打开浏览器,您就可以畅玩各种类型的网页游戏。然而,开发网页游戏并不是一项容易的任务,因为不同类型的游戏需要不同的开发方式和技术。在本文中,我们将探讨一些常见的网页游戏类型以及它们的开发方式。1.休闲游戏开发休闲游戏通常

【B+树索引】索引的使用和注意事项

索引的使用和注意事项一、索引的注意事项根节点是不会变的!内节点中目录项记录的唯一性一个页面至少容纳两条记录二、回表的代价三、更好的使用索引四、索引的代价一、索引的注意事项上一篇【B+树索引】索引页的结构含有可以快速查询的秘密从索引页的角度认识了MySQL为了提升查询速率,使用了B+树的数据结构对索引页进行了内存存储。以

【2023华为杯B题】DFT类矩阵的整数分解逼近(思路及代码下载)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2详细数学模型及题目、数据🎉3参考文献🌈4Matlab代码及思路实现💥1概述离散傅里叶变换(Discre

爬虫逆向实战(34)-某视综数据(MD5、AES)

一、数据接口分析主页地址:某视综1、抓包通过抓包可以发现数据接口是/rank/waiting/fans2、判断是否有加密参数请求参数是否加密?通过查看“载荷”模块可以发现有一个sign参数请求头是否加密?无响应是否加密?通过查看“响应”模块可以发现数据是加密的cookie是否加密?无二、加密位置定位1、sign(1)看

c++八股day3-c++什么时候生成默认拷贝构造函数

背景:如果不提供,就是浅拷贝,即位拷贝(把值按字节复制过去)位拷贝的危害:1、比如某个类的对象当中有堆上的资源(里面有一个指针指向了堆上的资源)2、文件句柄、socket3、虚函数表指针可能会丢失。。。如果是位拷贝,就会出现两个对象持有相同的堆上资源、文件句柄如果有一个对象释放,释放时会把堆上资源进行释放,把文件句柄进

App测试中ios和Android有哪些区别呢?

App测试中,大家最常问到的问题就是:ios和Android有什么区别呢?在Android端,我们经常会使用JavaScript、HTML、CSS等技术来编写一些简单的UI界面。而iOS端,我们经常会使用到UI设计、界面布局、代码结构、API等技术来开发一款App。那究竟有什么区别呢?作为一名开发者,应该了解一些基础知

JVM——4.垃圾回收

这篇文章我没来讲一下JVM中的垃圾回收。这是比较重要,内容也比较多的一篇文章。目录1.垃圾回收概述2.如何判断对象可以回收2.1引用计数法2.2可达性分析算法2.2.1GCRoot的选取2.3再谈引用2.3.1强引用2.3.2软引用2.3.3弱引用2.3.4虚引用2.3.5终结器引用2.3.6引用小结3.垃圾回收算法3

uniapp——实现二维码生成+保存二维码图片——基础积累

最近在做二维码推广功能,自从2020年下半年到今天,大概有三年没有用过uniapp了,而且我之前用uniapp开发的程序还比较少,因此很多功能都浪费了很多时间去查资料,现在把功能记录一下。这里写目录标题效果图1.根据接口返回的链接生成二维码——`uv-Qrcode`的用法1.1插件市场导入`uv-qrcode`插件1.

优思学院|为什么六西格玛团队不能忽视DMAIC中的C?【案例分享】

在DMAIC(即Define(定义)、Measure(测量)、Analyze(分析)、Improve(改进)和Control(控制))过程中,控制阶段扮演着至关重要的角色,有助于维护六西格玛项目所带来的改进效益。如果按照正常程序执行,它还有助于进一步提高结果。什么是DMAIC过程?在深入探讨DMAIC控制阶段的重要性之

KVM嵌套虚拟化实现

KVM嵌套虚拟化实现理论Libvirt主要支持三种CPUmodehost-passthrough:libvirt令KVM把宿主机的CPU指令集全部透传给虚拟机。因此虚拟机能够最大限度的使用宿主机CPU指令集,故性能是最好的。但是在热迁移时,它要求目的节点的CPU和源节点的一致。host-model:libvirt根据当

【建造者模式】

🏅我是默,一个在CSDN分享笔记的博主。📚📚🌟在这里,我要推荐给大家我的专栏《20种Java设计模式》。🎯🎯🚀无论你是编程小白,还是有一定基础的程序员,这个专栏都能满足你的需求。我会用最简单易懂的语言,带你走进Java的世界,让你从零开始,一步步成为JAVA大师。🚀🏆🌈让我们在Java的世界里畅游吧

热文推荐