Vue3 快速上手(详细)
Vue3快速上手,适合有Vue2基础的看
一. 概述
1 为什么提出Vue3
Vue2是一个非常优秀的框架, 好上手, 学习曲线也比较平滑. 也是目前使用最广泛的框架之一
为什么尤大要重构, 推出Vue3呢?
大家有兴趣可以看一下这篇专访
总结起来就是
更适应当下的技术环境
要知道, 每个技术都是有局限性的. 某一方面的提升往往意味着另一方面的牺牲.
2 提出了哪些改进
使用TS重构
应用了JS的新特性Proxy重写响应式
性能的提升
Composition API
如果一定要选出一个最大的区别, 应该是Composition API
3 Options API vs Composition API
1) Options API的代码组织形式
使用Options API实现一个功能, 需要在不同的地方编写代码
状态(数据)在data中定义
方法在methods中定义
计算属性
...
当新添加一个功能时, 代码的组织会比较零散
2) Composition API的代码组织
引入vue.js
创建页面容器
实例化对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入vue库 -->
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<!-- 2. 创建页面容器 -->
<div id="app">{{msg}}</div>
<script>
const app = {
data() {
return {
msg: 'hello',
}
},
}
// 创建Vue实例对象, 挂载到#app指定的页面容器
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
data必须是一个函数
之前Vue2中的配置项依然可以使用
练习
三. setup语法
1 setup配置项
在Vue3中, 为了向前兼容, 不影响之前的配置项
创造了一个新的配置项setup, 所有的Composition API都可以在setup中使用
:::info
setup是一个函数
返回一个对象, 对象中定义的属性, 方法在模板中直接使用
返回渲染函数(不常用)
:::
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
{{uname}} -- {{age}}
<p>{{ sayHi() }}</p>
</div>
<script>
const app = {
// setup配置项(函数, 返回对象)
// 在返回的对象中定义的属性, 方法 可以直接在模板中使用
setup() {
// 定义数据 data
let uname = 'xiaoming'
let age = 20
// 定义方法 methods
function sayHi() {
console.log(`大家好, 我是${uname}, 今年${age}岁了`)
return 123
}
return {
uname,
age,
sayHi,
}
},
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
这样写的代码会丢失响应式
:::warning
💡** 注意**
不要将vue2的语法和vue3的语法混用!!
:::
2 调试工具
这里我们安装最新的vue devtools工具, 可以同时支持vue2和vue3
通过调试工具, 我们发现定义的数据并不是响应式的.
在setup函数中, 如果要实现响应式, 需要借助
ref函数: 实现普通类型数据的响应式
reactive函数: 实现引用类型数据的响应式
3 ref函数
使用步骤
导入ref函数
使用ref函数定义数据
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">{{msg}}</div>
<script>
// 像ref, reactive, computed从Vue对象从导出的函数, 就是composition API
const { ref } = Vue
const app = {
setup() {
// ref函数: 实现值类型数据的响应式
// 将值类型数据(普通数据 String, Number, Boolean, undefined, null)
let msg = ref('hello')
// ref函数: 接收普通类型的数据作为参数, 返回一个RefImpl对象
console.log(msg)
return {
msg,
}
},
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
通过devtools修改
:::info
需求
点击按钮修改姓名
:::
如何使用代码实现修改数据呢?
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入vue库 -->
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<!-- 2. 创建页面容器 -->
<div id="app">
<p>姓名:{{uname}}</p>
<button @click="handleClick">点击修改</button>
</div>
<script>
const { ref } = Vue
const app = {
setup() {
let uname = ref('xiaoming')
function handleClick() {
// uname是一个RefImpl对象. 修改其`value`属性
uname.value = '小明'
}
return {
uname,
handleClick,
}
},
}
// 创建Vue实例对象, 挂载到#app指定的页面容器
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
练习
使用setup语法(Composition API)实现计数器
4 reactive函数
对于引用类型数据. 如对象, 数组
使用ref函数比较麻烦, 在访问时, 每次都需要.value
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入vue库 -->
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<!-- 2. 创建页面容器 -->
<div id="app">
<p>姓名:{{stu.name}}</p>
<button @click="handleClick">点击修改</button>
</div>
<script>
const { reactive } = Vue
const app = {
setup() {
const stu = reactive({
name: 'xiaoming',
age: 20,
})
function handleClick() {
console.log(stu)
stu.name = '小明'
}
return {
stu,
handleClick,
}
},
}
// 创建Vue实例对象, 挂载到#app指定的页面容器
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
区别
从定义的角度
ref: 主要用于基本数据类型
reactive: 主要用于引用数据类型
从实现的角度
ref: 通过Object.defineProperty的get和set来实现响应式
reactive: 通过Proxy来实现数据劫持, 通过reflect操作内部属性
从使用的角度
ref: 需要通过.value操作数据
reactive: 不需要.value, 直接操作数据
5 computed函数
使用步骤
导入computed函数
在setup中使用
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入vue库 -->
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<!-- 2. 创建页面容器 -->
<div id="app">
姓: <input type="text" v-model="data.firstName" /> <br />
名: <input type="text" v-model="data.lastName" /> <br />
全名: {{fullName}}
</div>
<script>
const { reactive, computed } = Vue
const app = {
setup() {
const data = reactive({
firstName: '',
lastName: '',
})
const fullName = computed(() => {
return data.firstName + data.lastName
})
return {
data,
fullName,
}
},
}
// 创建Vue实例对象, 挂载到#app指定的页面容器
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
优化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入vue库 -->
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<!-- 2. 创建页面容器 -->
<div id="app">
姓: <input type="text" v-model="person.firstName" /> <br />
名: <input type="text" v-model="person.lastName" /> <br />
全名: {{person.fullName}}
</div>
<script>
const { reactive, computed } = Vue
const app = {
setup() {
const person = reactive({
firstName: '',
lastName: '',
})
person.fullName = computed(() => {
return person.firstName + person.lastName
})
return {
person,
}
},
}
// 创建Vue实例对象, 挂载到#app指定的页面容器
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
6 watch函数
在Vue3中, 将watch也定义成一个组合式API
使用步骤
导入watch函数
使用watch函数监听
由于定义数据有两种方式. 监听时也分两种情况
监视ref定义的数据
监视reactive定义的数据
1) 监视ref定义的数据
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h3>当前计数为: {{count}}</h3>
<button @click="count++">点击+1</button>
</div>
<script>
const { ref, watch } = Vue
const app = {
setup() {
const count = ref(0)
watch(count, (newValue, oldValue) => {
console.log('count改变了', newValue, oldValue)
})
return {
count,
}
},
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
2) 监视reactive定义的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h3>姓名: {{stu.name}}</h3>
<h3>年龄: {{stu.age}}</h3>
<button @click="stu.name = '小明'">修改姓名</button>
<button @click="stu.age++">年龄+1</button>
</div>
<script>
const { reactive, watch } = Vue
const app = {
setup() {
const stu = reactive({
name: 'xiaoming',
age: 20,
})
watch(stu, (newValue, oldValue) => {
// 拿不到旧的value值
console.log('stu变化了', newValue, oldValue)
})
return {
stu,
}
},
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
对于引用类型, watch不能监视到oldValue
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h3>姓名: {{stu.name}}</h3>
<h3>年龄: {{stu.age}}</h3>
<button @click="stu.name = '小明'">修改姓名</button>
<button @click="stu.age++">年龄+1</button>
</div>
<script>
const { reactive, watch } = Vue
const app = {
setup() {
const stu = reactive({
name: 'xiaoming',
age: 20,
})
// 监听某个属性, 需要使用函数, 函数返回该属性
watch(() => stu.name, (newValue, oldValue) => {
// 拿不到旧的value值
console.log('stu变化了', newValue, oldValue)
})
return {
stu,
}
},
}
Vue.createApp(app).mount('#app')
</script>
</body>
</html>
7 生命周期
Vue3的生命周期在调用mount('#app')后开始
setup在所有生命周期函数执行前调用, 因此, 在setup()中this指向window, 没有批向当前实例
setup主要完成composition API的初始化. created完成OptionsAPI的初始化
在setup中最常用的生命周期有两个: onMounted和onBeforeUnmount
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../node_modules/vue/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<h1>我是vm根实例</h1>
<button @click="isShow = !isShow">切换显示子组件</button>
<Demo v-if="isShow"></Demo>
</div>
<script>
const { onMounted, onBeforeUnmount } = Vue
// 创建一个Vue应用
const app = Vue.createApp({
data() {
return {
isShow: true,
}
},
})
// 注册子组件
app.component('demo', {
template: '<h3>我是子组件</h3>',
setup() {
onMounted(() => {
console.log('demo组件挂载...')
})
onBeforeUnmount(() => {
console.log('demo组件卸载...')
})
},
})
app.mount('#app')
</script>
</body>
</html>
四. 工程化
创建Vue3.0项目有这样两种方式
使用vue-cli
使用vite
1 使用vue-cli创建
vue create vue3-project
2 使用vite构建
npm create vite
使用vite初始化项目
五. hooks函数
1 什么是hooks
hooks本质上还是一种函数, 将多个Composition API封装, 实现某个特定功能
2 hooks的作用
解耦
复用
示例
将特定功能封装到一个单独的文件usePoint.js
import { reactive, onMounted, onBeforeUnmount } from 'vue'
export default function usePoint() {
const point = reactive({
x: 0,
y: 0,
})
function onClick(event) {
point.x = event.pageX
point.y = event.pageY
console.log(point.x, point.y)
}
onMounted(() => {
window.addEventListener('click', onClick)
})
onBeforeUnmount(() => {
window.removeEventListener('click', onClick)
})
return point
}
在需要时引入hooks函数
<template>
<h3>子组件</h3>
<p>x的坐标: {{ point.x }}--y的坐标: {{ point.y }}</p>
</template>
<script setup>
import usePoint from '../hook/usePoint'
const point = usePoint()
</script>
<style>
</style>
更多推荐
所有评论(0)