“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”
Create a project
Basic grammar
Define the data
- Lang =”ts” on script tag
- Define a type
type
Or interfaceinterface
To restraindata
- You can use
ref
ortoRefs
To define reactive data- use
ref
insetup
Fetch is required when readingxxx.value
, but intemplate
Do not need to - use
reactive
Can be usedtoRefs
Deconstruction derived intemplate
You can use it directly
- use
<script lang="ts">
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 count = ref(0);
console.log(count.value)
return {
...toRefs(data)
}
})
</script>
Copy the code
Define the props
Props needs to be constrained using the PropType generic.
<script lang="ts">
import { defineComponent, PropType} from 'vue';
interface UserInfo = {
id: number.name: string.age: number
}
export default defineComponent({
props: {
userInfo: {
type: Object as PropType<UserInfo>, // Generic type
required: true
}
},
})
</script>
Copy the code
Define the methods
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
type Todo = {
id: number.name: string.completed: boolean
}
export default defineComponent({
const data = reactive({
todoList: [] as Todo[]
})
// Constrain input and output types
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
}
})
</script>
Copy the code
vue-router
createRouter
createrouter
The instancerouter
Are divided into:createWebHistory
– the history modecreateWebHashHistory
– the hash pattern
routes
Is the constraint type ofRouteRecordRaw
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '.. /views/Home.vue';
const routes: Array< RouteRecordRaw > = [
{
path: '/'.name: 'Home'.component: Home,
},
{
path: '/about'.name: 'About'.component: () = > import(/* webpackChunkName: "about" */ '.. /views/About.vue')}];const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
export default router;
Copy the code
Extended route additional attributes
In actual project development, it is common to encounter a scenario where a route does not need to be rendered to the sidebar navigation, so we can add a hidden property to that route.
With the strong typing constraint of TS, adding additional attributes is an error, so we need to extend the RouteRecordRaw type.
// Union type
typeRouteConfig = RouteRecordRaw & {hidden? :boolean}; // Hidden is an optional property
const routes: Array<RouteConfig> = [
{
path: '/'.name: 'Home'.component: Home,
hidden: true.meta: {
permission: true.icon: ' '}}];Copy the code
Used in setup
You need to import useRouter to create a Router instance.
<script lang="ts">
import { useRouter } from 'vue-router';
import { defineComponent } from 'vue';
export default defineComponent({
setup () {
const router = useRouter();
goRoute(path) {
router.push({path})
}
}
})
</script>
Copy the code
vuex
Use this. $store
import { createStore } from 'vuex';
export type State = {
count: number
}
export default createStore({
state: {
count: 0}});Copy the code
A declaration file vuex.d.ts needs to be created
// 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>
}
}
Copy the code
Used in setup
- Define InjecktionKey
- Pass in the key when installing the plug-in
- Passed in when using useStore
import { InjectionKey } from 'vue';
import { createStore, Store } from 'vuex';
export type State = {
count: number
}
// Create an injectionKey
export const key: InjectionKey<Store<State>> = Symbol('key');
Copy the code
// main.ts
import store, { key } from './store';
app.use(store, key);
Copy the code
<script lang="ts">
import { useStore } from 'vuex';
import { key } from '@/store';
export default defineComponent({
setup () {
const store = useStore(key);
const count = computed(() = > store.state.count);
return {
count
}
}
})
</script>
Copy the code
The module
Add a todo module. The imported Module, which needs to be an Interface Module object in VUEX, receives two generic constraints, the first for the Module type and the second for the root Module type.
// modules/todo.ts
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 Indicates the Module type R Indicates the root Module type
,>
Copy the code
// index.ts
export type State = {
count: number, todo? : TodoState// This must be optional, otherwise state will report an error
}
export default createStore({
state: {
count: 0
}
modules: {
todo
}
});
Copy the code
Use:
setup () {
console.log(store.state.todo? .todos); }Copy the code
elementPlus
yarn add element-plus
Copy the code
A complete introduction
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')
Copy the code
According to the need to load
Install the babel-plugin-component plug-in:
yarn add babel-plugin-component -D
// babel.config.js
plugins: [['component',
{
libraryName: 'element-plus'.styleLibraryName: 'theme-chalk'}]]Copy the code
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= > {
/ / the internationalization
locale.use(lang);
// Global configuration
app.config.globalProperties.$ELEMENT = { size: 'small' };
components.forEach(component= > {
app.component(component.name, component);
});
plugins.forEach(plugin= > {
app.use(plugin);
});
};
export default element;
Copy the code
// main.ts
import element from './plugin/elemment'
const app = createApp(App);
element(app);
Copy the code
axios
The installation of AXIos is not much different from vue2. If you need to make some extended properties, you still need to declare a new type.
type Config = AxiosRequestConfig & {successNotice? : boolean, errorNotice? : boolean}
Copy the code
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
});
// Error handling
const err = (error) = > {
if (error.message.includes('timeout')) {
ElMessage({
message: 'Request timed out, please refresh the page and try again'.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}
// Request interception
instance.interceptors.request.use((config: Config) = > {
config.headers['Access-Token'] = localStorage.getItem('token') | |' ';
return config;
}, err);
// Response interception
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;
Copy the code
setup script
There is an experimental way to write setup directly inside a script: setup script.
Previously we wrote the component like this:
<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>
Copy the code
After setup Script is enabled: Add setup to script
<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>
Copy the code
Does it look a lot simpler, components directly imported on the line, do not register components, data definition can be used. Script contains the contents of setup and returns.
Methods derived
<script lang="ts" setup>
const handleClick = (type: string) = > {
console.log(type);
}
</script>
Copy the code
Define the props
DefineProps is used to define functions in the same way as defineProps:
Basic usage
<script lang="ts" setup>
import { defineProps } from "vue";
const props = defineProps(['userInfo'.'gameId']);
</script>
Copy the code
The constructor to check for props defines the type:
const props = defineProps({
gameId: Number.userInfo: {
type: Object.required: true}});Copy the code
Use type annotations to check
defineProps<{
name: string
phoneNumber: number
userInfo: object
tags: string[]} > ()Copy the code
We can define the type first:
interface UserInfo {
id: number.name: string.age: number
}
defineProps<{
name: string
userInfo: UserInfo
}>()
Copy the code
defineEmit
<script lang="ts" setup>
import { defineEmit } from 'vue';
// expects emits options
const emit = defineEmit(['kk'.'up']);
const handleClick = () = > {
emit('kk'.'Click on me');
};
</script>
Copy the code
<Comp @kk="handleClick"/>
<script lang="ts" setup>
const handleClick = (data) = > {
console.log(data)
}
</script>
Copy the code
Get context
In standard component writing, the setup function supports two inputs by default:
parameter | type | meaning |
---|---|---|
props | object | Data passed from the parent component |
context | object | The execution context of the component |
Use useContext to get context in setup script:
<script lang="ts" setup>
import { useContext } from 'vue'
const { slots, attrs } = useContext();
</script>
Copy the code
Attrs is the same as setup.