vue+ts上集----vue-cli创建项目时注意选中TypeScript、定义组件的三种方式(类式,扩展式,函数式)、函数式组件没有this,它通过props接收父组件传来的值、函数式组件触发事件的方法、类组件中定义props,元数据,实例方法,计算属性,属性检测,ref,自定义指令,过滤器
### vue-cli创建项目
Babel
TypeScript
Use class-style component syntax? Yes
Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
### 配置
tsconfig.js 配置ts编译环境
xx.d.ts 支持vue,jsx==》ts写法
### 定义组件的三种方式
src/components
1、类式
①components下新建ClassComponent.vue:(注意要引入vue的装饰器:vue-property-decorator)
<template> <div> <h3>类组件</h3> </div> </template> <script lang="ts"> import Vue from 'vue'; // 引入vue装饰器 import {Component} from "vue-property-decorator"; // 用装饰器装饰类 @Component({}) export default class ClassComponent extends Vue{ mounted():void { console.log("class-component挂载完毕") } } </script>
②App.vue中:(在装饰器中注册组件)
<template> <div id="app"> <h3>vue+ts</h3> <ClassComponent></ClassComponent> </div> </template> <script lang="ts"> import Vue from 'vue'; // 引入vue装饰器 import {Component} from 'vue-property-decorator'; import ClassComponent from './components/ClassComponent.vue' // 用装饰器装饰类 @Component({ components:{ClassComponent} }) export default class App extends Vue{ } </script>
2、扩展式
①components下新建ExtendComponent.vue组件:(核心是Vue.extend())
import Vue from 'vue'; export default Vue.extend({ mounted() { console.log("extend-component挂载完毕") }, })
②App.vue中引入并注册:
import ExtendComponent from "./components/ExtendComponent.vue";
@Component({
components:{ExtendComponent}
})
3、函数式
①component下新建FunctionComponent.vue:(不同之处是template标签中添加functional属性)
<template functional> <div> <h3>函数式组件</h3> </div> </template>
②App.vue中引入并注册:
import FunctionComponent from "./components/FunctionComponent.vue";
@Component({
components:{FunctionComponent}
})
注意:函数式组件只有template标签,渲染速度最快,它可以接收上游传递下来的props,它没有this。继承式组件和原来的vue+js写法非常像,唯一不同的是
<script> export default {} </script>
变为
<script lang="ts"> import Vue from 'vue'; export default Vue.extend({}) </script>
类组件中有装饰器的概念,定义props、元数据、实例方法、计算属性、watch、ref、指令、过滤器时,有ts自己的写法。
### 函数式组件没有this,它通过props接收父组件传来的值
①父组件App.vue中定义自定义属性p1传值:
<FunctionComponent p1="ppppppp"></FunctionComponent>
②函数式组件FunctionComponent.vue中直接通过 props.p1接收值:
<div>{{props.p1}}</div>
### 函数式组件触发事件的方法:
①父组件App.vue中定义show()方法:
export default class App extends Vue{ show(arg:number):void{ alert("函数式组件中的事件触发:"+arg) } }
②函数式组件FunctionComponent.vue中通过parent.show()触发click事件:
<button @click="parent.show(10)">按钮</button>
### 类组件中定义props
①父组件App.vue中定义自定义属性p1和p2传值:
<ClassComponent p1="阿尼哈塞呦!!!!!" p2="接收到p2传过来的值" :p3="123"></ClassComponent>
②props的定义需要依赖于装饰器,先在装饰器插件中解构出Prop装饰器:
import {Component,Prop} from "vue-property-decorator";
③! 操作符表示该值不为空:
@Prop() readonly p1!:string;
④default表示默认值,readonly表示只读属性一旦修改会报错:
@Prop({default:"p2默认的值在装饰器的对象中设置default"}) readonly p2!:string|undefined;
⑤Prop装饰器中还可以约定传过来的值的type类型:
@Prop({default:12345,type:Number}) readonly p3!:number|undefined;
注意:接收props时的默认值不可以这样设置:@Prop() p4:string="aaa"; 默认值可以在装饰器中用default设置或者用 ! 操作符设置不为空。
### 类组件中定义元数据-data
①src下新建types/index.ts(自定义类型Person):
interface Person{ readonly id:number, name:string, age?:number } export {Person}
②ClassComponent.vue中引入自定义类型Person:
import {Person} from "../types";
③注意自定义类型的使用要先引入:
msg1:string="你今天吃了吗"; msg2:string="你今天吃了吗"+this.p1; msg3:undefined=undefined;// undefined 非响应式 msg4:any=null; msg5:Person={id:1,name:"wxm",age:24}
### 类组件中实例方法的定义
show(arg1:number,arg2:string):void{ alert("类组件的实例方法"+arg1+arg2) }
### 类组件中计算属性的定义
get cptMsg1():string{ return "经过计算后的msg1:"+this.msg1 }
### 类组件中属性检测的定义
①先引入装饰器:
import {Component,Prop,Watch} from "vue-property-decorator";
②利用Watch装饰器定义 msg1 的监听函数 onMsg1Change():
@Watch("msg1") onMsg1Change(newValue:string,oldValue:string):void{ console.log("msg1发生变化了","新值:"+newValue,"旧值:"+oldValue) }
③深度监听:(deep:true----深度监听 immediate:true----第一次加载就执行)
@Watch("msg5",{deep:true,immediate:true}) onMsg5Change(newValue:string,oldValue:string):void{ console.log("msg5发生变化了","新值:"+newValue,"旧值:"+oldValue) }
### 类组件中用ref引入元素
①先引入装饰器:
import {Component,Prop,Watch,Ref} from "vue-property-decorator";
②设置ref属性:
<p ref="box">box</p>
③利用Ref装饰器将 box标签代理到 bbox 中去:
@Ref("box") bbox!:HTMLPreElement;
④在挂载后钩子函数中可以对 bbox 进行操作:
mounted():void { this.bbox.style.backgroundColor="deeppink"; }
### 类组件中的自定义指令和过滤器的使用
①Component装饰器中定义局部自定义指令和局部过滤器:
@Component({ directives:{// 局部指令 direc1:(el:HTMLElement,binding)=>console.log("direc1",binding.value) }, filters:{// 局部过滤器 filt1(data:string,arg:number=2):string{ return "宝马"+arg } } })
②使用自定义指令和过滤器:
<div v-direc1>direc1</div> <div v-direc1="'qqqqq'">direc1</div>
<div>{{"bwm"|filt1}}</div> <div>{{"bwm"|filt1(33333)}}</div>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结