VUE3
简介
Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。无论是简单还是复杂的界面,Vue 都可以胜任。
发布日期:2020年9月18日
性能:
打包时间: 提升了41%
初次渲染速度 提升了55% 更新渲染速度133%
内存减少了 54%
升级:
Proxy替代defineProperty实现响应式
重写虚拟DOM实现Tree-Shaking
VUE3 更好的支持TypeScript
基于vue-cli创建
检查版本
vue --version
安装或者 升级vue /cli
npm i -g @vue/cli
执行创建命令
vue create 项目名
基于vite创建项目
vite的优势:
轻量快速的热重载、通用的插件
对TypeScript、JSX、CSS等的支持开箱即用。
真正的按需编译,不需要等待应用程序的完成
安装环境: npm install -g vite
创建项目:npm create vue@latest
创建项目配置
√ 请输入项目名称: ... vue3_test
√ 是否使用 TypeScript 语法? ... 是
√ 是否启用 JSX 支持? ... 否
√ 是否引入 Vue Router 进行单页面应用开发? ... 否
√ 是否引入 Pinia 用于状态管理? ... 否
√ 是否引入 Vitest 用于单元测试? ... 否
√ 是否要引入一款端到端(End to End)测试工具? >> 不需要
√ 是否引入 ESLint 用于代码质量检测? ... 否
√ 是否引入 Vue DevTools 7 扩展用于调试? (试验阶段) ... 否
中端》》进入项目的根目录
cd 项目名
npm i 项目初始化 (下载依赖)
npm run dev 启动项目
setup
setup是Vue3中一个新的配置。值是一个函数,
是组合式API结构。组件中用到的方法 数据 计算属性 监视等 配置在setup中。
使用return返回 数据 方法 等 可以在模板中直接使用。
setip中不能使用 this关键字 this: undefined
setup 函数会在beforeCreate之前调用,它是领先所有的 "钩子执行的"
setup语法糖
setup有一个语法糖,可以让我们讲setup独立出来
<!--setup语法糖-->
<script setup lang="ts">
console.log("this:", this)
//数据 原来是写在data中的
//此时 数据不是响应式的
let uName = "张三";
let uAge = 20;
let uTel = "15339253326";
//方法 原来写在methods中
const changeName = () => {
uName = "zhang-san"
console.log(uName)
}
const changeAge = () => {
uAge += 1;
console.log(uAge)
}
const showTel = () => {
console.log("联系方式:", uTel)
}
</script>
简化name属性
<script lang="ts">
export default {
name: "Person"
}
</script>
使用插件简化
安装:npm i vite-plugin-vue-setup-extend -D
配置:vite.config.ts >>>
1.引入:import vueSetupExtend from 'vite-plugin-vue-setup-extend'
2.配置
plugins: [
vue(), vueSetupExtend()
],
3.使用
<script setup lang="ts" name="Person">
App.vue
<template>
<Person></Person>
</template>
<script lang="ts" setup name="App">
//引入Person组件 也模板直接使用
import Person from "@/components/Person.vue";
</script>
基本类型的响应式数据(ref)
作用:定义响应式变量
引入 : import {ref} from "vue";
语法: let xxx = refu(初始值)
返回值:是一个RefImpl实例对象, 实例对象的value属性是响应式
注意:在模板中不需要 xxx .value
对于:let name = ref("张三") (RefImpl实例) name 不是响应式
而name.value是响应式
<template>
<h2>姓名:{{ uName }}</h2>
<h2>年龄:{{ uAge }}</h2>
<h2>电话:{{ uTel }}</h2>
<button @click="changeName">更新姓名</button>
<button @click="changeAge">更新年龄</button>
<button @click="showTel">点击查看联系方式</button>
</template>
<!--setup语法糖-->
<script setup lang="ts" name="Person">
//数据 原来是写在data中的
import {ref} from "vue";
let uName = ref("张三");
//ref >> RefImpl >> value << 张三
let uAge = ref(20);
let uTel = "15339253326";
//方法 原来写在methods中
const changeName = () => {
//编译错误
uName.value += "~";
console.log(uName.value)
}
const changeAge = () => {
uAge.value += 1;
console.log(uAge)
}
const showTel = () => {
console.log("联系方式:", uTel)
}
</script>
<style scoped>
</style>
对象类型的响应式数据 reactive
作用 定义一个响应式对象reactive (基本类型不能使用 要用ref)
引入reactive
import {reactive} from "vue";
//使用reactive 定义对象类型的数据
let 响应式对象 = reactive(源对象)。
返回值:reactive 返回一个 Proxy实例对象,响应式对象
注意:reactive定义的响应式数据是深层次
<template>
<h2>汽车信息:一台{{ car.brand }}汽车,价值:{{ car.price }}万</h2>
<button @click="changeCarPrice">修改汽车价格</button>
<hr/>
<h2>游戏列表</h2>
<ul v-for="(g,index) in games" :key="g.id">
{{ g.name }}
</ul>
<button @click="changeFirstGame">修改第一个游戏</button>
<hr/>
<h2>d:{{ obj.a.b.c.d }}</h2>
<button @click="changeD">修改d</button>
</template>
<script lang="ts" setup name="Person">
import {reactive} from "vue";
import {nanoid} from "nanoid";
console.log(nanoid())
let car = reactive({brand: '比亚迪', price: 100})
let games = reactive([
{id: nanoid(), name: '测试数据A'},
{id: nanoid(), name: '测试数据B'},
{id: nanoid(), name: '测试数据C'}
])
let obj = reactive({a: {b: {c: {d: 888}}}});
//修改 汽车价格
const changeCarPrice = () => {
car.price += +1;
console.log(car)
}
const changeFirstGame = () => {
games[0].name = "测试数据D";
console.log(games)
}
const changeD = () => {
obj.a.b.c.d = 666;
console.log(obj)
}
</script>
<style scoped>
</style>
ref创建 对象类型的响应式数据
其实ref接收的数据可以是:基本类型 对象类型。
如果ref接收的是对象类型,内部实际是调用了 reactive
<template>
<h2>汽车信息:一台{{ car.brand }}汽车,价值:{{ car.price }}万</h2>
<button @click="changeCarPrice">修改汽车价格</button>
<hr/>
<h2>游戏列表</h2>
<ul v-for="(g,index) in games" :key="g.id">
{{ g.name }}
</ul>
<button @click="changeFirstGame">修改第一个游戏</button>
<hr/>
<h2>d:{{ obj.a.b.c.d }}</h2>
<button @click="changeD">修改d</button>
</template>
<script lang="ts" setup name="Person">
import {ref} from "vue";
import {nanoid} from "nanoid";
let car = ref({brand: '比亚迪', price: 100})
// car >> ref >> RefImpl >> value << {brand: '比亚迪', price: 100} >> proxy
let games = ref([
{id: nanoid(), name: '测试数据A'},
{id: nanoid(), name: '测试数据B'},
{id: nanoid(), name: '测试数据C'}
])
let obj = ref({a: {b: {c: {d: 888}}}});
//修改 汽车价格
const changeCarPrice = () => {
car.value.price += +1;
console.log(car)
}
const changeFirstGame = () => {
games.value[0].name = "测试数据D";
console.log(games)
}
const changeD = () => {
obj.value.a.b.c.d = 666;
console.log(obj)
}
</script>
<style scoped>
</style>
reactive, ref 整体替换
<template>
<h2>汽车信息:一台{{ car.brand }}汽车,价值:{{ car.price }}万</h2>
<button @click="changeCarPrice">修改汽车价格</button>
<button @click="changeCar">替换汽车对象</button>
<hr/>
<h2>用户姓名:{{ person.name }},年龄:{{ person.age }}</h2>
<button @click="changePersonName">修改用户姓名</button>
<button @click="changePerson">替换用户对象</button>
</template>
<script lang="ts" setup name="Person">
import {reactive, ref} from "vue";
import {nanoid} from "nanoid";
let car = ref({brand: '比亚迪', price: 100})
// car >> ref >> RefImpl >> value << {brand: '比亚迪', price: 100} >> proxy
let person = reactive({id: nanoid(), name: '张三', age: 20})
// person >> proxy >>{id: nanoid(), name: '张三', age: 20}
const changeCarPrice = () => {
car.value.price += +1;
console.log(car)
}
const changePersonName = () => {
person.name += "~";
console.log(person.name)
}
const changeCar = () => {
car.value = {brand: '奔驰', price: 200};
/**
* car 》》 ref >>> RefImpl >> value >> 对象 >> reactive >> proxy
*/
}
const changePerson = () => {
// 使用 Object.assign(已有对象,新对象);
//如果新对象 与 已有对象的属性相同 则替换值
Object.assign(person,{id: nanoid(), name: '李四', age: 25});
// person = reactive({id: nanoid(), name: '李四', age: 25});
// console.log("触发了changePerson", person)
/**
* person >>> reactive >>> proxy
*
* person = {id: nanoid(), name: '李四', age: 25}
*
* person = reactive({id: nanoid(), name: '李四', age: 25});
*/
}
</script>
<style scoped>
</style>
reactive对比 ref
宏观角度:
ref用于定义 基本数据类型 对象数据类型
reactive 用于定义 对象类型数据
区别
ref创建的变量 必须.value使用。
reactive重新分配一个新的对象,会失去响应式(可以使用Object.assign 整体替换)
原则
如果需要一个基本类型的数据 必须使用ref 如果需要一个响应式独享
层次不深 ref reactive 如果 对象的层次 深 使用 reactive