最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3項(xiàng)目中引用TS語(yǔ)法的實(shí)例講解

 更新時(shí)間:2022年05月30日 10:52:44   作者:灬ManongLai  
這篇文章主要介紹了Vue3項(xiàng)目中引用TS語(yǔ)法的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

基礎(chǔ)語(yǔ)法

定義data 

//script標(biāo)簽上 **lang="ts"**
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
//定義一個(gè)類型type或者接口interface來(lái)約束data
type Todo = {
? id: number,
? name: string,
? completed: boolean
}
export default defineComponent({
?? ?//使用reactive時(shí),可以用toRefs解構(gòu)導(dǎo)出,在template就可以直接使用了
?? ?const data = reactive({
?? ? ?todoList: [] as Todo[]
?? ?})
?? ?//可以使用ref或者toRefs來(lái)定義響應(yīng)式數(shù)據(jù)
?? ?const count = ref(0);
?? ?//使用ref在setup讀取的時(shí)候需要獲取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泛型來(lái)約束。
? 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創(chuàng)建router實(shí)例
const router = createRouter({
//router的模式分為
?? ?//createWebHistory -- history模式
?? ?//createWebHashHistory -- hash模式
? history: createWebHistory(process.env.BASE_URL),
? routes
});
export default router;

擴(kuò)展路由額外屬性

// 聯(lián)合類型
//在實(shí)際項(xiàng)目開發(fā)中,常常會(huì)遇到這么一個(gè)場(chǎng)景
//某一個(gè)路由是不需要渲染到側(cè)邊欄導(dǎo)航上的
//此時(shí)我們可以給該路由添加一個(gè)hidden屬性來(lái)實(shí)現(xiàn)。
//在ts的強(qiáng)類型約束下,添加額外屬性就會(huì)報(bào)錯(cuò),那么我們就需要擴(kuò)展RouteRecordRaw類型。
type RouteConfig = RouteRecordRaw & {hidden?: boolean}; //hidden 是可選屬性
const routes: Array<RouteConfig> = [
? {
? ? path: '/',
? ? name: 'Home',
? ? component: Home,
? ? hidden: true,
? ? meta: {
? ? ? permission: true,
? ? ? icon: ''
? ? }
? }
];

在setup中使用

//需要導(dǎo)入useRouter創(chuàng)建一個(gè)router實(shí)例。
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
? }
});
  • 需要?jiǎng)?chuàng)建一個(gè)聲明文件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
}
// 創(chuàng)建一個(gè)injectionKey
export const key: InjectionKey<Store<State>> = Symbol('key');
  • 在安裝插件時(shí)傳入key
// main.ts
import store, { key } from './store';
app.use(store, key);
  • 在使用useStore時(shí)傳入
import { useStore } from 'vuex';
import { key } from '@/store';
export default defineComponent({
? setup () {
? ? const store = useStore(key);
? ? const count = computed(() => store.state.count);
? ? return {
? ? ? count
? ? }
? }
})

模塊

  • 新增一個(gè)todo模塊。導(dǎo)入的模塊,需要是一個(gè)vuex中的interface Module的對(duì)象,接收兩個(gè)泛型約束
  • 第一個(gè)是該模塊類型
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根模塊類型
  • 第二個(gè)是根模塊類型 
// index.ts
export type State = {
? count: number,
? todo?: TodoState // 這里必須是可選,不然state會(huì)報(bào)錯(cuò)
}
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'
? ? ? }
? ? ]
]
  • 創(chuàng)建 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 => {
? // 國(guó)際化
? 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;
  • 引用于項(xiàng)目 
// main.ts
import element from './plugin/elemment'
const app = createApp(App);
element(app);

axios

  • axios的安裝使用和vue2上沒有什么大的區(qū)別,如果需要做一些擴(kuò)展屬性,還是需要聲明一個(gè)新的類型。
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
});
// 錯(cuò)誤處理
const err = (error) => {
? if (error.message.includes('timeout')) {
? ? ElMessage({
? ? ? message: '請(qǐng)求超時(shí),請(qǐng)刷新網(wǎng)頁(yè)重試',
? ? ? 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}
// 請(qǐng)求攔截
instance.interceptors.request.use((config: Config) => {
? config.headers['Access-Token'] = localStorage.getItem('token') || '';
? return config;
}, err);
// 響應(yīng)攔截
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

  • 官方提供了一個(gè)實(shí)驗(yàn)性的寫法,直接在script里面寫setup的內(nèi)容,即: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>
  • 是不是看起來(lái)簡(jiǎn)潔了很多,組件直接導(dǎo)入就行了,不用注冊(cè)組件,數(shù)據(jù)定義了就可以用。其實(shí)我們可以簡(jiǎn)單的理解為script包括的內(nèi)容就是setup中的,并做了return。

導(dǎo)出方法

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

定義props

  • 使用props需要用到defineProps來(lái)定義,具體用法跟之前的props寫法類似:
  • 基礎(chǔ)用法
import { defineProps } from "vue";
const props = defineProps(['userInfo', 'gameId']);
  • 構(gòu)造函數(shù)進(jìn)行檢查 給props定義類型:
const props = defineProps({
? gameId: Number,
? userInfo: {
? ? ? type: Object,
? ? ? required: true
? }
});
  • 使用類型注解進(jìn)行檢查
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', '點(diǎn)了我');
};
<Comp @kk="handleClick"/>
<script lang="ts" setup>
const handleClick = (data) => {
? console.log(data)
}
</script>

獲取上下文

  • 在標(biāo)準(zhǔn)組件寫法里,setup 函數(shù)默認(rèn)支持兩個(gè)入?yún)ⅲ?nbsp;

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

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決在el-dialog中無(wú)法正確獲取DOM的問(wèn)題

    解決在el-dialog中無(wú)法正確獲取DOM的問(wèn)題

    這篇文章主要介紹了解決在el-dialog中無(wú)法正確獲取DOM的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue打包使用Nginx代理解決跨域問(wèn)題

    vue打包使用Nginx代理解決跨域問(wèn)題

    這篇文章主要介紹了vue打包使用Nginx代理解決跨域問(wèn)題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • vue-router動(dòng)態(tài)路由實(shí)現(xiàn)前端權(quán)限管理方式

    vue-router動(dòng)態(tài)路由實(shí)現(xiàn)前端權(quán)限管理方式

    這篇文章主要介紹了vue-router動(dòng)態(tài)路由實(shí)現(xiàn)前端權(quán)限管理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • VUE學(xué)習(xí)寶典之el-dialog使用示例

    VUE學(xué)習(xí)寶典之el-dialog使用示例

    在我工作過(guò)程中使用el-dialog的需求挺多的,也積累了一下使用技巧,這篇文章主要給大家介紹了關(guān)于VUE學(xué)習(xí)寶典之el-dialog使用的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • Vue3利用縮放進(jìn)行屏幕分辨率適配的解決方案講解

    Vue3利用縮放進(jìn)行屏幕分辨率適配的解決方案講解

    本文詳細(xì)解析了如何在Vue3中實(shí)現(xiàn)一個(gè)自動(dòng)根據(jù)設(shè)計(jì)寬度縮放并調(diào)整高度的響應(yīng)式組件,組件的核心功能包括設(shè)計(jì)寬度設(shè)定、動(dòng)態(tài)縮放比例計(jì)算和高度調(diào)整,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • vue組件和iframe頁(yè)面的相互傳參問(wèn)題及解決

    vue組件和iframe頁(yè)面的相互傳參問(wèn)題及解決

    這篇文章主要介紹了vue組件和iframe頁(yè)面的相互傳參問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法

    Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法

    這篇文章主要介紹了Vue 3中常用的生命周期鉤子和監(jiān)聽器的操作方法,分析常用的一些生命周期鉤子和監(jiān)聽器可以幫助我們?cè)诮M件中處理數(shù)據(jù)加載、狀態(tài)變化和響應(yīng)式更新,需要的朋友可以參考下
    2024-07-07
  • uniapp使用webview內(nèi)嵌H5的注意事項(xiàng)詳解

    uniapp使用webview內(nèi)嵌H5的注意事項(xiàng)詳解

    在移動(dòng)應(yīng)用開發(fā)中,uniApp框架提供了一種跨平臺(tái)的解決方案,允許開發(fā)者使用一套代碼來(lái)構(gòu)建iOS、Android等多平臺(tái)的應(yīng)用,這篇文章主要給大家介紹了關(guān)于uniapp使用webview內(nèi)嵌H5的注意事項(xiàng),需要的朋友可以參考下
    2024-07-07
  • vue中methods、mounted等的使用方法解析

    vue中methods、mounted等的使用方法解析

    這篇文章主要介紹了vue中methods、mounted等的使用方法解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Vue實(shí)現(xiàn)多標(biāo)簽選擇器

    Vue實(shí)現(xiàn)多標(biāo)簽選擇器

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)多標(biāo)簽選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評(píng)論

和平区| 浮山县| 临潭县| 隆林| 鸡西市| 马尔康县| 交口县| 胶州市| 泗洪县| 长海县| 青龙| 当雄县| 西宁市| 土默特右旗| 德惠市| 葵青区| 马山县| 永清县| 岚皋县| 津南区| 茌平县| 兴海县| 海城市| 怀仁县| 东丰县| 南康市| 美姑县| 弥勒县| 乳源| 灵武市| 沙湾县| 荃湾区| 泸西县| 顺昌县| 襄城县| 巫山县| 和平县| 沈阳市| 平乡县| 扶绥县| 枣阳市|