Vue3项目中引用TS语法的实例讲解

目录
  • 基础语法
  • vue-router
  • vuex#####
  • elementPlus
  • axios
  • setup script

基础语法

定义data 

//script标签上 **lang="ts"**
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
//定义一个类型type或者接口interface来约束data
type Todo = {
  id: number,
  name: string,
  completed: boolean
}
export default defineComponent({
    //使用reactive时,可以用toRefs解构导出,在template就可以直接使用了
    const data = reactive({
      todoList: [] as Todo[]
    })
    //可以使用ref或者toRefs来定义响应式数据
    const count = ref(0);
    //使用ref在setup读取的时候需要获取xxx.value,但在template中不需要
    console.log(count.value)
    return {
      ...toRefs(data)
    }
})
</script>

定义props

import { defineComponent, PropType} from 'vue';
interface UserInfo = {
  id: number,
  name: string,
  age: number
}
export default defineComponent({
//props需要使用PropType泛型来约束。
  props: {
    userInfo: {
      type: Object as PropType<UserInfo>, // 泛型类型
      required: true
    }
  },
})

定义methods 

import { defineComponent, reactive, ref, toRefs } from 'vue';
type Todo = {
  id: number,
  name: string,
  completed: boolean
}
export default defineComponent({
  const data = reactive({
    todoList: [] as Todo[]
  })
  // 约束输入和输出类型
  const newTodo = (name: string):Todo  => {
    return {
      id: this.items.length + 1,
      name,
      completed: false
    };
  }
  const addTodo = (todo: Todo): void => {
    data.todoList.push(todo)
  }
  return {
    ...toRefs(data),
    newTodo,
    addTodo
  }
})

vue-router

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '../views/Home.vue';
//routes的约束类型是RouteRecordRaw
const routes: Array< RouteRecordRaw > = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
];
//createRouter创建router实例
const router = createRouter({
//router的模式分为
    //createWebHistory -- history模式
    //createWebHashHistory -- hash模式
  history: createWebHistory(process.env.BASE_URL),
  routes
});
export default router;

扩展路由额外属性

// 联合类型
//在实际项目开发中,常常会遇到这么一个场景
//某一个路由是不需要渲染到侧边栏导航上的
//此时我们可以给该路由添加一个hidden属性来实现。
//在ts的强类型约束下,添加额外属性就会报错,那么我们就需要扩展RouteRecordRaw类型。
type RouteConfig = RouteRecordRaw & {hidden?: boolean}; //hidden 是可选属性
const routes: Array<RouteConfig> = [
  {
    path: '/',
    name: 'Home',
    component: Home,
    hidden: true,
    meta: {
      permission: true,
      icon: ''
    }
  }
];

在setup中使用

//需要导入useRouter创建一个router实例。
import { useRouter } from 'vue-router';
import { defineComponent } from 'vue';
export default defineComponent({
  setup () {
    const router = useRouter();
    goRoute(path) {
       router.push({path})
    }
  }
})

vuex#####

使用this.$store 

import { createStore } from 'vuex';
export type State = {
  count: number
}
export default createStore({
  state: {
    count: 0
  }
});
  • 需要创建一个声明文件vuex.d.ts
import {ComponentCustomProperties} from 'vue';
import {Store} from 'vuex';
import {State} from './store'
declare module '@vue/runtime-core' {
    interface ComponentCustomProperties {
        $store: Store<State>
    }
}

在setup中使用

  • 定义InjecktionKey
import { InjectionKey } from 'vue';
import { createStore, Store } from 'vuex';
export type State = {
  count: number
}
// 创建一个injectionKey
export const key: InjectionKey<Store<State>> = Symbol('key');
  • 在安装插件时传入key
// main.ts
import store, { key } from './store';
app.use(store, key);
  • 在使用useStore时传入
import { useStore } from 'vuex';
import { key } from '@/store';
export default defineComponent({
  setup () {
    const store = useStore(key);
    const count = computed(() => store.state.count);
    return {
      count
    }
  }
})

模块

  • 新增一个todo模块。导入的模块,需要是一个vuex中的interface Module的对象,接收两个泛型约束
  • 第一个是该模块类型
import { Module } from 'vuex';
import { State } from '../index.ts';
type Todo = {
  id: number,
  name: string,
  completed: boolean
}
const initialState = {
  todos: [] as Todo[]
};
export type TodoState = typeof initialState;
export default {
  namespaced: true,
  state: initialState,
  mutations: {
    addTodo (state, payload: Todo) {
      state.todos.push(payload);
    }
  }
} as Module<TodoState, State>; //Module<S, R> S 该模块类型 R根模块类型
  • 第二个是根模块类型
// index.ts
export type State = {
  count: number,
  todo?: TodoState // 这里必须是可选,不然state会报错
}
export default createStore({
  state: {
    count: 0
  }
  modules: {
    todo
  }
});
  • 使用:
setup () {
  console.log(store.state.todo?.todos);
}

elementPlus

yarn add element-plus

完整引入

import { createApp } from 'vue'
import ElementPlus from 'element-plus';import 'element-plus/lib/theme-chalk/index.css';import App from './App.vue';
import 'dayjs/locale/zh-cn'
import locale from 'element-plus/lib/locale/lang/zh-cn'
const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000, locale })
app.mount('#app')

按需加载

  • 需要安装babel-plugin-component插件:
  • 安装依赖包
yarn add babel-plugin-component -D
  • 加入配置
// babel.config.js
plugins: [
    [
      'component',
      {
        libraryName: 'element-plus',
        styleLibraryName: 'theme-chalk'
      }
    ]
]
  • 创建 element 组件文件
import 'element-plus/lib/theme-chalk/index.css';
import 'dayjs/locale/zh-cn';
import locale from 'element-plus/lib/locale';
import lang from 'element-plus/lib/locale/lang/zh-cn';
import {
  ElAside,
  ElButton,
  ElButtonGroup,
} from 'element-plus';
const components: any[] = [
  ElAside,
  ElButton,
  ElButtonGroup,
];
const plugins:any[] = [
  ElLoading,
  ElMessage,
  ElMessageBox,
  ElNotification
];
const element = (app: any):any => {
  // 国际化
  locale.use(lang);
  // 全局配置
  app.config.globalProperties.$ELEMENT = { size: 'small' };
  
  components.forEach(component => {
    app.component(component.name, component);
  });
  plugins.forEach(plugin => {
    app.use(plugin);
  });
};
export default element;
  • 引用于项目
// main.ts
import element from './plugin/elemment'
const app = createApp(App);
element(app);

axios

  • axios的安装使用和vue2上没有什么大的区别,如果需要做一些扩展属性,还是需要声明一个新的类型。
type Config = AxiosRequestConfig & {successNotice? : boolean, errorNotice? : boolean}
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios';
import { ElMessage } from 'element-plus';
const instance = axios.create({
  baseURL: process.env.VUE_APP_API_BASE_URL || '',
  timeout: 120 * 1000,
  withCredentials: true
});
// 错误处理
const err = (error) => {
  if (error.message.includes('timeout')) {
    ElMessage({
      message: '请求超时,请刷新网页重试',
      type: 'error'
    });
  }
  if (error.response) {
    const data = error.response.data;
    if (error.response.status === 403) {
      ElMessage({
        message: 'Forbidden',
        type: 'error'
      });
    }
    if (error.response.status === 401) {
      ElMessage({
        message: 'Unauthorized',
        type: 'error'
      });
    }
  }
  return Promise.reject(error);
};
type Config = AxiosRequestConfig & {successNotice? : boolean, errorNotice? : boolean}
// 请求拦截
instance.interceptors.request.use((config: Config) => {
  config.headers['Access-Token'] = localStorage.getItem('token') || '';
  return config;
}, err);
// 响应拦截
instance.interceptors.response.use((response: AxiosResponse) => {
  const config: Config = response.config;
  const code = Number(response.data.status);
  if (code === 200) {
    if (config && config.successNotice) {
      ElMessage({
        message: response.data.msg,
        type: 'success'
      });
    }
    return response.data;
  } else {
    let errCode = [402, 403];
    if (errCode.includes(response.data.code)) {
      ElMessage({
        message: response.data.msg,
        type: 'warning'
      });
    }
  }
}, err);
export default instance;

setup script

  • 官方提供了一个实验性的写法,直接在script里面写setup的内容,即:setup script。
  • 之前我们写组件是这样的:
<template>
  <div>
    {{count}}
    <ImgReview></ImgReview >
  </div>
</template>
<script lang="ts">
import { ref, defineComponent } from "vue";
import ImgReview from "./components/ImgReview.vue";
export default defineComponent({
  components: {
    ImgReview,
  },
  setup() {
    const count = ref(0);
    return { count };
  }
});
</script>
  • 启用setup script后:在script上加上setup
<template>
  <div>
    {{count}}
    <ImgReview></ImgReview>
  </div>
</template>
<script lang="ts" setup>
    import { ref } from "vue";
    import ImgReview from "./components/ImgReview.vue";
    const count = ref(0);
</script>
  • 是不是看起来简洁了很多,组件直接导入就行了,不用注册组件,数据定义了就可以用。其实我们可以简单的理解为script包括的内容就是setup中的,并做了return。

导出方法

const handleClick = (type: string) => {
  console.log(type);
}

定义props

  • 使用props需要用到defineProps来定义,具体用法跟之前的props写法类似:
  • 基础用法
import { defineProps } from "vue";
const props = defineProps(['userInfo', 'gameId']);
  • 构造函数进行检查 给props定义类型:
const props = defineProps({
  gameId: Number,
  userInfo: {
      type: Object,
      required: true
  }
});
  • 使用类型注解进行检查
defineProps<{
  name: string
  phoneNumber: number
  userInfo: object
  tags: string[]
}>()
  • 可以先定义好类型:
interface UserInfo {
  id: number,
  name: string,
  age: number
}
defineProps<{
  name: string
  userInfo: UserInfo
}>()

defineEmit

import { defineEmit } from 'vue';
// expects emits options
const emit = defineEmit(['kk', 'up']);
const handleClick = () => {
  emit('kk', '点了我');
};
<Comp @kk="handleClick"/>
<script lang="ts" setup>
const handleClick = (data) => {
  console.log(data)
}
</script>

获取上下文

  • 在标准组件写法里,setup 函数默认支持两个入参:

  • 在setup script 中使用useContext获取上下文:
 import { useContext } from 'vue'
 const { slots, attrs } = useContext();
  • 获取到的slots,attrs跟setup里面的是一样的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vite创建一个标准vue3+ts+pinia项目

    目录 [01]使用的 Yarn创建项目: [02]在项目中使用pinia [03]添加vue-router [04] 安装按需自动导入插件 [05] 添加element-plus组件库 [06]添加sass [07] 安裝prettier 和 eslint 1.安装依赖项 使用vite创建一个标准vue3+ts+pinia项目的实现示例 [01]使用的 Yarn创建项目: 1.执行命令 yarn create vite my-vue-app --template vue-ts 3.cd my-v

  • 使用vue3+TS实现简易组件库的全过程

    目录 前置 组件编写 dropdown form 验证 总结 前置 首先下载vue-cli,搭建我们的环境,vue-create-luckyUi,选择vue3和TypeScript .在src目录下创建package作为组件目录.再安装bootstrap,用bootstrap里面的样式来完成我们的组件. 组件编写 dropdown 首先查看boorstrap文档,是这样用的 <div class="dropdown"> <button class="btn

  • 一个基于vue3+ts+vite项目搭建初探

    目录 前言 环境准备 使用Vite快捷搭建 使用npm 使用yarn 安装依赖 启动项目 修改vite配置文件 找到根目录vite.config.ts文件打开 集成路由 集成Vuex 添加element ui 集成axios 集成Sass Vue3 使用 总结 前言 基于Vue3已经成为默认版本,目前的项目暂时还没有使用过vue3开发和最近有一个全新的新项目的基础下,使用vue3开发项目,必然是未来的一个趋势 下面记录一下怎么使用Vue3 + ts + vite 从0开始搭建一个项目 环境准备

  • 使用Vue3和Echarts 5绘制带有立体感流线中国地图(推荐收藏!)

    目录 本文绘制的地图效果图如下: 一.Echarts 使用五部曲 1.下载并引入 echarts 2.准备容器 3.实例化 echarts 对象 4.指定配置项和数据 5.给 echarts 对象设置配置项 二.开始绘制流线中国地图 第一步:先绘制一个中国地图 第二步:添加流线 第三步:添加立体投影 总结 本文绘制的地图效果图如下: 一.Echarts 使用五部曲 1.下载并引入 echarts Echarts 已更新到了 5.0 版本,安装完记得检查下自己的版本是否是 5.0 . npm in

  • 从零搭建一个vite+vue3+ts规范基础项目(搭建过程问题小结)

    目录 项目初始化 安装router和pinia 安装ESlint eslint的vue规则需要切换 安装prettier 安装stylelint 安装husky 安装commitlint 总结 参考: 最近时间总算是闲了下来,准备着手搭建一个基础模板,为后面新项目准备的,搭建过程中遇到不少问题,现在总结下来给大家使用. 项目初始化 本项目已vite开始,所以按照vite官方的命令开始.这里使用的命令行的方式来搭建基础项目: yarn create vite my-vue-app --templa

  • vue3中如何使用ts

    目录 如何使用ts app.vue header.vue list.vue listitem.vue footer.vue 如何使用ts 在创建vue脚手架的时候吧typescript选上 app.vue <template>   <!-- <div id="nav">     <router-link to="/">Home</router-link> |     <router-link to=&quo

  • Vue3项目中引用TS语法的实例讲解

    目录 基础语法 vue-router vuex##### elementPlus axios setup script 基础语法 定义data  //script标签上 **lang="ts"** <script lang="ts"> import { defineComponent, reactive, ref, toRefs } from 'vue'; //定义一个类型type或者接口interface来约束data type Todo = {  

  • vue3项目中引入ts的详细图文教程

    目录 1.基于脚手架的情况下创建 vue3项目 2.启动未引入ts的vue3项目 3.在页面中(HomeView.vue)引入ts 4.配置vue3+ts项目 5.其他配置 6.在HomeView.vue 使用Ts语法 总结 提示:文章是基于vue3的项目基础上引入ts 1.基于脚手架的情况下创建 vue3项目 vue create vue3-ts 选择自定义预设,ts设置未选中状态 选择yarn与npm启动项目(根据个人,在这里我选择yarn) 2.启动未引入ts的vue3项目 3.在页面中(

  • vue项目中使用ts(typescript)入门教程

    目录 1.引入Typescript 2.配置文件webpack配置 3.让项目识别.ts 4.vue组件的编写 data()中定义数据 props传值 完整代码案例 最近项目需要将原vue项目结合ts的使用进行改造,这个后面应该是中大型项目的发展趋势,看到一篇不错的入门教程,结合它并进行了一点拓展记录之.本文从安装到vue组件编写进行了说明,适合入门. 1.引入Typescript npm install vue-class-component vue-property-decorator --

  • 强烈推荐!Vue3.2中的setup语法糖

    目录 前文 1.什么是setup语法糖 2.使用setup组件自动注册 3.使用setup后新增API 3.1 defineProps 3.2 defineEmits 3.3 defineExpose vue3项目如何开启setup语法糖 总结: 前文 作为一个前端程序员,说起 Vue 3肯定不会陌生,作为时下最火的前端框架之一,很多人将它作为入门框架. 但是尽管 Vue 3很久之前就已经开始投入使用,也不免会有人抱怨 Vue 3的知识点太多太杂,更新太快.这不,最近 Vue 3又定稿了一项新技

  • Vue-cli3中使用TS语法示例代码

    目录 ts有什么用? 为什么用ts? 1.引入Typescript包 2.配置 3.让项目识别.ts 4.vue组件的编写 ts有什么用? 类型检查.直接编译到原生js.引入新的语法糖 为什么用ts? TypeScript的设计目的应该是解决JavaScript的“痛点”:弱类型和没有命名空间,导致很难模块化,不适合开发大型程序.另外它还提供了一些语法糖来帮助大家更方便地实践面向对象的编程. typescript不仅可以约束我们的编码习惯,还能起到注释的作用,当我们看到一函数后我们立马就能知道这

  • 浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法

    1.在Vue项目中引用公共方法 作为一个新人小白,在使用vue的过程中,难免会遇到很多的问题,比如某个方法在很多组件中都能用的上,如果在每个组件上都去引用一次的话,会比较麻烦,增加代码量.怎么做比较好呢,话不多说直接看代码把 首先 要在main.js中引入公共js.然后,将方法赋在Vue的原型链上. 像图中这样. 然后在需要的组件上去引入这个方法 mouted (){ //调用方法 this.common.login(); } /**然后公共方法里写一段简单的代码*/ export defaul

  • 在vue项目中引用Antv G2,以饼图为例讲解

    我就废话不多说了,大家还是直接看代码吧~ npm install @antv/g2 --save template内容: <template> <div id="pieChart"></div> </template> js部分: ​//引入G2组件 import G2 from "@antv/g2"; ​ export default { name:"", //数据部分 data(){ retur

  • Vue3项目中优雅实现微信授权登录的方法

    目录 前言 准备 实现思路 上代码 总结 前言 微信授权登录是做微信公众号开发一直绕不开的话题,而且整个授权登录流程的实现,是需要前后端配合一起完成的.在过去前后端还未分离的年代,也许我们前端并不需要太过关心授权的具体实现.然而现在都2021年了,前后端分离的架构大行其道,如何在前后端分离的情况下实现微信授权登录就成了今天要探讨的重点问题. 准备 首先,我们还是需要先梳理下微信授权整个流程是怎样的,这里我就直接将官方文档搬来: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制

  • Vue3项目中的hooks的使用教程

    目录 hooks 特点 hooks 基本使用 今天我们稍微说一下 vue3 项目中的 hooks 的使用,其实这个 hooks 呢是和 vue2 当中的 mixin 是类似的,学习过 vue2 的小伙伴一定对 mixin 一定比较熟悉,就算没用过也一定了解过,也就是混入,通过 mixin 混入来分发 vue 组件中的可复用功能.一个混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项.而 vue2 的 hooks 函数与 mixin 混入的区别,

  • linux下用renameTo方法修改java web项目中文件夹名称的实例

    经测试,在Linux环境中安装tomcat,然后启动其中的项目,在项目中使用java.io.File.renameTo(File dest)方法可行. 之前在本地运行代码可以修改,然后传到Linux服务器上一直无法实现功能,自己一直在捣鼓,以为是window环境和Linux环境不同的原因导致,后面发现在项目中使用renameTo方法修改文件夹名称不行是因为之前改了java web项目中的js,在js中传入值到后台,后台根据值来修改文件夹名称.由于没清除缓存导致js中的代码没有刷新,所以一直出现错

随机推荐