Vue3+Ts与vue2的区别
TypeScript的使用
1.初识TypeScript
TypeScript是JavaScript的超集,简单点来说,就是JavaScript的plus版本,JavaScript的命令在typescript里面都可以使用,typescript是编译过程中就可以看出来语法错误,而JavaScript只有在运行后才能知道那里错了。而且typescript是支持es6语法的。typescript是不能直接被浏览器执行的,需要先编译成JavaScript再运行。
2.TypeScript的安装和配置
TypeScript中文网 · TypeScript——JavaScript的超集 (tslang.cn)
首次安装typescript
npm i -g typescript
检测是否安装成功
tsc -v
新建demo.ts,通过如下命令启动
注:ts文件后缀名都是ts
tsc demo.ts
然后会生成demo.js文件执行如下命令
或者把demo.js引入到html文件到浏览器打开
node demo.js
3.TypeScript的数据类型使用
Js中有的数据类型Ts都有,在此基础上新增加了几种数据类型
1.Boolean
let bool:boolean=true
2.数字
支持二进制、八进制、十进制、十六进制
let num :number = 1
3.字符串
支持模板字符串
let str:string="tianxian"
4.数组
let list:number[]=[2,3,4];
let list:array<number>=[1,2,3];
5.null
let n:null=null
6.undefined
let u:undefined=undefined
7.元组Tuple
let t:[number,string]=[1,"q"]
8.枚举
枚举默认情况是从0开始排的,也可以手动赋值,默认自动加1,如果赋值的是字符串类型,必须全部赋值,不然会报错
enum Dir {up=10,down,left,right}
let u:Dir=Dir.up
9.Any
当数据类型为Any时数据类型是什么都可以,但是这个要慎用,不然会变成anyscript
let su:any=3;
su="tianxian";
su=false;
10.void
void在某种程度上与any相反,也就是说他没有任何数据类型
function User(): void {
console.log("I’m tianxian ");
}
4.除了以上10种之外还有另外一些好玩的写法
1.组合式赋值写法
let message:number|srting=1;
let message:number|srting="tianxian";
2.type提前声明变量类型
type n =number;
let num:n=1;
type s =string;
let str:s="天线"
3.直接指定值
type sex = 'girl'|'boy';
let s1:sex ="girl";//true
let s2:sex="boy";//true
let s3:sex = "天线";//不能赋值给sex
4.可选值
let b:{name:string,age?:number}//问号表示不必须要
b={
name:"tianxian"
}
5.只读
通过readonly指定只读属性,赋值后就不能再重新赋值
interface Point {
readonly x: number;
readonly y: number;
}
let p1 :Point={x:1,y:2};
p1.x=20;//error 不可分配到“X”,因为他是只读属性
5.setup语法
在vue3中一切数据还有函数全都定义在setup当中,写法如下
<script lang="ts">
import {ref} from "vue"
export default{
setup(){
let name:string='tianxian';
let age=ref(12)
function log(){
console.log("nihao");
}
return{
name,
log
}
}
}
</script>
setup还有一种语法糖的写法,只需要在script中写入 setup ,其余函数还有数据写法跟原生基本一样,如下:
<script lang="ts" setup>
import {ref} from "vue"
let name:string='tianxian';
let age=ref(12)
function log(){
console.log("nihao");
}
</script>
6.生命周期的变化
vue2的生命周期相对于vue3的生命周期有一些改变,如下表:
| vue2 | vue3 |
|---|---|
| beforeCreate | setup |
| created | setup |
| beforeMount | onbeforeMount |
| mounted | onMounted |
| beforeUpdate | onBeforeUpdate |
| updated | onUpdated |
| beforeDestroy | onBeforeUnmount |
| destroyed | onUnmounted |
vue3中删除了beforeCreate和created,变为setup,另外setup执行函数会在这两个之前执行,在vue3中需要按需求引入对应的生命周期,如下:
import { onMounted, onBeforeMount,ref } from "vue";
onBeforeMount(() => {
console.log("onBeforeMount");
})
onMounted(() => {
console.log("onMounted");
})
7.路由跳转
在vue2中我们使用this.route获取路由参数,但是在vue3中我们需要使用useRouter进行路由跳转,通过useRoute获取路由参数,如下:
import {useRouter,useRoure} from "vue-router"
// 路由跳转
const router =useRouter()
function go(){
router.push({
path:'/about',
query:{
msg:"你好,天线"
}
})
}
// 获取路由参数
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.msg)
8.父子组件传值与组件注册
父子组件传值与组件注册的写法有两种,第一种写法是跟vue2的写法一样,第二种是在script setup包裹下的写法,另外在传值这一块有一点很奇怪,虽然vue支持一个template写多个div标签,但是建议写一个大的标签,不然有时候在控制台会警告你,子组件未传值如下:
8.1、组件注册
在vue3中可以导入后,可以不用注册,直接在标签写入
<template>
<div>
<Test/>
</div>
</template>
<script lang="ts" setup>
import Test from "../components/Test.vue"
</script>
8.2、父向子传值
父组件传值:
<template>
<div>
<Test msg="传递数据"/>
</div>
</template>
<script lang="ts" setup>
import Test from "../components/Test.vue"
</script>
子组件使用defineProps接受并显示:
<template>
<div>
<div>{{ props.msg }}</div>
</div>
</template>
<script lang="ts" setup >
import {defineProps, defineEmits} from "vue";
import { ref, reactive } from 'vue'
let props = defineProps({ msg: String });
</script>
8.3、子向父传值
子组件通过defineEmits传值:
<template>
<div>
<button @click="clickChild">点击</button>
</div>
</template>
<script lang="ts" setup >
import Vue, { defineEmits} from "vue";
let props = defineProps({ msg: String });
const emit = defineEmits({
"clickChild": null
})
const clickChild=()=> {
let param={
val:"b"
}
emit("clickChild", param)
}
</script>
父组件接收值:
<template>
<div>
<Test @clickChild="clickEven" />
</div>
</template>
<script lang="ts" setup>
import Test from "../components/Test.vue"
const clickEven = (val: any) => {
console.log(val);
}
</script>
8.4、兄弟之间传值
通过defineExpose将需要的数据暴露出来,其余组件就可以访问到
<script lang="ts" setup >
let num2: number = 10;
defineExpose({num2})
</script>
其余组件获取信息:
<template>
<div>
<Test ref="test"/>
</div>
</template>
<script lang="ts" setup>
import Test from "../components/Test.vue"
import { onMounted, onBeforeMount,ref } from "vue";
let test =ref()
onMounted(() => {
console.log(test.value)
})
</script>
9.插槽的使用
Vue2 的中一般是通过 slot 属性指定模板的位置,通过 slot-scope 获取作用域插槽的数据,如下:
父组件
<script setup>
import ChildView from './ChildView.vue'
</script>
<template>
<Slot>
<template slot="content" slot-scope="{ msg }">
<div>{{ msg }}</div>
</template>
</Slot>
</template>
子组件
<template>
<slot name="content" msg="hello tianxian!"></slot>
</template>
在 Vue3 中则是通过 v-slot 这个指令来指定模板的位置,同时获取作用域插槽的数据,如下:
父组件
<template>
<Slot>
<template v-slot:content="{msg}">
<div>{{ msg }}</div>
</template>
</Slot>
</template>
<script lang="ts" setup>
import Slot from '../components/Slot.vue'
</script>
子组件
<template>
<div>
<slot name="content" msg="hello tianxian!"></slot>
</div>
</template>
<script lang="ts" setup>
</script>
10.ref的区别
在vue2中使用
<div class="huakuai interpose" ref="huakuai2">
</div>
js中获取元素
this.$refs.huakuai2
在vue3中使用
<div class="huakuai interpose" ref="huakuai2">
</div>
js中获取元素
import { onMounted ,ref} from "vue";
let huakuai2=ref()
huakuai2.value
获取到的元素都是这个
11.setup语法糖响应式数据
下面这种写法是不生效的
let title=9
const sum =()=>{
title=10
}
如果不使用ref或者(reactive)包裹就会不生效,需要像这样子
let title=ref(9)
const sum = ()=>{
title.value=10
}