简单梳理一下vue3【BASIC】
本文于
573
天之前发表,文中内容可能已经过时。
1. 简介 https://cn.vuejs.org/guide/introduction.html
2. 创建vue3工程【详细看vue创建前端项目的那篇】 2.1【基于 vue-cli创建】 基本和vue-cli的过程类似,只是选择的时候用vue3创建
2.2【基于vite创建】【推荐】 【官网】https://vitejs.cn/ 【可以先去学一下webpack】 vite 是新一代前端构建工具,官网地址:https://vitejs.cn,vite的优势如下 :
轻量快速的热重载(HMR),能实现极速的服务启动。
对 Typescript、Jsx、css 等支持开箱即用。
真正的按需编译、不再等待整个应用编译完成。
npm create vue@latest pnpm create vue
你还可以通过附加的命令行选项直接指定项目名称和你想要使用的模板。例如,要构建一个 Vite + Vue 项目,运行:bash
1 2 3 4 5 6 7 8 9 10 11 # npm 7+, extra double-dash is needed: npm create vite@latest my-vue-app -- --template vue # yarn yarn create vite my-vue-app --template vue # pnpm pnpm create vite my-vue-app --template vue # bun bun create vite my-vue-app --template vue
查看 create-vite 以获取每个模板的更多细节:vanilla,vanilla-ts, vue, vue-ts,react,react-ts,react-swc,react-swc-ts,preact,preact-ts,lit,lit-ts,svelte,svelte-ts,solid,solid-ts,qwik,qwik-ts。
2.4 命令行创建
3. 小结
4. VUE3核心语法 【optionsAPI】和【compositionAPI】->【vue2】和【vue3】
Vue2 的 API 设计是 options(配置)风格的。
Vue3 的API 设计是 Composition(组合)风格的。
5. 拉开序幕的【setup】
新的配置项
setup语法糖出现时机在beforecreated之前
setup的返回值也是一个渲染函数
【面试题】setup和vue2中的data、method有什么区别?
可以同时存在
setup执行的比data的早(data可以拿到setup中的值,但是反过来拿不到)
6. Setup语法糖 之前的写法 缺点是:每次都要返回数据和方法 语法糖写法 不需要返回,setup自动给你返回;只关注数据和方法 因为最新的语法糖省去了name,则利用插件npm i vite-plugin-vue-setup-extend -D来命名 一般其实和文件名一样可以不写
7. ref_可以实现【基本类型】响应式数据 【让数据动起来】 vue2->都放在data中,就是响应式了 vue3->ref 和 reative 此ref不是vue2中的ref
什么时候需要value和什么时候不需要value是需要注意的点
模块中不需要。JS中操作需要!
作用:
8. reactive_创建【对象类型】【只能定义】响应式数据
9. ref_可以实现【对象类型】响应式数据 【让数据动起来】 需要注意的是:
使用ref的时候必须加上.value去拿到值
ref的实现也是基于reactive实现的(底层逻辑)
ref既可以定义基本类型也可以对象类型
10.【ref对比reactive】
可以用volar插件【目前是官方vue插件】自动添加.value
在设置中进行设置-勾上即可
11. toRefs 和 toRef
1 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 27 28 29 <template> <h1>hello</h1> <h1>姓名:{{ name }}</h1> <h1>年龄:{{ age}}</h1> <button @click="changeName">修改名字</button> <button @click="changeAge">修改年龄</button> </template> <script setup lang="ts"> import { reactive,toRefs } from 'vue'; let person = reactive({ name: 'John', age:22 }) // toRefs 就是将reactive中的数据都取出来 数据还是具备响应式 let {name, age} = toRefs(person) const changeName = () =>{ name.value = 'lisi' } const changeAge = () =>{ age.value += 1 } </script> <style> </style>
12. computed属性【是有缓存的与vue2一致】
1 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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <template> 姓:<input type="text" v-model="names"><br> 名:<input type="text" v-model="ming"><br> 姓名: <h1>{{fullname}}</h1> <button @click="changeFullname">修改全名</button> </template> <script setup lang="ts"> import { ref ,computed} from 'vue'; let names= ref('张三') let ming = ref('ming') // 只读的不可修改的 // let fullname =computed(()=>{ // return names.value + ming.value.slice(0,1).toUpperCase() + ming.value.slice(1) // }) // 这样可读可写 let fullname =computed({ get(){ return names.value + ming.value.slice(0,1).toUpperCase() + ming.value.slice(1) }, set(vals){ const x = vals.split('-') names.value = x[0] ming.value = x[1] console.log(x); }, }) let changeFullname = ()=>{ console.log(fullname.value); fullname.value = 'li-si' } </script> <style> </style>
13. watch监视数据的变化
13.1 情况一【常用】: 监视 ref 定义的【基本类型】数据:直接写数据名即可,监视的是其 value 值的改变。
1 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 27 <template> <div class="person"> <h1>情况一</h1> <h1>sum:{{ sum }}</h1> <button @click="changeName">点我sum+1</button> </div> </template> <script setup lang="ts"> import {ref,watch} from 'vue' let sum = ref(100) let changeName = ()=>{ sum.value += 100 } const stopWatch = watch(sum,(newValue,oldValue)=>{ console.log(newValue,oldValue); if(newValue>1000){ stopWatch() } }) </script> <style> </style>
13.2 情况二:
1 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 27 28 29 30 31 32 33 34 35 36 37 38 <template> <div class="person"> <h1>姓名:{{person.name }}</h1> <h2>年龄:{{person.age}}</h2> <button @click="changename">修改年龄</button> <button @click="changeperson">修改person</button> </div> </template> <script lang="ts" setup> import {ref,watch} from 'vue' let person = ref({ name:"zhangsan", age:22, }) const changename = () =>{ person.value.age += 1; } const changeperson = () =>{ // 如果是recative 就要用object.assgin person.value = {name:"zha33ngsan", age:2342} } watch(person,(newValue,oldValue)=>{ console.log(newValue,oldValue); },{deep:true,immediate:true}) </script> <style> .person{ background-color: skyblue; box-shadow: 0 0 10px; border-radius: 10px; padding: 10px; } </style>
13.3 情况三:
1 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 27 28 29 30 31 32 33 34 35 36 37 38 <template> <div class="person"> <h1>姓名:{{person.name }}</h1> <h2>年龄:{{person.age}}</h2> <button @click="changename">修改年龄</button> <button @click="changeperson">修改person</button> </div> </template> <script lang="ts" setup> import {ref,watch,reactive} from 'vue' let person = reactive({ name:"zhangsan", age:22, }) const changename = () =>{ person.age += 1; } const changeperson = () =>{ // 如果是recative 就要用object.assgin Object.assign(person,{name:"zha33ngsan", age:2342}) } watch(person,(newValue,oldValue)=>{ console.log(newValue,oldValue); }) </script> <style> .person{ background-color: skyblue; box-shadow: 0 0 10px; border-radius: 10px; padding: 10px; } </style>
13.4 情况四【常用】【函数式】:
结论: 监视的要是对象里面的属性,最好写成函数,注意:若是监视的是地址值,需要关注对象内部。需要开启手动深度监视
1 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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <template> <div class="person"> <h1>姓名:{{person.name }}</h1> <h2>年龄:{{person.age}}</h2> <h2>汽车:{{person.car.car1}}-{{ person.car.car2 }}</h2> <button @click="changename">修改年龄</button> <button @click="changeperson">修改person</button> <button @click="changeCar1">修改car1</button> <button @click="changeCar2">修改car2</button> <button @click="changeAll">修改全部</button> </div> </template> <script lang="ts" setup> import {ref,watch,reactive} from 'vue' let person = reactive({ name:"zhangsan", age:22, car:{ car1:'hello1', car2:'hello2' } }) const changename = () =>{ person.age += 1; } const changeperson = () =>{ // 如果是recative 就要用object.assgin Object.assign(person,{name:"zha33ngsan", age:2342}) } const changeCar1 = ()=>{ person.car.car1 = 'world1' } const changeCar2 = ()=>{ person.car.car2 = 'world2' } const changeAll = ()=>{ person.car = {car1:'hello221', car2:'hello241'} } watch(()=>{return person.age},(newValue,oldValue)=>{ console.log(newValue,oldValue); }) watch(()=>person.car,(newValue,oldValue)=>{ console.log(newValue,oldValue); },{deep:true}) </script> <style> .person{ background-color: skyblue; box-shadow: 0 0 10px; border-radius: 10px; padding: 10px; } </style>
13.5 情况五: 监视上述的多个数据【多个函数】
1 2 3 watch([()=>person.name,()=>person.car.car1],(newValue,oldValue)=>{ console.log(newValue,oldValue); },{deep:true})
【多写项目-练习】
14. watchEffect )
15. 标签中ref属性
16. 回顾TS中的接口_泛型_自定义类型
17. Props的使用 vue2【父子之间的通信】 vue3通信 注意点:【区别一下:的绑定和 ref的区别】 【父子之间的传值的多种方式】 【注意:宏函数不用引入,例如defineProps】
18. 理解生命周期【组件的一生】 概念: vue 组件实例在创建时要经历一系列的初始化步骤,在此过程中 vue 会在合适的时机,调用特定的函数,从而让开发者有机会在特定阶段运行自己的代码,这些特定的函数统称为:生命周期钩子创建、挂载、更新、销毁【每个时期都调用特定的函数】created 、 mounted 、updated 、destoyed叫法:生命周期、生命周期函数、生命周期钩子。
18.1 vue2的生命周期 创建、(前与后)(beforeCreate|Created) 挂载、(前与后)(beforeMount|Mounted) 更新、(前与后)(beforeUpdate|updated) 销毁、(前与后)(beforeDestory|destoryed)
18.2 vue3的生命周期 创建、setup —————————-> (前与后)(beforeCreate|Created) 挂载、onBeforeMount|onMounted—>(前与后)(beforeMount|Mounted) 更新、onBeforeUpdate|onUpdated—>(前与后)(beforeUpdate|updated) 卸载、onBeforeUnmount|onUnmounted—->(前与后)(beforeDestory|destoryed)
19. 自定义hooks【mixin】【重】
20【….】. 路由
20.1 两个注意点 路由组件:pages/views 一般组件:components
20.2 to的两种写法
20.3 路由器工作模式 【history 和 hash模式】
20.4 命名路由
20.5 嵌套路由
20.6 路由_query参数
20.7 路由_params参数
必须为name
参数如果可传可不传则添加?在占位的地方
参数不能为数组和对象
21. 路由的Props配置
【注意】
22. 路由的_replace属性
23.【编程式导航】
出了routerlink进行跳转还有编程式路由导航
24. 路由重定向
25. Pinia【对比VUE2中vuex】【集中式状态数据管理】 【redux vuex pinia】 是vue的最新的状态管理工具,是vuex的替代品
26. 手动添加pinia 官网:https://pinia.vuejs.org/zh/introduction.html
使用vite创建一个新的vue3项目
安装pinia到项目中
用vite安装时注意node的版本
26.1 案例 lovetalk.vue
1 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 27 28 29 30 31 32 33 34 35 36 37 38 <template> <div class="lovetalk"> <button @click="getLoveTalk">hello</button> <ul> <li v-for="item in newsList" :key="item.id">{{ item.title }}</li> </ul> </div> </template> <script lang="ts" setup> import { reactive } from 'vue'; import axios from 'axios'; import { nanoid } from 'nanoid'; const newsList = reactive([ { id: '12423421', title: 'hel123' }, { id: '1224231', title: 'h424el123' }, { id: '1242341', title: 'he4243l123' }, ]); async function getLoveTalk() { // 下面的写法:连续解构赋值 + 重命名 let { data: { content:title }, } = await axios.get('https://api.uomg.com/api/rand.qinghua?format=json'); // nanoid 可以随机生成ID let obj = { id: nanoid(),title}; console.log(obj); newsList.unshift(obj); } </script> <style> .lovetalk { background-color: skyblue; box-shadow: 0 0 10px; border: 1px solid black; } </style>
count.vue
1 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 27 28 29 30 31 32 <template> <div class="count"> <h2>当前求和为:{{sum}}</h2> <select v-model.number="n"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> </select> <button @click="add">加</button> <button @click="minus">减 </button> </div> </template> <script setup lang="ts"> import {ref} from 'vue' let sum = ref(1) let n = ref(1) function add(){ sum.value += n.value } function minus(){ sum.value -= n.value } </script> <style> .count { background-color: skyblue; box-shadow: 0 0 10px; border: 1px solid black; } </style>
【注意】:引入了axios和nanoid【随机生成id】
26.2 搭建pinia环境 npm i pinia
26.3 存取读取数据
27. 修改数据的三种方式
28. storeToRefs【只关注store数据】【对数据进行解构操作】
29. getters 对数据的加工
30. $subscribe
31. store的组合式写法【推荐】
32. 组件通信_方式1_props 【父子】
33. 组件通信_方式2_自定义事件【子传父】
34. 组件通信_方式3_mitt【任意组件通信】
35. 组件通信_方式4_v-model【通常用于表单】 作用在组件和html的方式【底层】
36. 组件通信_方式5_$atters【祖孙之间通信】【打扰了中间人】
37. 组件通信_方式6_$refs-$parent【父->子|子->父】
38. 组件通信_方式7_provide_inject【提供-注入】【向后代之间通信】【零打扰】
39. 插槽 39.1 默认插槽
39.2 具名插槽【template 中 v-solt & #】【重】【动态的摆放】 可以用【#s1 、#s2代替v-slot】
39.3 作用域插槽
40. 总结
41. 其他API 41. shallowRef 和 shallowReactive
41.2 readonly 和 shallowReadonly
41.3 roRaw 和 markRow
41.4 customRef
41.5 Teleport【转移】
41.6 Suspense
41.7 全局api到应用对象
41.8 其他【非兼容性改变】
41.9 面试题:vue3相比vue2做了哪些改变? https://v3-migration.vuejs.org/zh/breaking-changes/