首页 > 其他分享 >备战2021:vue3+ts开发指南

备战2021:vue3+ts开发指南

时间:2022-10-06 15:32:02浏览次数:52  
标签:items counter ts Todo todoName 2021 vue3 todo store

Vue3 + Typescript开发指南

为什么要使用Ts

应不应该使用TS开发Vue3是当前的热门话题,大家主要纠结成本和收益之间的取舍。

什么是TypeScript

官网:构建于JavaScript,增加了静态类型定义

JavaScript变量没有类型,导致代码中各种类型判断语句,冗余度比较高。如果类型没有限制,变量类型可能发生变化,使代码可能出现问题。

备战2021:vue3+ts开发指南_对象类型ts-01-003.opt.jpg

使用TS的额外成本

备战2021:vue3+ts开发指南_对象类型_02image-20210531150655190

是否需要TS

备战2021:vue3+ts开发指南_typescript_03image-20210531151342630

整合vue3+ts

vue cli环境

vue create my-project

备战2021:vue3+ts开发指南_对象类型_04image-20210510114727426

Vite环境

npm init @vitejs/app

备战2021:vue3+ts开发指南_typescript_05image-20210531151929571

使用TS编写Vue组件

组件定义

​<script lang="ts">​​​ 和 ​​defineComponent​

<template>
<div>{{ counter }}</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
data() {
return {
counter: 0
}
},
});
</script>

工具支持:Volar

data类型定义

利用类型断言确定数据类型

类型定义

types.d.ts

export type Todo = {
id: number;
name: string;
completed: boolean;
}

Comp.vue

import type { Todo } from "../types";
组件定义
<script lang="ts">
export default defineComponent({
data() {
return {
// 利用类型断言
items: [] as Todo[]
}
},
created() {
// 此处会获得类型支持
this.items.push({
id: 1,
name: 'vue3',
completed: false
})
}
});
</script>

模板定义

<template>
<!-- 此处会获得类型支持 -->
<div v-for="item in items" :key="item.id" class="todo-item">
{{ item.name }}
</div>
</template>

props类型定义

对象类型利用类型断言和PropType<T>。

类型定义
export type TitleInfo = {
value: string;
color: string;
}
属性定义
<script lang="ts">
// 属性类型需要PropType支持
import { PropType } from "vue";
import type { TitleInfo } from "../types"

export default defineComponent({
props: {
// 利用泛型类型约束对象类型
titleInfo: Object as PropType<TitleInfo>,
},
})
</script>

模板中使用

<h1 :style="{ backgroundColor: titleInfo?.color }">{{ titleInfo?.value }}</h1>
<Comp :title-info="{ value: '待办事项', color: '#41b883' }"></Comp>

computed计算属性

标识函数返回类型

computed: {
doubleCounter(): number {
return this.counter * 2
}
},

methods方法

标识函数形参和返回类型

methods: {
newTodo(todoName: string): Todo {
return {
id: this.items.length + 1,
name: todoName,
completed: false,
};
},
addTodo(todo: Todo) {
this.items.push(todo);
this.todoName = ''
},
},
data() {
return {
todoName: "",
};
},
<input
type="text"
v-model="todoName"
@keydown.enter="addTodo(newTodo(todoName))"
/>

Setup Script

setup script方式编写代码会更加简洁

数据定义
<script setup lang="ts">
import { defineProps, ref, computed } from "vue";

type Todo = {
id: number;
name: string;
completed: boolean;
};

type TitleInfo = {
value: string;
color: string;
};

const items = ref<Todo[]>([]);
items.value.push({
id: 1,
name: "vue3",
completed: false,
});
</script>
属性定义
defineProps<{
titleInfo: TitleInfo;
}>();
计算属性
const counter = ref(0);
const doubleCounter = computed(() counter.value * 2);
方法
const todoName = ref("");

function newTodo(todoName: string): Todo {
return {
id: items.value.length + 1,
name: todoName,
completed: false,
};
}
function addTodo(todo: Todo) {
items.value.push(todo);
todoName.value = "";
}

使用TS编写Vuex

$store类型化

为ComponentCustomProperties扩展$store属性,store/vuex.d.ts

import { ComponentCustomProperties } from "vue";
import { Store } from "vuex";

// declare your own store states
export interface State {
counter: number;
}

declare module "@vue/runtime-core" {
// provide typings for `this.$store`
interface ComponentCustomProperties {
$store: Store<State>;
}
}

创建Store

store/index.ts

import { createStore, Store } from "vuex";
import { State } from "./vuex";

const store = createStore({
state: {
counter: 0,
},
});

export default store;

引入,main.ts

createApp(App).use(store).mount("#app");

使用,Comp.vue

import { mapState } from "vuex";

export default defineComponent({
props: {
titleInfo: Object as PropType<TitleInfo>,
},
data() {
return {
// counter不需要了
// counter: 0,
};
},
computed: {
// 映射state counter
...mapState(['counter']),
doubleCounter(): number {
// $store已经有类型了
return this.$store.state.counter * 2;
},
},
}

useStore()类型化

setup中使用useStore时要类型化,共需要三步:

  1. 定义​​InjectionKey​
  2. app安装时提供​​InjectionKey​
  3. 传递​​InjectionKey​​ 给 ​​useStore​

store/index.ts

import { InjectionKey } from "vue";
import { State } from "./vuex";

// define injection key
export const key: InjectionKey<Store<State>> = Symbol();

main.ts

import { key } from "./store";
// 作为参数2传入key
createApp(App).use(store, key).mount("#app");

使用,CompSetup.vue

import { useStore } from 'vuex'
import { key } from '../store'

const store = useStore()
const counter = computed(() store.state.counter);

简化使用

封装useStore,避免每次导入key,store/index.ts

import { useStore as baseUseStore } from "vuex";
export function useStore() {
return baseUseStore(key);
}

使用变化,CompSetup.vue

import { useStore } from '../store'
const store = useStore()

模块化

创建模块文件,store/modules/todo.ts

import { Module } from "vuex";
import { State } from "../vuex";
import type { Todo } from "../../types";

const initialState = {
items: [] as Todo[],
};

export type TodoState = typeof initialState;

export default {
namespaced: true,
state: initialState,
mutations: {
initTodo(state, payload: Todo[]) {
state.items = payload;
},
addTodo(state, payload: Todo) {
state.items.push(payload)
}
},
actions: {
initTodo({ commit }) {
setTimeout(() {
commit("initTodo", [
{
id: 1,
name: "vue3",
completed: false,
},
]);
}, 1000);
}
},
} as Module<TodoState, State>;

引入子模块,store/index.ts

import todo from "./modules/todo";
const store = createStore({
modules: {
todo,
},
});

状态中添加模块信息,vuex.d.ts

import type { TodoState } from "./modules/todo";

export interface State {
todo?: TodoState;
}

组件中使用,Comp.vue

export default {
data() {
return {
// items: [] as Todo[],
};
},
computed: {
items(): Todo[] {
return this.$store.state.todo!.items
}
},
methods: {
addTodo(todo: Todo) {
// this.items.push(todo);
this.$store.commit("todo/addTodo", todo);
this.todoName = "";
},
},
}

setup中使用,CompSetup.vue

const items = computed(() store.state.todo!.items)
store.dispatch('todo/initTodo')

function addTodo(todo: Todo) {
// items.value.push(todo);
store.commit('todo/addTodo', todo)
todoName.value = "";
}


标签:items,counter,ts,Todo,todoName,2021,vue3,todo,store
From: https://blog.51cto.com/u_15680963/5733733

相关文章

  • 备战2021:vite2项目最佳实践
    备战2021:Vite2项目最佳实践作者同款机械键盘vite2来了​​Vite1​​​还没用上,​​Vite2​​​已经更新了,全新插件架构,丝滑的开发体验,和​​Vue3​​的完美结合。2021年第一......
  • 备战2021:Vite2插件开发指南
    Vite插件是什么使用Vite插件可以扩展Vite能力,比如解析用户自定义的文件输入,在打包代码前转译代码,或者查找第三方模块。image-20210216214524914Vite插件的形式​​Vite​​......
  • CF895C Square Subsets
    CF895CSquareSubsets注意到平方数要求每个质因数的幂次均为偶数。由于\(70\)以内仅有\(19\)个质因数,考虑将每个\(a_i\)按照每个质因数的奇偶性分解为\(01\)串......
  • 1738C-Even Number Addicts - dp, games, greedy
      voidsolve(){intn;cin>>n;intodd=0,even=0;for(inti=0;i<n;i++){inta;cin>>a;if(a&1)odd++;elseeven+......
  • Subsets of Array
    寻找一组数组中不重复元素的子集packagecom.example.mathematicaldemo.demo;importlombok.extern.slf4j.Slf4j;/***资料:*https://easylearn.baidu.com/edu-......
  • vue3中pinia的使用总结
      pinia的简介和优势:Pinia是Vue生态里Vuex的代替者,一个全新Vue的状态管理库。在Vue3成为正式版以后,尤雨溪强势推荐的项目就是Pinia。那先来看看Pinia比Vuex好的地方,也......
  • ts+vite3+vue3+mock+qs实现本地模拟数据功能
    第一步:安装qs因为项目中用到了ts,所以还需要安装:第二步:安装mock第三步:创建Vue页面:Category.vue<template><button@click="getById">getById</button><button......
  • 查看网络状态netstat和ss命令
    ####yum-yinstallnetstat安装netstat命令#netstat命令查看网络状态#netstat-lnp查看监听端口#-l表示监听#netstat-an查看系统的网络所有连接状况#netstat-l......
  • Bootstrap
    两种方法引用Bootstrap一种是把下载的bootstrap-3.3.7-dist文件夹放入所要用到Bootstrap框架的项目的文件夹:官网下载地址:http://getbootstrap.com/中文网下载地址:http://w......
  • MSC Adams 2021软件安装包和安装教程
    MSCAdams2021软件简介:MSCAdams2021是一款著名的机械系统动态仿真分析软件,使用交互式图形环境和零件库、约束库、力库,创建完全参数化的机械系统几何模型,可以帮助工程师在......