初识Vue3.0
什么是 Vue?
Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。
本文探讨主题
Vue3与Vue2的对比探讨
- 书写风格:
选项式API
与组合式API
以及setup语法糖
- ref 和 reactive 响应式和非响应式
- 计算属性
- 混入的方法重名问题
- 速度:打包速度、构建速度、vite
一、书写风格
Vue提供两种不同的风格书写:选项式API 与组合式API
选项式API (Options API)示例
选项式Api
是将data
和methods
包括后面的watch
,computed
等分开管理
html
<template>
<div @click="changeMsg">{{msg}}</div>
</template>
<script>
export default {
data(){
return {
msg:'hello world'
}
},
methods:{
changeMsg(){
this.msg = 'hello zte'
}
}
}
</script>
组合式API (Composition API)示例
组合式Api
则是将相关逻辑放到了一起(类似于原生js开发),Vue3推荐语法
组合式 API通常会与
<script setup>
搭配使用。这个setup
attribute 是一个标识,告诉 Vue 需要在编译时进行一些处理,让我们可以更简洁地使用组合式 API。比如<script setup>
中的导入和顶层变量/函数都能够在模板中直接使用。
html
<template>
<div @click="changeMsg">{{ msg }}</div>
</template>
<script setup>
import { ref } from "vue";
const msg = ref('hello world')
const changeMsg = () => {
msg.value = 'hello zte'
}
</script>
setup语法糖
setup语法糖则可以让变量方法不用再写return,后面的组件甚至是自定义指令也可以在我们的template中自动获得。
html
<template>
<div @click="changeMsg">{{ msg }}</div>
</template>
<script setup>
import { ref } from "vue";
const msg = ref('hello world')
const changeMsg = () => {
msg.value = 'hello juejin'
}
</script>
二、ref 和 reactive
在选项式api 中,data函数中的数据都具有响应式,页面会随着data中的数据变化而变化;
而组合式api中不存在data函数该如何呢?所以Vue3则引入了ref
和reactive
函数来使变量成为响应式的数据
响应式:Vue 会自动跟踪 JavaScript 状态并在其发生变化时响应式地更新 DOM。
ref与reactive的区别
对比 | ref | reactive |
---|---|---|
返回数据类型 | RefImpl对象(也叫ref对象) | Proxy对象 |
传入基本类型返回 | {value: 基本类型} | 禁止这么做 |
传入引用类型返回 | {value: Proxy对象} | Proxy对象 |
ref
在组合式 API 中,推荐使用 ref()
函数来声明响应式状态:
js
import { ref } from 'vue'
const count = ref(0)
ref()
接收参数,并将其包裹在一个带有 .value
属性的 ref 对象中返回:
ts
import { ref } from 'vue'
import type { Ref } from 'vue'
// 这里使用TS语言,更加严谨
const year: Ref<string | number> = ref('2023')
year.value = 2023 // 成功!
使用ref的时候在js中取值的时候需要加上
.value
。
如果需要再组件中访问他们就需要用setup()
包裹起来
js
export default {
// `setup` 是一个特殊的钩子,专门用于组合式 API。
setup() {
const count = ref(0)
// 将 ref 暴露给模板
return {
count
}
}
}
html
<div>{{ count }}</div>
为什么要使用 ref?
为什么我们需要使用带有 .value
的 ref,而不是普通的变量?
简单地讨论一下 Vue 的响应式系统是如何工作的。
当你在模板中使用了一个 ref,然后改变了这个 ref 的值时,Vue 会自动检测到这个变化,并且相应地更新 DOM。
这是通过一个基于依赖追踪的响应式系统实现的。当一个组件首次渲染时,Vue 会追踪 在渲染过程中使用的每一个 ref。然后,当一个 ref 被修改时,它会触发追踪它的组件的一次重新渲染。
在标准的 JavaScript 中,检测普通变量的访问或修改是行不通的。
然而,我们可以通过 getter 和 setter 方法来拦截对象属性的 get 和 set 操作。
该 .value
属性给予了 Vue 一个机会来检测 ref 何时被访问或修改。
在其内部,Vue 在它的 getter 中执行追踪,在它的 setter 中执行触发。
从概念上讲,你可以将 ref 看作是一个像这样的
js
// 伪代码,不是真正的实现
const myRef = {
_value: 0,
get value() {
track()
return this._value
},
set value(newValue) {
this._value = newValue
trigger()
}
}
reactive
使用 reactive()
API。与将内部值包装在特殊对象中的 ref 不同,reactive()
将使对象本身具有响应性:
js
import { reactive } from 'vue'
const state = reactive({ count: 0 })
ts
import { reactive } from 'vue'
interface Book {
title: string
year?: number
}
const book: Book = reactive({ title: 'Vue 3 指引' })
在模版中使用
html
<button @click="state.count++">
{{ state.count }}
</button>
响应式对象是 JavaScript Proxy代理
,其行为就和普通对象一样。
不同的是,Vue 能够拦截对响应式对象所有属性的访问和修改,以便进行依赖追踪和触发更新。
注意事项:
解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接。
总结:
reactive
更推荐去定义复杂的数据类型
ref
更推荐定义基本类型
三、计算属性
模板中的表达式虽然方便,但也只能用来做简单的操作。
js
<script setup>
import { reactive, computed } from 'vue'
const author = reactive({
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
})
// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
</script>
<template>
<p>Has published books:</p>
<span>{{ publishedBooksMessage }}</span>
</template>
Vue 的计算属性会自动追踪响应式依赖。它会检测到 publishedBooksMessage
依赖于 author.books
,所以当 author.books
改变时,任何依赖于 publishedBooksMessage
的绑定都会同时更新。
ts
// TS
const double = computed<number>(() => {
// 若返回值不是 number 类型则会报错
})
四、混入重命名解决方法
稍微说一下 vue3 项目中的 hooks 的使用,其实这个 hooks 呢是和 vue2 当中的 mixin 是类似的
混入,通过 mixin 混入来分发 vue 组件中的可复用功能。
一个混入对象可以包含任意组件选项。
当组件使用混入对象时,所有混入对象的选项将被"混合"进入该组件本身的选项。
而 vue3 的 hooks 函数与 mixin 混入的区别,主要是 hooks 是函数。
特点:
- vue3 中的 hooks 函数相当于 vue2 里面的 mixin 混入,不同在于 hooks 是函数。
- vue3 中的 hooks 函数可以提高代码的复用性,能够在不同的组件当中都利用 hooks 函数。
- hooks 函数可以与 mixin 连用,但是不建议。
Demo:一个小功能,就是获取页面的宽高值
实现方法:
html
<template>
<h3>hooks</h3>
<p>页面宽度: {{screen.width}}</p>
<p>页面高度: {{screen.height}}</p>
<el-button @click="getWH">获取页面的宽高</el-button>
</template>
<script setup>
import { reactive } from 'vue'
const screen = reactive({
width: 0,
height: 0
})
const getWH = () => {
screen.width = document.documentElement.clientWidth
screen.height = document.documentElement.clientHeight
}
</script>
<style scoped>
</style>
如果这个功能在所有页面都需要使用,那就需要一边一边的复制粘贴。
使用hooks实现:
src 文件夹下创建一个 hooks 文件夹
在 hooks 文件夹下创建一个文件,名字就叫做 useScreenWh.js
文件
把获取可视化界面的代码放进这个 js 文件,然后导出去,给其他页面使用就可以了
js
import { reactive } from 'vue'
export default function () { // 导出一个默认方法
// 创建一个对象,保存宽度和高度值
const screen = reactive({
width: 0,
height: 0
})
// 创建一个方法,获取可视化界面的宽度和高度值
const getWH = () => {
screen.width = document.documentElement.clientWidth
screen.height = document.documentElement.clientHeight
}
return { screen, getWH } // 方法返回宽高值
}
在需要使用 hooks 的文件引入就可以使用了
html
<template>
<h3>hooks</h3>
<p>页面宽度: {{screen.width}}</p>
<p>页面高度: {{screen.height}}</p>
<el-button @click="getWH">获取页面的宽高</el-button>
</template>
<script setup lang="ts">
// 导入 hooks
import screenWH from '../hooks/useScreenWh.js'
// 因为 screenWH 是一个导出的方法,所以需要调用一下子,然后顺便解构一下就可以在模板使用了。
let { screen, getWH } = screenWH()
</script>
<style scoped>
</style>
五、速度研究
- 更轻量的打包大小:Vue3采用了新的编译模板方式,将模板编译为更小且更高效的代码。新版本中,编译模板的过程更加智能化,并通过Tree-Shaking技术实现更好的代码摇树性能。
- 支持模块化 :全面支持ES模块化,并且通过使用ES模块系统来组织和加载代码。
- 静态组件:Vue3引入了一项名为静态组件提升的优化技术。在Vue2中,每次渲染组件时,都会创建一个新的响应式实例,这会消耗一定的内存和性能。
- 全面支持TS
这就是vue3的基本使用,注意啊,是基本使用,vue3 相关的东西很多,这里只是简单的是用,剩下的你们慢慢看文档。
今天到这儿,打卡收工!
参考资料:
Vue3官方文档:v3.cn.vuejs.org/guide/intro...
TS官方文档:www.tslang.cn/docs/home.h...