尚硅谷Vue3.0
1.Vue3简介2.创建Vue3工程2.1.【基于vue-cli创建】2.2.【基于vite创建】推荐2.3.【一个简单的效果】template div classperson h2姓名{{ name }}/h2 h2年龄{{ age }}/h2 button clickchangeName修改姓名/button button clickchangeAge修改年龄/button button clickshowTel点击显示电话号码/button /div /template script langts export default { name: Person, data() { return { name: 张三, age: 18, telephone: 1234567890, } }, methods: { changeName() { this.name zhang-san }, changeAge() { this.age 1 }, showTel() { alert(this.telephone) }, }, } /script style scoped .person { background-color: #90c0e7; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); border-radius: 8px; padding: 20px; } button { margin: 0 5px; } /style3.Vue3核心语法3.1.【OptionsAPI与CompositionAPI】)3.2.拉开序幕的setup原来的写法是可以读取 新写法里的内容 但是新的不可以返回旧的vue3 用 setup 来写轻易不要用两个 script 一个是配置组件名的 一个是配置 API 的3.3.【ref创建基本类型的响应式数据】的含义是要把后面的内容当成JS 去解析ref 遇到对象类型 实际代码是用 reactive 实现的3.4【reactive创建对象类型的响应式数据】3.6.【ref对t比reactive】3.7.【toRefs与toRef】3.8【computed】## 3.8. 【computed】 作用根据已有数据计算出新数据和Vue2中的computed作用一致。 img srcimages/computed.gif stylezoom:20%; / vue template div classperson 姓input typetext v-modelfirstName br 名input typetext v-modellastName br 全名span{{fullName}}/span br button clickchangeFullName全名改为li-si/button /div /template script setup langts nameApp import {ref,computed} from vue let firstName ref(zhang) let lastName ref(san) // 计算属性——只读取不修改 /* let fullName computed((){ return firstName.value - lastName.value }) */ // 计算属性——既读取又修改 let fullName computed({ // 读取 get(){ return firstName.value - lastName.value }, // 修改 set(val){ console.log(有人修改了fullName,val) firstName.value val.split(-)[0] lastName.value val.split(-)[1] } }) function changeFullName(){ fullName.value li-si } /script3.9.【watch】template div classperson h1情况一监视【ref】定义的【基本类型】数据/h1 h2当前求和为{{sum}}/h2 button clickchangeSum点我sum1/button /div /template script langts setup namePerson import {ref,watch} from vue // 数据 let sum ref(0) // 方法 function changeSum(){ sum.value 1 } // 监视情况一监视【ref】定义的【基本类型】数据 const stopWatch watch(sum,(newValue,oldValue){ console.log(sum变化了,newValue,oldValue) if(newValue 10){ stopWatch() } }) /script style scoped .person { background-color: skyblue; box-shadow: 0 0 10px; border-radius: 10px; padding: 20px; } button { margin: 0 5px; } li { font-size: 20px; } /style可以自己分析监视谁3.12. 【props】template div classperson ??? /div /template script langts setup namePerson import {type PersonInter,type Persons} from /types // let person:PersonInter {id:asyud7asfd01,name:张三,age:60} let personList:Persons [ {id:asyud7asfd01,name:张三,age:60}, {id:asyud7asfd02,name:李四,age:18}, {id:asyud7asfd03,name:王五,age:5} ] /script style scoped .person { background-color: skyblue; box-shadow: 0 0 10px; border-radius: 10px; padding: 20px; } button { margin: 0 5px; } li { font-size: 20px; } /style3.13. 【生命周期】3.14. 【自定义hook】4. 路由4.1. 【对路由的理解】template div classapp h2 classtitleVue路由测试/h2 !-- 导航区 -- div classnavigate RouterLink to/home active-classxiaozhupeiqi首页/RouterLink RouterLink to/news active-classxiaozhupeiqi新闻/RouterLink RouterLink to/about active-classxiaozhupeiqi关于/RouterLink /div !-- 展示区 -- div classmain-content RouterView/RouterView /div /div /template script langts setup nameApp import {RouterView,RouterLink} from vue-router /script style /* App */ .title { text-align: center; word-spacing: 5px; margin: 30px 0; height: 70px; line-height: 70px; background-image: linear-gradient(45deg, gray, white); border-radius: 10px; box-shadow: 0 0 2px; font-size: 30px; } .navigate { display: flex; justify-content: space-around; margin: 0 100px; } .navigate a { display: block; text-align: center; width: 90px; height: 40px; line-height: 40px; border-radius: 10px; background-color: gray; text-decoration: none; color: white; font-size: 18px; letter-spacing: 5px; } .navigate a.xiaozhupeiqi { background-color: #64967E; color: #ffc268; font-weight: 900; text-shadow: 0 0 1px black; font-family: 微软雅黑; } .main-content { margin: 0 auto; margin-top: 30px; border-radius: 10px; width: 90%; height: 400px; border: 1px solid; } /style4.3. 【两个注意点】4.5. 【to的两种写法】4.6. 【命名路由】4.7. 【嵌套路由】template div classnews !-- 导航区 -- ul li v-fornews in newsList :keynews.id RouterLink to/news/detail{{ news.title }}/RouterLink /li /ul !-- 展示区 -- div classnews-content RouterView/RouterView /div /div /template script setup langts nameNews import { reactive } from vue import { RouterView, RouterLink } from vue-router const newsList reactive([ { id: asfdtrfay01, title: 很好的抗癌食物, content: 西蓝花 }, { id: asfdtrfay02, title: 如何一夜暴富, content: 学IT }, { id: asfdtrfay03, title: 震惊万万没想到, content: 明天是周一 }, { id: asfdtrfay04, title: 好消息好消息, content: 快过年了 }, ]) /script style scoped /* 新闻 */ .news { padding: 0 20px; display: flex; justify-content: space-between; height: 100%; } .news ul { margin-top: 30px; list-style: none; padding-left: 10px; } .news li a { font-size: 18px; line-height: 40px; text-decoration: none; color: #64967e; text-shadow: 0 0 1px rgb(0, 84, 0); } .news-content { width: 70%; height: 90%; border: 1px solid; margin-top: 20px; border-radius: 10px; } /style4.8. 【路由传参】query参数params参数1. 传递参数 vue !-- 跳转并携带params参数to的字符串写法 -- RouterLink :to/news/detail/001/新闻001/内容001{{news.title}}/RouterLink !-- 跳转并携带params参数to的对象写法 -- RouterLink :to{ name:xiang, //用name跳转 params:{ id:news.id, title:news.title, content:news.title } } {{news.title}} /RouterLink 2. 接收参数 js import {useRoute} from vue-router const route useRoute() // 打印params参数 console.log(route.params) 备注1传递params参数时若使用to的对象写法必须使用name配置项不能用path。 备注2传递params参数时需要提前在规则中占位。4.9. 【路由的props配置】4.10. 【 replace属性】4.11. 【编程式导航】路由组件的两个重要的属性$route和$router变成了两个hooks4.12. 【重定向】5. pinia5.1【准备一个效果】5.2【搭建 pinia 环境】import { createApp } from vue import App from ./App.vue // 第一步引入pinia import { createPinia } from pinia const app createApp(App) // 第二步创建pinia const pinia createPinia() // 第三步安装pinia app.use(pinia) app.mount(#app)5.3【存储读取数据】1. Store是一个保存**状态**、**业务逻辑** 的实体每个组件都可以**读取**、**写入**它。 2. 它有三个概念state、getter、action相当于组件中的 data、 computed 和 methods。 3. 具体编码src/store/count.ts ts // 引入defineStore用于创建store import {defineStore} from pinia // 定义并暴露一个store export const useCountStore defineStore(count,{ // 动作 actions:{}, // 状态 state(){ return { sum:6 } }, // 计算 getters:{} }) 4. 具体编码src/store/talk.ts js // 引入defineStore用于创建store import {defineStore} from pinia // 定义并暴露一个store export const useTalkStore defineStore(talk,{ // 动作 actions:{}, // 状态 state(){ return { talkList:[ {id:yuysada01,content:你今天有点怪哪里怪怪好看的}, {id:yuysada02,content:草莓、蓝莓、蔓越莓你想我了没}, {id:yuysada03,content:心里给你留了一块地我的死心塌地} ] } }, // 计算 getters:{} }) 5. 组件中使用state中的数据 vue template h2当前求和为{{ sumStore.sum }}/h2 /template script setup langts nameCount // 引入对应的useXxxxxStore import {useSumStore} from /store/sum // 调用useXxxxxStore得到对应的store const sumStore useSumStore() /script vue template ul li v-fortalk in talkStore.talkList :keytalk.id {{ talk.content }} /li /ul /template script setup langts nameCount import axios from axios import {useTalkStore} from /store/talk const talkStore useTalkStore() /script 5.4.【修改数据】(三种方式)1. 第一种修改方式直接修改 ts countStore.sum 666 2. 第二种修改方式批量修改 ts countStore.$patch({ sum:999, school:atguigu }) 3. 第三种修改方式借助action修改action中可以编写一些业务逻辑 js import { defineStore } from pinia export const useCountStore defineStore(count, { /*************/ actions: { //加 increment(value:number) { if (this.sum 10) { //操作countStore中的sum this.sum value } }, //减 decrement(value:number){ if(this.sum 1){ this.sum - value } } }, /*************/ }) 4. 组件中调用action即可 js // 使用countStore const countStore useCountStore() // 调用对应action countStore.incrementOdd(n.value) 5.5.【storeToRefs】5.6.【getters,5.7.【$subscribe】5.8. 【store组合式写法】import {defineStore} from pinia import axios from axios import {nanoid} from nanoid import {reactive} from vue export const useTalkStore defineStore(talk,(){ // talkList就是state const talkList reactive( JSON.parse(localStorage.getItem(talkList) as string) || [] ) // getATalk函数相当于action async function getATalk(){ // 发请求下面这行的写法是连续解构赋值重命名 let {data:{content:title}} await axios.get(https://api.uomg.com/api/rand.qinghua?formatjson) // 把请求回来的字符串包装成一个对象 let obj {id:nanoid(),title} // 放到数组中 talkList.unshift(obj) } return {talkList,getATalk} })