前言
Vue3
已经出了一段时间了,本人也一直在学习,但楼主是学生,最近一直在做一些微信小程序和可视化的一些东西,所以更新的有点慢。请大家理解一下。
本文主要讲述一下自己在学习Vue3 + Ts + vite过程中,自己的理解即使用方法
Ts
个人的Ts
不能说学的很好,只能说会一部分基础。所以在这里就不 误导大家了,本文会在下面Vue3
中进行简单的使用。
如果想深入学习。推荐下面几本书
推荐一本书TypeScript 入门教程,这个是放在Github
(可能需要科学上网)。(推荐优先阅读这本书,个人感觉比较通俗易懂)
第二本书就是 官方手册(也可能需要科学上网),相对于第一本我觉得比较难理解,所以首推第一本
Vue3基本环境及语法
配置 vue3 开发环境
// 安装或者升级
npm install -g @vue/cli
yarn global add @vue/cli
// 全局升级vueCli
npm update -g @vue/cli
// 或者
yarn global upgrade --latest @vue/cli
// 保证 vue cli 版本在 4.5.0 以上
vue --version
// 创建项目
vue create my-project
// 或者使用图形化界面创建
vue ui
CSS预处理器推荐
推荐使用dart-sass
,(深受node-sass的毒害)。这也是官方所推荐的
有关命令行的步骤。主要是一些配置,大家可以参考一些平常自己的使用。个人推荐Vue ui创建。可能是好看吧
template的变化
在Vue2
中,每个template
节点只能有一个根节点。
而在Vue3
中,可以有多个根节点
举例说明
//vue2
<template>
<div>
</div>
</template>
// vue3
<template>
<div>
</div>
<router-view/>
</template>
新增语法
setUp
这个就是代替了原来的data函数
,可以接收两个参数,props
,context
(没有用到的时候可以省略不写)。且只执行一次
示例代码
<template>
<div>
<h1>
num:{
{ num }}
</h1>
</div>
<button @click="add">加1</button>
</template>
<script lang="ts">
export default {
name: 'App',
setup () {
let num = 0
const add = () => {
num++
}
console.log(num)
return {
add, num
}
}
}
</script>
这就是一个基本的setup
的过程,可能大家在这里还看不出来,和Vue2
具体有哪些区别,别急。可以试着点击一下button
按钮,发现num
并没有发生改变。看一下控制台(F12),发现输出的是一个number
的值。但是我们点击并没有发生改变。所以接下来,我们将用到第一个 新的API Ref
Ref
首先,我们改造一下上面的代码
<template>
<div>
<h1>
msg:{
{ msg }}
</h1>
<h1>
num:{
{ num }}
</h1>
</div>
<button @click="add">加1</button>
</template>
<script lang="ts">
import { ref } from 'vue'
export default {
name: 'App',
setup () {
const msg = ref(0)
let num = 0
const add = () => {
msg.value++
num++
}
console.log(msg)
console.log(num)
return {
msg, add, num
}
}
}
</script>
首先,先看引用形式,可以看到这里是 按需导入,好处我也不就一一叙述, 我们直接看 控制台
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H6ZDHj1K-1610456412702)(https://upload.cc/i1/2020/10/15/LpIr9k.png)]
一个是 RefImpl
一个是数值 0
。点击按钮发现,msg
可以改变,而num
不行。
RefImpl
是什么呢?我把它理解为 代理对象。就比如我们知道Vue2
中data
的数据是通过Object.defineProperty()来进行拦截。从而达到 数据响应式 的目的。而Vue3
是利用了ES6
中的proxy,相对于Object.defineProperty()
来说,能拦截的方式更多。功能也更加强大。
所以,大家知道为什么msg
能改变,num
不能改变了吗?因为msg
被proxy
进行了代理。而num
并没有。所以才会造成了上面的局面
解释Ref
ref
是一个函数,它接受一个参数,返回的就是一个响应式对象 。
例子中,我们初始化的这个 0
作为参数包裹到这个对象中去,在未来操作这个值的时候,可以检测到改变并作出对应的相应。
如果说我想创建一个对象呢?这时候就不能时使用这个函数了。就要使用接下来这个函数Reactive
Reactive
创建一个 JavaScript对象 反应式状态,就要使用reactive
方法:
示例代码
<template>
<div>
{
{
data }}
<h1>
count:{
{
data.count }}
</h1>
<h1>
double:{
{
data.double }}
</h1>
</div>
<button @click="data.increase">加1</button>
</template>
<script lang="ts">
import {
reactive, computed } from 'vue'
export default {
name: 'App',
setup () {
const data = reactive({
count: 0,
increase: () => {
data.count++
},
double: computed(() => data.count * 2)
})
return {
data
}
}
}
</script>
这时候呢,我们点击按钮就可以改变状态了。
computed计算属性,给Vue2
差不多。学过Vue2
的同学可以理解。如果不理解,请看后续有专门介绍
这时候可能回有人嫌比较麻烦,为什么不直接{
{count}}
这样呢。就想到了Es6
中的 解构
所以代码换成了如下
<template>
<div>
<h1>
count:{
{ count }}
</h1>
<h1>
double:{
{ double }}
</h1>
</div>
<button @click="increase">加1</button>
</template>
<script lang="ts">
import { reactive, computed } from 'vue'
export default {
name: 'App',
setup () {
const data = reactive({
count: 0,
increase: () => {
data.count++
},
double: computed(() => data.count * 2)
})
return {
...data
}
}
}
</script>
这时候大家会发现一个问题。为什么点击按钮不改变状态了呢?
这是因为,解构会破坏代理,把他编程一个普通值。就跟上面的Ref
的例子一样,所以点击按钮并没有发生变化。
这时候,就要请出 另外一个新加的api
了,toRefs
toRefs
这是引用官网的一句话
toRefs
从组合函数返回反应对象时,此函数很有用,以便使用组件可以对返回的对象进行解构/扩展而不会失去反应性:
使用起来 比较简单,就返回的时候加上就可以
<template>
<div>
<h1>
count:{
{ count }}
</h1>
<h1>
double:{
{ double }}
</h1>
</div>
<button @click="increase">加1</button>
</template>
<script lang="ts">
import { reactive, computed, toRefs } from 'vue'
export default {
name: 'App',
setup () {
const data = reactive({
count: 0,
increase: () => {
data.count++
},
double: computed(() => data.count * 2)
})
return {
...toRefs(data)
}
}
}
</script>
生命周期改变
beforeMount |
onBeforeMount |
---|---|
mounted |
onMounted |
beforeUpdate |
onBeforeUpdate |
updated |
onUpdated |
beforeUnmount |
onBeforeUnmount |
unmounted |
onUnmounted |
errorCaptured |
onErrorCaptured |
renderTracked |
onRenderTracked |
renderTriggered |
onRenderTriggered |
提示(来自官网)
由于
setup
是围绕beforeCreate
和created
生命周期挂钩运行的,因此您无需显式定义它们。换句话说,将在这些挂钩中编写的任何代码都应直接在setup
函数中编写。
原来语法
watch
// watch 基本使用 记得引入
watch(data, () => {
document.title = '更新过后 ' + data.count
})
// watch 的两个参数,代表新的值和旧的值
watch(data, (newValue, oldValue) => {
console.log('old', oldValue)
console.log('new', newValue)
document.title = '更新过后 ' + data.count
})
// watch 多个值,返回的也是多个值的数组
watch([greetings, data],