刘金鹏做网站在哪里找工厂采购信息
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:28
当前位置: 首页 > news >正文
刘金鹏做网站,在哪里找工厂采购信息,免费软件的特征,wordpress建淘宝客网站教程Vue3学习 1. Vue3新的特性 2. 创建Vue3工程2.1 基于 vue-cli 创建项目文件说明 2.2 基于 vite 创建具体操作项目文件说明 2.3 简单案例(vite) 3. Vue3核心语法3.1 OptionsAPI 与 CompositionAPIOptions API 弊端Composition API 优势 ⭐3.2 setup小案例setup返回值setup 与 Opt… Vue3学习 1. Vue3新的特性 2. 创建Vue3工程2.1 基于 vue-cli 创建项目文件说明 2.2 基于 vite 创建具体操作项目文件说明 2.3 简单案例(vite) 3. Vue3核心语法3.1 OptionsAPI 与 CompositionAPIOptions API 弊端Composition API 优势 ⭐3.2 setup小案例setup返回值setup 与 Options API 的关系setup语法糖 3.2 refref 创建基本类型的响应式数据ref 创建对象类型的响应式数据 3.3 reactivereactive 创建对象类型的响应式数据 3.4 ref 对比 reactive区别使用原则 3.5 toRefs 与 toRef3.6 computed3.7 watch情况一情况二情况三情况四情况五 3.8 watchEffect3.9 标签中的ref属性回顾TSvue文件路径 3.10 props使用reactive和泛型一起用示例 3.11 生命周期3.12 自定义hooks 1. Vue3 新的特性 Composition API组合API setup ref与reactive computed与watch … 新的内置组件 Fragment Teleport Suspense … 其他改变 新的生命周期钩子 data 选项应始终被声明为一个函数 移除keyCode支持作为 v-on 的修饰符 …
创建Vue3工程 2.1 基于 vue-cli 创建 点击查看官方文档 备注目前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 serve具体步骤 ① 项目名字不可以大写英文 ②
③ 进入文件夹运行 项目文件说明 /src/main.js 入口文件 import { createApp } from vue /* 这里引入的不再是vue构造函数了在vue2中 import Vue from vue vue3 引入的是一个名为 creatApp 的工厂函数 区别是 vue 构造函数需要通过new调用工厂函数可以直接调用creatApp /import App from ./App.vue// 直接调用 createApp函数 // 把外壳组件 App 传递进去 // #app是页面上容器的 id createApp(App).mount(#app) / 不简写 const app createApp(App) 创建应用实例对象app 类似vue2中的vm但app更轻 app.mount(#app) 挂载 // vue2写法: new Vue({el: #app, //容器 })或者 new Vue({render:(h)h(App) }).\(mount(#app)或者 const vm new Vue({render:(h)h(App) })vm.\)mount(#app)*/vue3组件中可以没有 根标签 2.2 基于 vite 创建 vite 是新一代前端构建工具官网地址https://vitejs.cn。 vite的优势如下 轻量快速的热重载HMR 热重载的意思是改代码之后局部刷新能实现极速的服务启动。 对 TypeScript、JSX、CSS 等支持开箱即用。 真正的按需编译不再等待整个应用编译完成。 webpack构建 与 vite构建对比图如下 webpack 分析路由、模块进行打包服务器准备8080。所以我们每次执行npm run serve时都需要等待一段时间等的就是打包的过程 vite先打开服务器 具体操作 点击查看官方文档1.创建命令
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具体步骤 Need to install the following packages: create-vue3.10.2 Ok to proceed? (y) y 项目文件说明 .vscode/extensions.json 官方推荐的插件 public/favicon.ico 页签图标 src/ 源代码文件 .gitignore git的忽略文件 env.d.ts 该文件只有一一行/// reference typesvite/client /且飘红飘红的原因是当前没有 node_modules没有依赖在命令行 npm i 安装重新打开 vs code就不红了。 .ts文件不认识 .jpg .txt这个文件的目的就是让ts认识他们。 index.html 入口文件与webpack区别 package.json 、package-lock.json 包管理文件 REANME.md可以删除 tsconfig.app.json, tsconfig.json, tsconfig.node.json是ts的配置文件 vite.config.ts 整个工程的配置文件 src文件夹说明 入口文件 index.html把 /src/main.ts 引入 main.ts import ./assets/main.css // 引入样式import { createApp } from vue // 创建应用花盆 import App from ./App.vue // 组件植物的根createApp(App).mount(#app) //挂载到 index.html 的 app div里面总结 Vite 项目中index.html 是项目的入口文件在项目最外层。加载index.html后Vite 解析 script typemodule src/src/main.ts/script 指向的typescript。Vue3 中是通过 createApp 函数创建一个应用实例。 2.3 简单案例(vite) 注意当前笔记及之后 都是使用 vite 创建的工程 这个案例证明了vue3可以写vue2的代码 ① script langts这里写明是 ts /components/Person.vue templatediv classpersonh2姓名{{ name }}/h2h2年龄{{ age }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickshowTel点击查看联系方式/button/div /templatescript langts export default {name: Person,data() {return {name: 张三,age: 18,tel: 11111111111111}},methods: {changeName(){this.name zhang-san},changeAge(){this.age},showTel(){alert(this.tel)}}, } /scriptstyle .person {background-color: skyblue; } button {margin: 0 5px; } /style/App.vue 对person组件①引用import ②注册components ③使用 templatediv classhahah1你好啊/h1Person/Person/div /templatescript langtsimport Person from ./components/Person.vueexport default {name: App,components: {Person}} /scriptstyle .haha{background-color: pink; } /style3. Vue3核心语法 3.1 OptionsAPI 与 CompositionAPI Vue2的API设计是Options配置风格的。Vue3的API设计是Composition组合风格的。 Options API 弊端 选项式/配置式写法 学习vue2就是在学习配置项 data、methods、components。 Options类型的 API数据、方法、计算属性等是分散在data、methods、computed中的若想新增或者修改一个需求就需要分别修改data、methods、computed不便于维护和复用。 Composition API 优势 可以用函数的方式更加优雅的组织代码让相关功能的代码更加有序的组织在一起。 ⭐3.2 setup setup是Vue3中一个新的配置项值是一个函数它是 Composition API “表演的舞台”组件中所用到的数据、方法、计算属性、监视…等等均配置在setup中。 小案例 下文案例的问题数据不是响应式之后会讲 注意事项 ① setup中的函数没有维护 this。在setup函数中 console.log(this)值为undefined ② setup函数的时机setup比vue2中的 beforeCreate时机早之后会讲 templatediv classpersonh2姓名{{ name }}/h2h2年龄{{ age }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickshowTel点击查看联系方式/button/div /templatescript langts export default {name: Person,// data() {// return {// name: 张三,// age: 18,// tel: 11111111111111// }// },// methods: {// changeName(){// this.name zhang-san// },// changeAge(){// this.age// },// showTel(){// alert(this.tel)// }// },setup() {// 数据// 如果这么简单的定义数据那就不是响应式数据// 响应式后续数据变化 页面上也变化let name 张三let age 18let tel 1388888// 方法function changeName(){// this.name ???// 这样写是错的vue在setup中没有维护this关键字 // console.log(this) undefinedname zhang-san}function changeAge(){age 1}function showTel(){alert(tel)}// 返回数据和函数return {name,age,changeName,changeAge,showTel}} } /scriptstyle .person {background-color: skyblue; } button {margin: 0 5px; } /stylesetup返回值 setup的返回值是对象把数据、方法交出去 setup() {…return {name,age,changeName,changeAge,showTel} }setup的返回值如果是一个函数的话会直接渲染页面内容 setup(){…return function() {哈哈} }或者 setup(){…return () 哈哈 //因为setup不维护this 所以可以直接简写为箭头函数 } setup 与 Options API 的关系 面试题 ① data 、methods 、setup可以同时存在 ② Vue2 的配置data、methos…中可以访问到 setup中的属性、方法。因为setup是最早的生命周期当data去读数据的时候setup已经有数据了 ③ 但在setup中不能访问到Vue2的配置data、methos…。 ④ 如果与Vue2冲突则setup优先。 templatediv classpersonh2姓名{{ name }}/h2h2年龄{{ age }}/h2hrh2测试data读到setup中的数据{{ b }}/h2h2测试setup中无法读到data中的数据/h2/div /templatescript langts export default {name: Person,data() {return {// 测试a: 100,b: this.name,d: 900}},setup() {let name 张三let age 18let tel 1388888// 测试// let s d // Cannot find name d. return {name,age}} } /scriptsetup语法糖 setup函数有一个语法糖这个语法糖可以让我们把setup独立出去代码如下 templatediv classpersonh2姓名{{ name }}/h2h2年龄{{ age }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickshowTel点击查看联系方式/button/div /templatescript langts export default {name: Person } /scriptscript langts setuplet name 张三let age 18let tel 1388888// 方法function changeName(){ name zhang-san}function changeAge(){age 1}function showTel(){alert(tel)} /script扩展 上述代码还需要编写一个不写setup的script标签在开发者工具去指定组件名字比较麻烦我们可以借助vite中的插件简化。 第一步npm i vite-plugin-vue-setup-extend -D D是开发依赖的意思 第二步vite.config.ts 中引入 import VueSetupExtend from ‘vite-plugin-vue-setup-extend’ 第三步script setup langts namePerson
这样就只用一个script标签了 templatediv classpersonh2姓名{{ name }}/h2h2年龄{{ age }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickshowTel点击查看联系方式/button/div /templatescript langts setup namePerson2222let name 张三let age 18let tel 1388888// 方法function changeName(){ name zhang-san}function changeAge(){age 1}function showTel(){alert(tel)} /script如果【不】添加这个插件同时也只写一个script标签开发者工具中的组件名字和文件名保持一致。 3.2 ref 上文案例中的数据方法此时数据不是响应式的 vue2中数据都存放在data里面只要把数据放在data里面数据就是响应式会自动数据代理、数据劫持。 在vue3中有两个东西定义响应式数据 ① ref ②reactive ref 创建基本类型的响应式数据 作用 定义响应式变量。 语法 先引入 import {ref} from vue 哪个数据是响应式就用ref包起来 let xxx ref(初始值)。 ref() 返回值 一个RefImpl的实例对象简称ref对象或refref对象的value属性是响应式的。 注意点 JS中操作数据需要xxx.value但模板中不需要.value直接使用即可。对于let name ref(张三)来说name不是响应式的name.value是响应式的。 script langts setup namePerson// 引入refimport {ref} from vue// 哪个数据是响应式就用ref包起来let name ref(张三)let age ref(18)let tel 1388888let address 北京昌平区console.log(name,name);console.log(age,age);console.log(tel,tel);console.log(address,address); /script name、age是 RefImpl 的实例对象 目前先知道 下划线的属性都不是给我们用的value才是给我们用的。而且模板(HTML)内自动帮我们解析了value所以模板中使用的时候不需要 {{name.value}}使用直接{{name}}就可以。但是在JS代码中需要写 name.value ref 创建对象类型的响应式数据 其实ref接收的数据可以是基本类型、对象类型。若ref接收的是对象类型内部其实也是调用了reactive函数。 templatediv classcarh2一辆{{ car.brand }}车,价值{{ car.price }}万/h2button clickchangePrice修改汽车价格/button/divhrh2游戏列表/h2ulli v-foritem in games :keyitem.id{{item.name}}/li/ulbutton clickchangeFirstGame修改游戏/button /templatescript langts setup namePersonimport {ref} from vuelet car ref({brand: 奔驰, price: 100})console.log(car); // 这个对象let games ref([{id:001, name:王者荣耀},{id:002, name:原神},{id:003, name:三国志}])function changePrice(){car.value.price 10}function changeFirstGame(){games.value[0].name 星穹铁道} /script3.3 reactive reactive 创建对象类型的响应式数据 作用定义一个响应式对象基本类型不要用它要用ref否则报错 语法 引入reactive import {reactive} from vue 哪个对象想变成响应式就包裹住哪个let 响应式对象 reactive(源对象)。 源对象可以是 对象、数组、函数 返回值 一个Proxy的实例对象简称响应式对象。 注意点reactive定义的响应式数据是 深层次 的。 templatediv classcarh2一辆{{ car.brand }}车,价值{{ car.price }}万/h2button clickchangePrice修改汽车价格/button/div /templatescript langts setup namePersonimport {reactive} from vuelet car reactive({brand: 奔驰, price: 100})console.log(car); // 这个对象function changePrice(){car.price 10} /script打印这个car 这个Proxy是window上就有的一个函数 Proxy。数据藏在 target 里面 3.4 ref 对比 reactive 宏观角度看 1、ref用来定义基本类型数据、对象类型数据 2、reactive用来定义对象类型数据。 区别 1、ref创建的变量必须使用.value可以使用volar插件自动添加.value。 2、reactive重新分配一个新对象会失去响应式可以使用Object.assign去整体替换。 注意在ref中整体替换就是可以的。因为 ref 的响应式体现在 car.value这个值变了 响应式可以检测到。 使用原则 1、若需要一个基本类型的响应式数据必须使用ref。 2、若需要一个响应式对象层级不深ref、reactive都可以。 3、若需要一个响应式对象且层级较深推荐使用reactive。 3.5 toRefs 与 toRef 作用将一个响应式对象中的每一个属性转换为ref对象。 备注toRefs与toRef功能一致但toRefs可以批量转换。 语法如下 // 数据 let person reactive({name:张三, age:18, gender:男})// 通过toRefs将person对象中的n个属性批量取出且依然保持响应式的能力 let {name,gender} toRefs(person)// 通过toRef将person对象中的gender属性取出且依然保持响应式的能力 let age toRef(person,age)示例 加入toRefs script langts setup namePersonimport {reactive, toRefs} from vuelet person reactive({name: 张三,age: 18})let {name, age} toRefs(person)function changeName() {name.value ~}function changeAge() {age.value 1} /script3.6 computed 计算属性是有缓存的、方法没有 使用方式import {computed} from vue computed是一个函数实参是函数因为vue3中没有this所以用箭头函数 必须要使用 set get才能对计算属性进行修改 script langts setup namePersonimport {ref,computed} from vuelet firstName ref(张)let lastName ref(三)// 这么定义的fullName是一个计算属性只读、不可以修改let fullName computed((){return firstName.value - lastName.value })// 上述的fullName是 ComputedRefImpl{}// 这么定义的fullName是一个计算属性可读可写let fullName2 computed({get(){return firstName.value - lastName.value },set(val){const [str1, str2] val.split(-)firstName.value str1lastName.value str2}})function changeName(){fullName2.value 李-四}/script3.7 watch watch作用监视数据的变化和Vue2中的watch作用一致 特点Vue3中的watch只能监视以下四种数据 ref定义的数据。ref能定义基本类型和对象类型reactive定义的数据。一个函数返回一个值也就是一个getter函数。一个包含上述内容的数组。 我们在Vue3中使用watch的时候通常会遇到以下几种情况 情况一 情况一监视ref定义的【基本类型】数据直接写数据名即可监视的是其value值的改变。 使用 引入watch import {ref, watch} from vue。watch是函数有很多参数目前只看两个 watch(监视对象回调) 回调函数的参数是newValue, oldValue因为setup中没有thisundefined所以可以直接写成箭头函数。 示例 templatediv classpersonh1情况一监视【ref】定义的【基本类型】数据/h1h2当前求和为{{sum}}/h2button clickchangeSum点我sum1/button/div /templatescript langts setup namePerson// 引入watchimport {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注意事项 ① watch 里面的 sum监视的ref的数据不写value ② 解除监视 watch的返回值是一个函数调用这个函数就可以结束监视 情况二 监视ref定义的【对象类型】数据直接写数据名监视的是对象的【地址值】若想监视对象内部的数据要手动开启深度监视。 注意 若修改的是ref定义的对象中的属性newValue 和 oldValue 都是新值因为它们是同一个对象。 若修改整个ref定义的对象newValue 是新值 oldValue 是旧值因为不是同一个对象了。 watch的第一个参数是被监视的数据 watch的第二个参数是监视的回调新值旧值 watch的第三个参数是配置对象deep、immediate等等….. templatediv classpersonh1情况二监视【ref】定义的【对象类型】数据/h1h2姓名{{ person.name }}/h2h2年龄{{ person.age }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickchangePerson修改整个人/button/div /templatescript langts setup namePersonimport {ref,watch} from vue// 数据let person ref({name:张三,age:18})// 方法function changeName(){person.value.name ~}function changeAge(){person.value.age 1}function changePerson(){person.value {name:李四,age:90}}/* 监视【ref】定义的【对象类型】数据监视的是对象的地址值若想监视对象内部属性的变化需要手动开启深度监视deepwatch的第一个参数是被监视的数据watch的第二个参数是监视的回调watch的第三个参数是配置对象deep、immediate等等….. /watch(person,(newValue,oldValue){console.log(person变化了,newValue,oldValue)},{deep:true})/script注意事项 有些时候 newValue oldValue是一样的
若修改的是ref定义的对象中的属性newValue 和 oldValue 都是新值因为它们是同一个对象。 情况三 监视reactive定义的【对象类型】数据且 默认开启了深度监视。且不能关闭即不能通过deep:false关闭深度监视隐式创建深层监听。 templatediv classpersonh1情况三监视【reactive】定义的【对象类型】数据/h1h2姓名{{ person.name }}/h2h2年龄{{ person.age }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickchangePerson修改整个人/buttonhrh2测试{{obj.a.b.c}}/h2button clicktest修改obj.a.b.c/button/div /templatescript langts setup namePersonimport {reactive,watch} from vue// 数据let person reactive({name:张三,age:18})let obj reactive({a:{b:{c:666}}})// 方法function changeName(){person.name ~}function changeAge(){person.age 1}function changePerson(){Object.assign(person,{name:李四,age:80})}function test(){obj.a.b.c 888}// 监视情况三监视【reactive】定义的【对象类型】数据且默认是开启深度监视的watch(person,(newValue,oldValue){console.log(person变化了,newValue,oldValue)})watch(obj,(newValue,oldValue){console.log(Obj变化了,newValue,oldValue)}) /script情况四 监视ref或reactive定义的【对象类型】数据中的某个属性注意点如下 若该属性值不是【对象类型】需要写成函数形式。若该属性值是依然是【对象类型】可直接写也可写成函数建议写成函数。 结论监视的要是对象里的属性那么最好写函数式因为setup中没有this所以直接写箭头函数注意点如果要同时① 监视对象属性的地址值②需要关注对象内部需要手动开启深度监视。 templatediv classpersonh1情况四监视【ref】或【reactive】定义的【对象类型】数据中的某个属性/h1h2姓名{{ person.name }}/h2h2年龄{{ person.age }}/h2h2汽车{{ person.car.c1 }}、{{ person.car.c2 }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickchangeC1修改第一台车/buttonbutton clickchangeC2修改第二台车/buttonbutton clickchangeCar修改整个车/button/div /templatescript langts setup namePersonimport {reactive,watch} from vuelet person reactive({name: 张三,age: 18,car: {c1: 奔驰,c2: 宝马}})// 方法function changeName(){person.name ~}function changeAge(){person.age 1}function changeC1(){person.car.c1 奥迪}function changeC2(){person.car.c2 大众}function changeCar(){// 这里可以直接赋值更换因为这是person内部的一个属性person.car {c1:雅迪,c2:爱玛}}// 监视person对象里面的 name属性不是对象类型watch(()person.name,(newValue,oldValue){console.log(person.name,newValue,oldValue);})接上文代码如果想监视 person.car(这个属性是一个对象属性)watch的第一个参数可以直接写 person.car 但是 当执行函数changeCar的时候无法监视。因为这段代码的意思是监视这个 person.car当changeCar函数把整个car都换了的时候就无法监视到原本的car。 watch(person.car,(newValue,oldValue){console.log(person.car,newValue,oldValue); })因此如果需要监视原本 person.car 的地址值的时候就需要用函数包裹起来如下文代码。但此时 修改第一辆第二辆车的时候又没法检测到了因为地址值没有变化。 watch(()person.car,(newValue,oldValue){console.log(person.car,newValue,oldValue);
})怎么同时检测呢加一个deep:true watch(()person.car,(newValue,oldValue){console.log(person.car,newValue,oldValue);
},{deep:true})情况五 监视上述的多个数据
templatediv classpersonh1情况五监视上述的多个数据/h1h2姓名{{ person.name }}/h2h2年龄{{ person.age }}/h2h2汽车{{ person.car.c1 }}、{{ person.car.c2 }}/h2button clickchangeName修改名字/buttonbutton clickchangeAge修改年龄/buttonbutton clickchangeC1修改第一台车/buttonbutton clickchangeC2修改第二台车/buttonbutton clickchangeCar修改整个车/button/div /templatescript langts setup namePersonimport {reactive,watch} from vue// 数据let person reactive({name:张三,age:18,car:{c1:奔驰,c2:宝马}})// 方法function changeName(){person.name ~}function changeAge(){person.age 1}function changeC1(){person.car.c1 奥迪}function changeC2(){person.car.c2 大众}function changeCar(){person.car {c1:雅迪,c2:爱玛}}// 监视情况五监视上述的多个数据watch([()person.name,person.car],(newValue,oldValue){console.log(person.car变化了,newValue,oldValue)},{deep:true})/script3.8 watchEffect 官网立即运行一个函数同时响应式地追踪其依赖并在依赖更改时重新执行该函数。 watch对比watchEffect 都能监听响应式数据的变化不同的是监听数据变化的方式不同 watch要明确指出监视的数据 watchEffect不用明确指出监视的数据函数中用到哪些属性那就监视哪些属性。 示例 需求当水温达到60度或水位达到80cm时给服务器发请求。 为什么要引入watcheffect因为如果同时检测的数据多了每一个都要写进数据里很不方便。 templatediv classpersonh2需求当水温达到60度或水位达到80cm时给服务器发请求/h2h2当前水温{{temp}}℃/h2h2当前水位{{height}}cm/h2button clickchangeTemp水温10/buttonbutton clickchangeHeight水位10/button/div /templatescript langts setup namePersonimport {ref,watch,watchEffect} from vue// 数据let temp ref(10)let height ref(0)// 方法function changeTemp(){temp.value 10}function changeHeight(){height.value 10}// 监视 – watch实现 / watch([temp,height],(value){// 从value中获取最新的水温(newTemp)、最新的水位(newHeight)// 数组解构赋值let [newTemp,newHeight] value // 逻辑if(newTemp 60 || newHeight 80){console.log(给服务器发请求)}}) */// 监视 – watchEffect实现watchEffect((){if(temp.value 60 || height.value 80){console.log(给服务器发请求)}}) /script3.9 标签中的ref属性 为什么要引入ref属性在vue文件的 templateHTML部分可能会用 id 表示一个标签的唯一性。但是打包合并文件的时候不同vue文件的HTML会合并到一起如果多个组件用了同一个id名字例如div idtitle哈哈/div会有冲突。所以要用ref属性。 用法 ① 引入import {ref} from vue ② 通过 ref 创建一个东西 用于存储其标记的内容 let title ref() ③ HTML中 h2 reftitle北京/h2 作用 用于注册模板引用。 ① 用在普通DOM标签上获取的是DOM节点。 ② 用在组件标签上获取的是组件实例对象。 示例 用在普通DOM标签上获取的是DOM节点 templatediv classpersonh1中国/h1h2 reftitle2北京/h2h3尚硅谷/h3button clickshowLog点我输出h2这个元素/button/div /templatescript langts setup namePersonimport {ref} from vue// 创建一个title2用于存储ref标记的内容let title2 ref()console.log(title2);function showLog(){console.log(title2.value) // h2 data-v-4cadc14e北京/h2console.log(title2.value.innerHTML) // 北京} /script控制台输出h2 data-v-4cadc14e北京/h2输出的是DOM节点 注意这里的 data-v-4cadc14e 是因为 style 上加了 scoped 局部样式ref 用在组件标签上获取的是组件实例对象。 注意 ref 如果用在组件标签上肯定是父标签在其文件中使用因为父标签中才会使用子组件。因此 父组件获取了子组件的实例对象。但是不能轻易获得子组件里面的数据必须是子组件通过defineExpose暴露的数据才可以访问。 补充vue3 中父组件中只需① 引入组件import② 使用不需要注册。因为是在setup中写的代码。 !– 父组件App.vue – templatePerson refren/button clicktest测试/button /templatescript langts setup nameAppimport Person from ./components/Person.vueimport {ref} from vuelet ren ref()function test(){console.log(ren.value.name)console.log(ren.value.age)} /script!– 子组件Person.vue中要使用defineExpose暴露内容 – script langts setup namePersonimport {ref,defineExpose} from vue// 数据let name ref(张三)let age ref(18)/*************************//*************************/// 使用defineExpose将组件中的数据交给外部defineExpose({name,age}) /script回顾TS 引入的时候如果要引入这个 /types/index.js 只用写到 /types里面的 index.js会自动补上 vue文件路径 表示在 src 文件夹 示例接口、泛型、自定义类型 /src/types/index.js // 定义一个接口用于限制person对象的具体属性 export interface PersonInter {id: string,name: string,age: number }// 一个自定义类型 // export type Persons ArrayPersonInter export type Persons PersonInter[]/src/components/Person.vue //因为这里不是具体的值 所以要加一个type import {type PersonInter,type Persons} from /types// 定义一个person对象要符合PersonInter接口规范 let person:PersonInter {id:1111, name:张三,age:60} console.log(person);// 定义一个数组它里面的每一项都符合PersonInter规范 let personList:ArrayPersonInter [{id:1111, name:张三,age:25},{id:2222, name:李四,age:20},{id:3333, name:王五,age:30} ]let personList2:Persons [{id:1111, name:张三,age:25},{id:2222, name:李四,age:20},{id:3333, name:王五,age:30} ]3.10 props使用 父组件要把数据给子组件 reactive和泛型一起用 import {reactive} from vueimport {type Persons} from /typeslet personList reactivePersons([{id:1111, name:张三,age:25},{id:2222, name:李四,age:20},{id:3333, name:王五,age:30}])示例 父组件要把数据给子组件 接口 // 定义一个接口限制每个Person对象的格式 export interface PersonInter { id:string, name:string,age:number }// 定义一个自定义类型Persons export type Persons ArrayPersonInterApp.vue 父组件中代码 templatePerson :listpersons/ /templatescript langts setup nameApp import Person from ./components/Person.vue import {reactive} from vueimport {type Persons} from ./typeslet persons reactivePersons([{id:e98219e12,name:张三,age:18},{id:e98219e13,name:李四,age:19},{id:e98219e14,name:王五,age:20}]) /scriptPerson.vue中代码 template div classperson ulli v-foritem in list :keyitem.id{{item.name}}–{{item.age}}/li/ul /div /templatescript langts setup namePerson import {defineProps} from vue import {type PersonInter} from /types// 第一种写法接收。defineProps返回值是一个对象 // const props defineProps([list])// 第二种写法接收限制类型 // defineProps{list:Persons}() // 写法是defineProps可以传入一个泛型泛型里面是规定传入数据的类型的因为父组件不一定只传递一个数据所以用对象传递// 第三种写法接收限制类型指定默认值限制必要性 let props withDefaults(defineProps{list?:Persons}(),{list:()[{id:asdasg01,name:小猪佩奇,age:18}] }) console.log(props) /scriptprops 用于父组件给子组件传递数据 父组件 Son strhelloworld :listlist/Son 这里传递的两个数据是不一样的 str实为一个字符串list通过:也就是v-bind绑定了数据子组件中接收数据 通过defineProps在模板中可以直接使用 但是在script中不能使用如果想用的话 就需要定义变量接收。defineProps返回值是一个对象对象的每一个元素都是父元素传递来的数据 scriptimport {defineProps} from vue // 引入——其实可以不引入defineProps([list])// 通过defineProps接收数据const father_data defineProps([list])template{{list}} /template因为子组件在接收父组件的数据时想做一些限制比如限制类型指定默认值限制数据传递必要性所以引入了第二种第三种写法 第二种写法补充说明 defineProps{list:Persons}()。写法是defineProps可以传入一个泛型泛型里面是规定传入数据的类型的因为父组件不一定只传递一个数据所以用对象限制类型 子组件中如果想表明 父组件的数据可传可不传就要加一个问号 defineProps{list ? :Persons}()第三种写法补充说明 // 第三种写法接收限制类型指定默认值限制必要性 let props withDefaults(defineProps{list?:Persons}(),{list:()[{id:asdasg01,name:小猪佩奇,age:18}] })withDefaults配置默认值withDefaults 是一个函数。 第一个参数defineProps获取父组件传递的数据这里用问号设置为可传可不传递用泛型限制了传递过来的数据的类型第二个参数是对象设置每个属性的默认值要用函数返回function xxx(){return yyy}简写为() yyy defineProps 和 withDefaults都可以不用引入。 definexxx就是宏函数自动引入 3.11 生命周期 概念Vue组件实例在创建时要经历一系列的初始化步骤在此过程中Vue会在合适的时机调用特定的函数从而让开发者有机会在特定阶段运行自己的代码这些特定的函数统称为生命周期钩子 规律 生命周期整体分为四个阶段分别是创建、挂载、更新、销毁每个阶段都有两个钩子一前一后。 Vue2的生命周期 创建阶段beforeCreate、created 创建前、创建完毕 挂载阶段beforeMount、mounted 挂载前、挂载完毕 更新阶段beforeUpdate、updated 更新前、更新完毕 销毁阶段beforeDestroy、destroyed 销毁前、销毁完毕 Vue3的生命周期 创建阶段setup 挂载阶段onBeforeMount、onMounted 更新阶段onBeforeUpdate、onUpdated 卸载阶段onBeforeUnmount、onUnmounted 常用的钩子onMounted(挂载完毕)、onUpdated(更新完毕)、onBeforeUnmount(卸载之前)
templatediv classpersonh2当前求和为{{ sum }}/h2button clickchangeSum点我sum1/button/div /template!– vue3写法 – script langts setup namePersonimport { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from vue// 数据let sum ref(0)// 方法function changeSum() {sum.value 1}console.log(setup)// 生命周期钩子// vue3在 挂载前调用 onBeforeMount【里面的函数】onBeforeMount((){console.log(挂载之前)})onMounted((){console.log(挂载完毕)})onBeforeUpdate((){console.log(更新之前)})onUpdated((){console.log(更新完毕)})onBeforeUnmount((){console.log(卸载之前)})onUnmounted((){console.log(卸载完毕)}) /script子组件先挂载父组件再挂载 从入口文件开始分析。App组件是最后挂载的 3.12 自定义hooks 什么是hook—— 本质是一个函数把setup函数中使用的Composition API进行了封装类似于vue2.x中的mixin。 自定义hook的优势复用代码, 让setup中的逻辑更清楚易懂。 使用src文件夹下新建一个hooks文件夹里面根据功能创建文件 useDog.ts useSum.ts。ts文件向外暴露函数hook本质是函数而且函数内要返回值。 示例 useDog.ts import axios from axios import {reactive} from vueexport default function (){// 数据let dogList reactive([https://images.dog.ceo/breeds/pembroke/n02113023_7292.jpg])// 方法async function getDog() {try {let res await axios.get(https://dog.ceo/api/breed/pembroke/images/random)// console.log(res.data.message);dogList.push(res.data.message)} catch(err) {console.log(err);}}//给外部提供东西return {dogList,getDog} }useSum.ts import {ref} from vueexport default function(){let sum ref(0)function add() {sum.value 1} //给外部提供东西return {sum,add} } 组件中使用 templatediv classpersonh2当前求和为{{ sum }}/h2button clickadd点我加一/buttonhrimg v-for(dog, index) in dogList :srcdog :keyindexbutton clickgetDog()再来一只狗/button/div /templatescript langts setup namePersonimport useSum from /hooks/useSumimport useDog from /hooks/useDogconst {sum,add} useSum()const{dogList,getDog} useDog()/script
- 上一篇: 刘家窑做网站网上开店如何推广自己的网店
- 下一篇: 刘涛给孩子网站做的广告火车头导入wordpress
相关文章
-
刘家窑做网站网上开店如何推广自己的网店
刘家窑做网站网上开店如何推广自己的网店
- 技术栈
- 2026年03月21日
-
领券的网站怎么建设wordpress 国人主题
领券的网站怎么建设wordpress 国人主题
- 技术栈
- 2026年03月21日
-
领卷网站如何做代理游戏开发物语完美搭配
领卷网站如何做代理游戏开发物语完美搭配
- 技术栈
- 2026年03月21日
-
刘涛给孩子网站做的广告火车头导入wordpress
刘涛给孩子网站做的广告火车头导入wordpress
- 技术栈
- 2026年03月21日
-
浏览器73qcc泉州seo计费管理
浏览器73qcc泉州seo计费管理
- 技术栈
- 2026年03月21日
-
浏览器打开网站du制作网站
浏览器打开网站du制作网站
- 技术栈
- 2026年03月21日
