vue+Ts

124 阅读4分钟

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的生命周期有一些改变,如下表:

vue2vue3
beforeCreatesetup
createdsetup
beforeMountonbeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted

vue3中删除了beforeCreatecreated,变为setup,另外setup执行函数会在这两个之前执行,在vue3中需要按需求引入对应的生命周期,如下:

import { onMounted, onBeforeMount,ref } from "vue";
onBeforeMount(() => {
  console.log("onBeforeMount");
})
onMounted(() => {
  console.log("onMounted");
})

7.路由跳转

在vue2中我们使用this.router进行路由跳转,this.router进行路由跳转,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  

获取到的元素都是这个 image.png

11.setup语法糖响应式数据

下面这种写法是不生效的

let title=9
const sum =()=>{
    title=10
}

如果不使用ref或者(reactive)包裹就会不生效,需要像这样子

let title=ref(9)
const sum = ()=>{
    title.value=10
}