网站做微信链接怎么做的,淘宝客优惠卷网站怎么做的,长春省妇幼网站做四维,施工企业年终总结及明年工作计划文章目录 1. Vue3简介1.1. 性能的提升1.2.源码的升级1.3. 拥抱TypeScript1.4. 新的特性 2. 创建Vue3工程2.1. 基于 vue-cli 创建2.2. 基于 vite 创建#xff08;推荐#xff09;vite介绍创建步骤项目结构安装插件项目结构总结 2.3. 一个简单的效果Person.vueApp.vue 3. Vue3核… 文章目录 1. Vue3简介1.1. 性能的提升1.2.源码的升级1.3. 拥抱TypeScript1.4. 新的特性 2. 创建Vue3工程2.1. 基于 vue-cli 创建2.2. 基于 vite 创建推荐vite介绍创建步骤项目结构安装插件项目结构总结 2.3. 一个简单的效果Person.vueApp.vue 3. Vue3核心语法3.1. OptionsAPI 与 CompositionAPIOptions API 的弊端Composition API 的优势 3.2. 拉开序幕的 setupsetup 概述setup 的返回值setup 与 Options API 的关系setup 语法糖 3.3. ref 创建基本类型的响应式数据3.4. reactive 创建对象类型的响应式数据3.5. 【ref 创建对象类型的响应式数据】3.6. 【ref 对比 reactive】宏观角度区别使用原则 1. Vue3简介 2020年9月18日Vue.js发布版3.0版本代号One Piecen 经历了4800次提交、40个RFC、600次PR、300贡献者 官方发版地址Release v3.0.0 One Piece · vuejs/core 截止2023年10月最新的公开版本为3.3.4
1.1. 性能的提升 打包大小减少41%。 初次渲染快55%, 更新渲染快133%。 内存减少54%。
1.2.源码的升级 使用Proxy代替defineProperty实现响应式。 重写虚拟DOM的实现和Tree-Shaking。
1.3. 拥抱TypeScript
Vue3可以更好的支持TypeScript。
1.4. 新的特性 Composition API组合API setup ref与reactive computed与watch … 新的内置组件 Fragment Teleport Suspense … 其他改变 新的生命周期钩子 data 选项应始终被声明为一个函数 移除keyCode支持作为 v-on 的修饰符 …
2. 创建Vue3工程
2.1. 基于 vue-cli 创建
点击查看 Vue-Cli 官方文档基于vue-cli创建其实就是基于webpack来创建vue项目 备注目前vue-cli已处于维护模式官方推荐基于 Vite 创建项目。 ## 查看vue/cli版本确保vue/cli版本在4.5.0以上
vue --version## 安装或者升级你的vue/cli
npm install -g vue/cli## 执行创建命令
vue create vue_test## 随后选择3.x
## Choose a version of Vue.js that you want to start the project with (Use arrow keys)
## 3.x
## 2.x## 启动
cd vue_test
npm run serve2.2. 基于 vite 创建推荐
vite介绍
vite 是新一代前端构建工具官网地址https://vitejs.cnvite的优势如下
轻量快速的热重载HMR能实现极速的服务启动。对 TypeScript、JSX、CSS 等支持开箱即用不用配置直接就可以用。真正的按需编译不再等待整个应用编译完成。webpack构建 与 vite构建对比图如下
创建步骤
具体操作如下点击查看官方文档
## 1.创建命令基于vite创建vue3项目前提是需要安装nodejs环境
npm create vuelatest## 2.具体配置
## 配置项目名称
√ Project name: vue3_test
## 是否添加TypeScript支持
√ Add TypeScript? Yes
## 是否添加JSX支持
√ Add JSX Support? No
## 是否添加路由环境
√ Add Vue Router for Single Page Application development? No
## 是否添加pinia环境
√ Add Pinia for state management? No
## 是否添加单元测试
√ Add Vitest for Unit Testing? No
## 是否添加端到端测试方案
√ Add an End-to-End Testing Solution? » No
## 是否添加ESLint语法检查
√ Add ESLint for code quality? Yes
## 是否添加Prettiert代码格式化
√ Add Prettier for code formatting? No构建过程如下 访问vue3项目如下 项目结构
安装插件
安装官方推荐的vscode插件 项目结构 index.html
!DOCTYPE html
html langenheadmeta charsetUTF-8link relicon href/favicon.icometa nameviewport contentwidthdevice-width, initial-scale1.0titleVite App/title/headbodydiv idapp/divscript typemodule src/src/main.ts/script/body
/htmlmain.ts
import ./assets/main.css// 引入createApp用于创建应用
import { createApp } from vue// 引入App根组件
import App from ./App.vuecreateApp(App).mount(#app)App.vue
!-- 自己动手编写的一个App组件 --
templatediv classapph1你好啊/h1/div
/templatescript langts // 添加langts, 里面写ts或js都可以export default {name:App //组件名}/scriptstyle.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}
/style总结
Vite 项目中index.html 是项目的入口文件在项目最外层。加载index.html后Vite 解析 script typemodule srcxxx 指向的JavaScript。Vue3在main.ts中是通过 createApp 函数创建一个应用实例。
2.3. 一个简单的效果
Vue3向下兼容Vue2语法且Vue3中的模板中可以没有根标签
Person.vue
templatediv classpersonh2姓名{{name}}/h2h2年龄{{age}}/h2button clickchangeName修改名字/buttonbutton clickchangeAge年龄1/buttonbutton clickshowTel点我查看联系方式/button/div
/templatescript langtsexport default {name:App,data() {return {name:张三,age:18,tel:13888888888}},methods:{changeName(){this.name zhang-san},changeAge(){this.age 1},showTel(){alert(this.tel)}},}
/scriptApp.vue
templatediv classapph1你好啊/h1Person//div
/templatescript langtsimport Person from ./components/Person.vueexport default {name:App, //组件名components:{Person} //注册组件}
/scriptstyle.app {background-color: #ddd;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}
/style3. Vue3核心语法
3.1. OptionsAPI 与 CompositionAPI
Vue2的API设计是Options配置风格的。Vue3的API设计是Composition组合风格的。
Options API 的弊端
Options类型的 API数据、方法、计算属性等是分散在data、methods、computed中的若想新增或者修改一个需求就需要分别修改data、methods、computed不便于维护和复用。 Composition API 的优势
可以用函数的方式更加优雅的组织代码让相关功能的代码更加有序的组织在一起。 3.2. 拉开序幕的 setup
setup 概述
介绍
setup是Vue3中一个新的配置项值是一个函数。它是 Composition API “表演的舞台”组件中所用到的数据、方法、计算属性、监视…等等均配置在setup中。
特点如下
setup函数返回的对象中的内容可直接在模板中使用。setup中访问this是undefined。setup函数会在beforeCreate之前调用它是“领先”所有钩子执行的。
templatediv classpersonh2姓名{{name}}/h2h2年龄{{age}}/h2button clickchangeName修改名字/buttonbutton clickchangeAge年龄1/buttonbutton clickshowTel点我查看联系方式/button/div
/templatescript langtsexport default {name:Person,// 生命周期函数beforeCreate(){console.log(beforeCreate)},setup(){// 先打印的setup..., 再打印的beforeCreate, 说明了setup函数与beforeCreate生命周期函数的执行顺序console.log(setup ...)// 【setup函数中的this是undefined】console.log(this); // undefined// 数据原来写在data中【注意此时的name、age、tel数据都不是响应式数据】// 不是响应式的意思是当这些数据变化并不会触发dom更新// 模板中应用这些变量的地方没有重新渲染let name 张三let age 18let tel 13888888888// 方法原来写在methods中function changeName(){name zhang-san // 注意此时这么修改name页面是不变化的console.log(name) // name确实改了但name不是响应式的}function changeAge(){age 1 // 注意此时这么修改age页面是不变化的console.log(age) // age确实改了但age不是响应式的}function showTel(){alert(tel)}// 返回一个对象对象中的内容模板中可以直接使用将数据、方法交出去模板中才可以使用这些交出去的数据、方法return {name,age,tel,changeName,changeAge,showTel}}}
/scriptsetup 的返回值
若返回一个对象则对象中的属性、方法等在模板中均可以直接使用**重点关注。**若返回一个函数则可以直接指定 自定义渲染的内容代码如下
templatediv classperson我特么一点都不重要了/div
/templatescript langtsexport default {name:Person,setup(){// setup的返回值也可以是一个渲染函数// 模板什么的都不重要了直接在页面上渲染成你好啊这几个字// return ()哈哈}}
/scriptstyle scoped.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}
/stylesetup 与 Options API 的关系
Vue2 的配置data、methos…中可以访问到 setup中的属性、方法。但在setup中不能访问到Vue2的配置data、methos…。如果与Vue2冲突则setup优先。
templatediv classpersonh2姓名{{name}}/h2h2年龄{{age}}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickshowTel查看联系方式/buttonhrh2测试1{{a}}/h2h2测试2{{c}}/h2h2测试3{{d}}/h2button clickb测试/button/div
/templatescript langtsexport default {name:Person,beforeCreate(){console.log(beforeCreate)},data(){return {a:100,// 在data配置项中, 可以使用this.name来使用setup中交出的数据, 因为setup执行时机更早。// 但是在setup中不能使用在data中定义的数据c:this.name, d:900,age:90}},methods:{b(){console.log(b)}},// setup可以与data、methods等配置项同时存在setup(){// 数据原来是写在data中的此时的name、age、tel都不是响应式的数据let name 张三let age 18let tel 13888888888// 方法function changeName() {name zhang-san // 注意这样修改name页面是没有变化的console.log(name) // name确实改了但name不是响应式的}function changeAge() {age 1 // 注意这样修改age页面是没有变化的console.log(age) // age确实改了但age不是响应式的}function showTel() {alert(tel)}// 将数据、方法交出去模板中才可以使用return {name,age,tel,changeName,changeAge,showTel}// setup的返回值也可以是一个渲染函数// return ()哈哈}}
/scriptstyle scoped.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;}button {margin: 0 5px;}
/stylesetup 语法糖
setup函数有一个语法糖这个语法糖可以让我们把setup独立出去代码如下
templatediv classpersonh2姓名{{name}}/h2h2年龄{{age}}/h2button clickchangName修改名字/buttonbutton clickchangAge年龄1/buttonbutton clickshowTel点我查看联系方式/button/div/template!-- 专门单个弄个script标签, 特地来配置组件的名字 --
script langtsexport default {name:Person,}
/script!-- 下面的写法是setup语法糖 --
!-- 1. 相当于写了setup函数; 2. 相当于自动把其中定义的变量交出去--
script setup langtsconsole.log(this) // undefined// 数据注意此时的name、age、tel都不是响应式数据let name 张三let age 18let tel 13888888888// 方法function changName(){name 李四//注意此时这么修改name页面是不变化的}function changAge(){console.log(age)age 1 //注意此时这么修改age页面是不变化的}function showTel(){alert(tel)}
/script扩展上述代码还需要编写一个不写setup的script标签去指定组件名字比较麻烦我们可以借助vite中的插件简化 第一步npm i vite-plugin-vue-setup-extend -D第二步vite.config.ts
import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite
import vue from vitejs/plugin-vue
import VueSetupExtend from vite-plugin-vue-setup-extend// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),VueSetupExtend(),],resolve: {alias: {: fileURLToPath(new URL(./src, import.meta.url))}}
})
第三步script setup langts namePerson
3.3. ref 创建基本类型的响应式数据
**作用**定义响应式变量。语法let xxx ref(初始值)。**返回值**一个RefImpl的实例对象简称ref对象或refref对象的value属性是响应式的。注意点 JS中操作数据需要xxx.value但模板中不需要.value直接使用即可。对于let name ref(张三)来说name不是响应式的name.value是响应式的。
templatediv classperson!-- 模板中直接使用, 不需要.value --h2姓名{{name}}/h2h2年龄{{age}}/h2h2电话{{tel}}/h2button clickchangeName修改名字/buttonbutton clickchangeAge年龄1/buttonbutton clickshowTel点我查看联系方式/button/div
/template!-- 使用了setup语法糖, 会自动将定义的变量和方法交出去, 以供给模板使用 --
script setup langts namePerson// 引入vue中的ref函数import { ref } from vue// name和age是一个RefImpl的实例对象简称ref对象它们的value属性是响应式的。//所谓的响应式指的是, 对数据的改变后, 能够让模板中使用该数据的地方得到重新渲染更新// ref是1个函数, 向这个ref函数中传入参数, 返回的是1个RefImpl的实例对象let name ref(张三)let age ref(18)// tel就是一个普通的字符串不是响应式的let tel 13888888888function changeName(){// JS中操作ref对象时候需要.valuename.value 李四 // 页面得到刷新console.log(name.value)// 注意name不是响应式的name.value是响应式的所以如下代码并不会引起页面的更新。// name ref(zhang-san)}function changeAge(){// JS中操作ref对象时候需要.valueage.value 1 // 页面得到刷新console.log(age.value)}function showTel(){// tel是普通数据 tel 1 // tel的确改了, 但页面并未刷新alert(tel)}
/script3.4. reactive 创建对象类型的响应式数据
作用定义一个响应式对象基本类型不要用它要用ref否则报错语法let 响应式对象 reactive(源对象)。**返回值**一个Proxy的实例对象简称响应式对象。注意点reactive定义的响应式数据是“深层次”的。
template
div classpersonh2汽车信息一台{{ car.brand }}汽车价值{{ car.price }}万/h2h2游戏列表/h2ulli v-forg in games :keyg.id{{ g.name }}/li/ulh2测试{{ obj.a.b.c.d }}/h2button clickchangeCarPrice修改汽车价格/buttonbutton clickchangeFirstGame修改第一游戏/buttonbutton clicktest测试/button/div
/templatescript langts setup namePersonimport { reactive } from vue// 定义数据// reactive是1个函数, 向这个reactive函数中传入参数传入对象或数组, 返回的是1个Proxy的实例对象//Proxy是原生Js就有的函数// reactive函数中传入对象let car reactive({ brand: 奔驰, price: 100 }) console.log(car, car); // car Proxy {brand: 奔驰, price: 100}// reactive函数传入数组let games reactive([ { id: ahsgdyfa01, name: 英雄联盟 },{ id: ahsgdyfa02, name: 王者荣耀 },{ id: ahsgdyfa03, name: 原神 }])// reactive定义的响应式数据是 深层次 的let obj reactive({a: {b: {c: {d: 666}}}})// 修改对象中的属性修改使用reactive包裹对象后返回的对象function changeCarPrice() {car.price 10}// 修改数组中的对象的属性修改使用reactive包裹数组后返回的对象function changeFirstGame() {games[0].name 流星蝴蝶剑}function test() {obj.a.b.c.d 999}
/script3.5. 【ref 创建对象类型的响应式数据】
其实ref接收的数据可以是基本类型、对象类型。若ref接收的是对象类型内部其实也是调用了reactive函数。
templatediv classpersonh2汽车信息一台{{ car.brand }}汽车价值{{ car.price }}万/h2h2游戏列表/h2ulli v-forg in games :keyg.id{{ g.name }}/li/ulh2测试{{ obj.a.b.c.d }}/h2button clickchangeCarPrice修改汽车价格/buttonbutton clickchangeFirstGame修改第一游戏/buttonbutton clicktest测试/button/div
/templatescript langts setup namePersonimport { ref,reactive } from vue// 使用ref定义对象类型响应式数据let car ref({ brand: 奔驰, price: 100 })// 使用reactive定义对象类型响应式数据let car2 reactive({brand: 奔驰, price: 100})// reactive只能用来定义对象类型的响应式数据// let name reactive(zhangsan) // 错误, value cannot be made reactive: zhangsan// 使用ref定义对象(数组)类型响应式数据let games ref([{ id: ahsgdyfa01, name: 英雄联盟 },{ id: ahsgdyfa02, name: 王者荣耀 },{ id: ahsgdyfa03, name: 原神 }])// 使用ref定义对象类型响应式数据也是深层次的let obj ref({a: {b: {c: {d: 666}}}})// 若ref接收的是对象类型内部其实也是使用的reactive函数console.log(car) // RefImpl {__v_isShallow: false, dep: undefined, // __v_isRef: true, _rawValue: {…}, _value: Proxy}console.log(car.value) // Proxy {brand: 奔驰, price: 100}console.log(car2) // Proxy {brand: 奔驰, price: 100}function changeCarPrice() {// 使用ref函数定义的响应式数据, 在js操作时, 需要带上.value, 才能碰到内部的Proxy对象car.value.price 10console.log(car.value.price);}function changeFirstGame() {// 使用ref函数定义的响应式数据, 在js操作时, 需要带上.value, 才能碰到内部的Proxy对象games.value[0].name 流星蝴蝶剑console.log(games.value); // Proxy {0: {…}, 1: {…}, 2: {…}}}function test() {// 使用ref函数定义的响应式数据, 在js操作时, 需要带上.value, 才能碰到内部的Proxy对象obj.value.a.b.c.d 999}/script3.6. 【ref 对比 reactive】
宏观角度 ref可以定义基本类型、对象类型的响应式数据 reactive只能定义对象类型的响应式数据
区别 ref创建的变量必须使用.value可以使用volar插件自动添加.value。 可以在齿轮-设置-扩展-volar中勾选 它会在使用ref创建的变量时自动添加上.value reactive重新分配一个新对象会失去响应式可以使用Object.assign去整体替换。 templatediv classpersonh2汽车信息一台{{ car.brand }}汽车价值{{ car.price }}万/h2button clickchangeBrand改品牌/buttonbutton clickchangePrice改价格/buttonbutton clickchangeCar改car/button/div
/templatescript langts setup namePersonimport { ref,reactive } from vuelet car reactive({brand:奔驰, price:100})function changeBrand() {// 正常修改car的brand, 并且是响应式car.brand 宝马
}function changePrice() {// 正常修改car的price, 并且是响应式car.price 10
}function changeCar() {// 错误做法1// 不可以直接给reactive重新分配一个新对象这会让car直接失去响应式// car {brand:奥托, price:10}// 错误做法2// 这样也不行, 因为模板中用的car是上面定义的响应式对象, // 现在car指向的是1个新的响应式对象, 而模板中压根就没有使用这个新的响应式对象// car reactive({brand:奥托, price:10})// 正确做法car仍然是响应式的// API介绍: Object.assign(obj1, obj2, obj3, ..), // 将obj2中的每一组属性和值设置到obj1中, 然后obj3的每一组属性和值设置到obj1中Object.assign(car, {brand:奥托, price:10})
}/scripttemplatediv classpersonh2汽车信息一台{{ car.brand }}汽车价值{{ car.price }}万/h2button clickchangeBrand改品牌/buttonbutton clickchangePrice改价格/buttonbutton clickchangeCar改car/button/div
/templatescript langts setup namePersonimport { ref,reactive } from vuelet car ref({brand:奔驰, price:100})function changeBrand() {// 正常修改car的brand, 并且是响应式car.value.brand 宝马
}function changePrice() {// 正常修改car的price, 并且是响应式car.value.price 10
}function changeCar() {// 错误做法1// 不能直接给car换了个ref, 因为模板中压根就没有使用这个新的RefImpl对象// car ref({brand:奥托, price:10})// 正确做法1car仍然是响应式的// API介绍: Object.assign(obj1, obj2, obj3, ..), 将obj2中的每一组属性和值设置到obj1中, // 然后obj3的每一组属性和值设置到obj1中// Object.assign(car.value, {brand:奥托, price:10})// 正确做法2//这里相比于对car使用reactive定义而言, 使用ref定义则可以直接给car.value整体赋值// 原因在于car.value获取的是Proxy响应式对象, 凡是对Proxy响应式对象的操作都可以被拦截到car.value {brand:奥托, price:10}}/script使用原则 若需要一个基本类型的响应式数据必须使用ref。 若需要一个响应式对象层级不深ref、reactive都可以。 若需要一个响应式对象且层级较深推荐使用reactive。