Vue3.2 语法基础
# 前言
官网地址:https://staging-cn.vuejs.org/
vue最新版分为两个版本: Vue3.0(20年9月18日) Vue 3.2 (21年8月10日)
# Vue 3.2 +Vite+volar
Vue3 框架做了大量的性能优化,包括虚拟 DOM,编译模板、代理的新数据监听,体积更小的打包文件等。
新的组合式 API (composition-api),更适合大型项目的构建,去除繁琐的 this 操作;
由于是基于 TypeScript 编写,对 TypeScript 原生支持更好,更强大的智能类型推导功能;
生命周期的一些改变,vue2 中的 beforeCreate 和 created 被一个新增的 setup 生命周期函数代替;
一些常见 API 如 v-model 的变化,支持对一个组件同时进行多个 v-model 的数据绑定。
vscode 的插件 vetur 对vue3 的composition API语法支持度非常弱,所以开发vue3项目需要将vetur禁用 更换另一个插件
开发vue3安装并使用:
volar
插件
# 1.项目创建
Vite 官网:
https://cn.vitejs.dev/
yarn create vite my-vue-app --template vue
# 2.SFC 单文件组件
html 部分变化不大
vue2的 template 中只能有一个子节点,vue3的 template 中可以写多个子节点
js 部分内置ts,但是vite创建的项目没有开启 ,
<script lang="ts" setup>
这样写即可支持ts新增setup 语法糖,js代码大量简化
代码中不再出现
this
css 代码中 可以使用v-bind 指令
<template>
<div>
</div>
</template>
<script setup>
let color = '#f60';
</script>
<style scoped>
.box{
width: 100px;
height: 100px;
background: v-bind(color);
}
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 2. setup语法糖
起初 Vue3.0 暴露变量必须 return 出来,template中才能使用; 这样会导致在页面上变量会出现很多次。
vue3.2只需在script标签中添加setup,可以帮助我们解决这个问题。
1.组件只需引入不用注册,属性和方法也不用返回, 也不用写setup函数,也不用写export default , 甚至是自定义指令也可以在我们的template中自动获得。
# 3.data 定义
# 3.1 直接定义 无响应式
<template>
<div>
<h1>{{name}}</h1>
<!-- 这里双向绑定失效,直接定义变量没有响应式特性 -->
<input type="text" v-model="name">
</div>
</template>
<script setup>
let name = '张麻子';
</script>
2
3
4
5
6
7
8
9
10
11
12
# 3.2 ref 定义基本数据类型 有响应式
<template>
<div>
<h1>{{name}}</h1>
<!-- 修改数据 有响应式 -->
<input type="text" v-model="name">
<button @click="setData">修改数据</button>
</div>
</template>
<script setup>
import {ref} from 'vue';
let name = ref('张麻子');
//js中修改数据有响应式
const setData = ()=>{
name.value = '黄四郎'
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3.3 reactvie 定义引用数据类型 有响应式
<template>
<div>
<h2>{{user.name}}</h2>
<!-- 修改数据 有响应式 -->
<input type="text" v-model="user.name">
<!-- 新增属性 -->
<button @click="addItem">新增属性</button>
</div>
</template>
<script setup>
import {ref,reactive} from 'vue'
let user = reactive({
name:'张麻子',
age:40
})
// js中新增对象属性-可以直接赋值和修改(有响应式),在ts环境下,vscode会提示错误,但在页面中可以正常渲染
const addItem = ()=>{
user.like='打豆豆'
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 4.methods 方法定义
<template>
<div>
<!-- 年龄 + -->
<h1>{{user.age}}</h1>
<!-- 调用方法 -->
<button @click="addAge">年龄+</button>
</div>
</template>
<script setup>
import { ref, reactive } from "vue";
let user = reactive({
name: "张麻子",
age: 40,
});
//方法
const addAge=()=>{
user.age++;
}
//方法调用方法
const getUserInfo=()=>{
addAge()
console.log(user.age)
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 5.computed 计算属性
<script setup>
import { ref, reactive, computed } from "vue";
let user = reactive({
name: "张麻子",
age: 40,
});
//计算属性
const getAge = computed(()=>{
return '我的年龄'+user.age
})
</script>
2
3
4
5
6
7
8
9
10
11
12
# 6.watch 使用
watch(监听数据源,执行函数,[配置参数])
//配置参数: 立即执行 深度监听
{immediate: true, deep: true }
2
3
# 6.1 监听基本数据类型单一数据源
<script setup>
import {ref, watch} from 'vue'
let name = ref('张麻子')
//监听器
watch(name,(newVal,oldVal)=>{
console.log('变量发生了改变...',newVal);
})
</script>
2
3
4
5
6
7
8
9
# 6.2 监听引用数据类型单一数据源
<script setup>
import {reactive, ref, watch} from 'vue'
let user = reactive({name:'张三',age:14})
//监听器
watch(()=>user.name,(newVal,oldVal)=>{
console.log('对象user中的name属性发生了变化..',newVal);
})
</script>
2
3
4
5
6
7
8
# 6.3 监听引用数据类型 多数据源[深度监听]
<template>
<div>
<button @click="addNum()"> 添加随机数</button>
<div v-for="item in nums" :key="item">{{ item }}</div>
</div>
</template>
<script setup>
import { reactive, ref, watch } from 'vue'
let nums = reactive([]);
//添加随机数
const addNum = () => {
let num = Math.ceil(Math.random() * 100);
nums.push(num);
}
//监听数组变化-深度监听
watch(()=>nums,(newVal,oldVal)=>{
console.log('nums数组发生了变化..',newVal);
},{deep:true})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 7.生命周期
vue2 | vue3.0 | vue3.2 | 备注 |
---|---|---|---|
beforeCreate | setup | 组件创建之前 可以获取顶级实例对象 | |
created | setup | 组件创建完成,可以获取变量 | |
beforeMount | onBeforeMount | 挂载前,VNdom创建完成,真实dom未渲染 | |
mounted | onMounted | 挂载完成,真实dom创建完成,可以获取dom | |
beforeUpdate | onBeforeUpdate | dom更新前触发 | |
updated | onUpdated | dom更新完成触发 | |
beforedestroy,destroyed | beforeUnmount | onBeforeUnmount | 组件卸载后触发 所有的挂载的数据 子组件全部卸载后触发 |
errorCaptured | onErrorCaptured | 在捕获一个来自后代组件的错误时被调用 | |
renderTracked | onRenderTracked | 跟踪虚拟 DOM 重新渲染时调用 | |
renderTriggered | onRenderTriggered | 当虚拟 DOM 重新渲染被触发时调用 | |
activated | activated | onActivated | 缓存组件激活时调用 |
deactivated | deactivated | onDeactivated | 缓存组件失活时调用 |
<template>
<div>
<div class="box"></div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
//生命周期钩子监听
onMounted(()=>{
console.log(document.querySelector('.box')); //可以获取dom
})
</script>
2
3
4
5
6
7
8
9
10
11
12
# 8.组件使用
创建 src/components/Son.vue
App.vue中导入并使用该组件
vue3.2 中当我们导入子组件时,setup语法糖会自动去注册该组件,所以注册语句不用写了。
<template>
<div>
<son></son>
</div>
<script setup>
import Son from './components/Son.vue'
</script>
2
3
4
5
6
7
# 9.组件通信
# 9.1 父传子 defineProps
- 父组件
<template>
<div>
<Son class="box" title="我是父组件传递的标题" :likes="likes"></Son>
</div>
</template>
<script setup>
import Son from './components/Son.vue'
let likes = ['张三','李四']
</script>
2
3
4
5
6
7
8
9
10
- 子组件
<script setup>
const props=defineProps({
title:{
type:String,
default:''
},
likes:{
type:Array,
default:()=>[]
}
})
</script>
2
3
4
5
6
7
8
9
10
11
12
# 9.2 子传父 defineEmits
- 子组件
<template>
<div>
<button @click="sendData">传递数据</button>
</div>
</template>
<script setup>
//定义自定义事件
const emit = defineEmits(['send'])
//自己的事件执行函数
const sendData = () => {
//执行自定义事件
emit('send', '我是儿子组件传递的数据')
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 父组件
<template>
<div>
<Son class="box" @send="getData" ></Son>
</div>
</template>
<script setup>
import Son from './components/Son.vue'
//触发自定义事件-接收数据
const getData = (data)=>{
console.log(data);
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13