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