1.插件说明

vue2中安装的插件是vetur,可以实现组件高亮。但是vue3的一些语法在vetur中报错。

vue3需要安装插件volar,提供了更加强大的功能,所以,在使用vue3创建项目是,需要禁用vetur

vue AES128 解密_vue AES128 解密

 目前vue3支持的组件库有: element-plus  vant  ant-design-vue

2.vue3的动机与新特性

动机: 更好的逻辑复用 与  代码组织  (composition组合式api)

         更好的类型推导 (typescript支持)
         vue3 源码用 ts 重写了, vue3 对 ts 的支持更友好了  (ts  可以让代码更加稳定, 类型检测! )

新特性: 

数据响应式原理重新实现  (ES6 proxy 替代了 ES5 的 Object.defineProperty)
解决了: 例如数组的更新检测等bug, 大大优化了响应式监听的性能
(原来检测对象属性的变化, 需要一个个对属性递归监听)  proxy 可以直接对整个对象劫持

虚拟DOM - 新算法 (更快 更小)

提供了composition api, 可以更好的逻辑复用

模板可以有多个根元素

源码用 typescript 重写, 有更好的类型推导 (类型检测更为严格, 更稳定)

3.vite

(1)使用vite创建项目

npm create vite
# or
yarn create vite

(2)输入项目名字,默认为vite-project

(3)选择创建的项目类型,选择vue即可

(4)选择创建的vue项目类型,  不选ts

(5)启动项目

4.composition API vs options API

vue2 采用的就是 optionsAPI (1) 优点:易于学习和使用, 每个代码有着明确的位置 (例如: 数据放 data 中, 方法放 methods中)
(2) 缺点:  相似的逻辑, 不容易复用, 在大项目中尤为明显
(3) 虽然 optionsAPI 可以通过mixins 提取相同的逻辑, 但是也并不是特别好维护

vue3 新增的就是 compositionAPI (1) compositionAPI 是基于  逻辑功能  组织代码的, 一个功能 api 相关放到一起
(2) 即使项目大了, 功能多了, 也能快速定位功能相关的 api
(3) 大大的提升了 代码可读性可维护性

vue3 推荐使用 composition API, 也保留了options API
即就算不用composition API, 用 vue2 的写法也完全兼容!!

5.setup函数

setup 函数是一个新的组件选项, 作为组件中 compositionAPI 的起点

从生命周期角度来看, setup 会在 beforeCreate 钩子函数之前执行

setup 中不能使用 this, this 指向 undefined

注意: 在模版中需要使用的数据和函数,需要在 setup 返回。

<template>
  <div class="container">
    <h1 @click="say()">{{msg}}</h1>
  </div>
</template>

<script>
export default {
  setup () {
    console.log('setup执行了')
    console.log(this)
    // 定义数据和函数
    const msg = 'hi vue3'
    const say = () => {
      console.log(msg)
    }

    return { msg , say}
  },
  beforeCreate() {
    console.log('beforeCreate执行了')
    console.log(this)
  }
}
</script>

5.reactive 函数

作用: 传入一个复杂数据类型,将复杂类型数据, 转换成响应式数据,用来定义响应式对象数据

<template>
  <div>{{ obj.name }}</div>
  <div>{{ obj.age }}</div>
  <button @click="obj.name = 'ls'">改值</button>
</template>

<script>
import { reactive } from 'vue'

export default {
  setup () {
    // 1. setup 需要返回值, 返回的值才能在模板中使用
    // 2. 默认的普通的值不是响应式的, 需要用 reactive 函数
    const obj = reactive({
      name: 'zs',
      age: 18
    })

    return {
      obj
    }
  }
}
</script>

6.ref函数

作用: 对传入的数据(一般简单数据类型),包裹一层对象,  转换成响应式。

概述: 和reactive类似

ref 函数接收一个的值, 返回一个ref 响应式对象,  有唯一的属性 value

在 setup 函数中, 通过 ref 对象的 value 属性, 可以访问到值

在模板中, ref 属性会自动解套, 不需要额外的 .value

ref函数也支持传入复杂类型,传入复杂类型,也会做响应式处理

<template>
  <div>{{ money }}</div>
  <button @click="money++">改值</button>
</template>

<script>
import { reactive, ref } from 'vue'
export default {
  setup() {
    let money = ref(100)
    money.value++
    return {
      money
    }
  }
}
</script>

7. script setup语法糖

需要吧setup写到script标签上

顶层的绑定会自动暴露给模板,所以定义的变量,函数和import导入的内容都可以直接在模板中直接使用

<template>
  <div>
    <h3>根组件</h3>
    <div>点击次数:{{ count }}</div>
    <button @click="add">点击修改</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)
const add = () => {
  count.value++
}

// 不再需要return {}
</script>

8.计算属性computed

set里面的val表示,绑定的值手动改变时调用set

<template>
  <div>我今年的年纪 <input type="text" v-model="age" /></div>
  <div>我明年的年龄 {{ nextAge }}</div>
  <div>我后年的年龄 <input type="text" v-model="nextAge2" /></div>
</template>

<script setup>
import { computed, ref } from 'vue'
const age = ref(10)
// 不带set的计算属性
const nextAge = computed(() => {
  return +age.value + 1
})

// 带set的计算属性
const nextAge2 = computed({
  get() {
    return +age.value + 2
  },
  set(value) {
    age.value = value - 2
  },
})
</script>

9.侦听器 watch

watch函数接收三个常规参数

  1. 第一个参数有三种取值:
    参数类型:(3种)
    任意类型:要监听的响应式数据
    数组:每个元素是响应式数据
    函数:监听对象的某一个属性
  2. 第二个参数是:响应式数据变化之后要执行的回调函数,
  3. 第三个参数是: 一个对象,在里面配置是否开启立刻执行或者深度监听
  4. 注意: watch监听ref包裹的对象时,要开启深度监听
// 1. 侦听-单个数据
        watch(salary, (newVal, oldVal) => {
            console.log('监听单个数据', newVal, oldVal)
        })
			 // 侦听-单个数据
        watch(stu, (newVal, oldVal) => {
            console.log('监听单个数据', newVal, oldVal)
        })

      	// 侦听-多个数据
        watch([stu, salary], (newVal, oldVal) => {
            console.log('监听多个数据', newVal, oldVal)
        })
				// 侦听对象的某个属性
        watch(()=>stu.address , (newVal, oldVal) => {
            console.log('第一个参数是函数', newVal, oldVal)
        }, {deep: true,  immediate: true} )