网站地图    收藏   

主页 > 前端 > vue教程 >

详解Vue3.0 前的 TypeScript 最佳入门实践

来源:自学PHP网    时间:2019-07-23 15:24 作者:小飞侠 阅读:

[导读] 详解Vue3.0 前的 TypeScript 最佳入门实践...

前言

1. 使用官方脚手架构建

npm install -g @vue/cli
# OR
yarn global add @vue/cli 。 。 选项,如下图:2. 项目目录解析 





3. TypeScript 极速入门  共享相同的基本类型,但有一些额外的类型。 与 Void
// 数字,二、八、十六进制都支持
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;

// 字符串,单双引都行
let name: string = "bob";
let sentence: string = `Hello, my name is ${ name }.

// 数组,第二种方式是使用数组泛型,Array<元素类型>:
let list: number[] = [1, 2, 3];
let list: Array = [1, 2, 3];

let u: undefined = undefined;
let n: null = null;
const messyArray = [' something', 2, true, undefined, null];
const tuple: [number, string, string] = [24, "Indrek" , "Lasn"]
// 默认情况从0开始为元素编号,也可手动为1开始
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

let colorName: string = Color[2];
console.log(colorName); // 输出'Green'因为上面代码里它的值是23. Void
let person: any = "前端劝退师"
person = 25
person = true
throw new Error(message)
return error("Something failed")
while (true) {} // 存在无法达到的终点3. 类型断言 :
let someValue: any = "this is a string";

let strLength: number = (someValue).length;
let strLength: number = (someValue as string).length;
function getLength(something: string | number): number {
 return something.length;
}

// index.ts(2,22): error TS2339: Property 'length' does not exist on type 'string | number'.
// Property 'length' does not exist on type 'number'.
function getLength(something: string | number): number {
 if ((something).length) {
 return (something).length;
 } else {
 return something.toString().length;
 }
}
 中,可以使用"泛型"来创建可复用的组件,并且组件可支持多种数据类型。这样便可以让用户根据自己的数据类型来使用组件。
function gen_func1(arg: T): T {
 return arg;
}
// 或者
let gen_func2: (arg: T) => T = function (arg) {
 return arg;
}
gen_func1('Hello world');
gen_func2('Hello world'); 
// 第二种调用方式可省略类型参数,因为编译器会根据传入参数来自动识别对应的类型。 在具体使用时,可以代替任意类型,咋一看两者好像没啥区别,其实不然:
// 方法一:带有any参数的方法
function any_func(arg: any): any {
 console.log(arg.length);
		return arg;
}

// 方法二:Array泛型方法
function array_func(arg: Array): Array {
	 console.log(arg.length);
		return arg;
} 参数的 length 可以代替任意类型,所以该方法在传入参数不是数组或者带有 length 的泛型类型,肯定会有 length
interface Generics_interface {
 (arg: T): T;
}
 
function func_demo(arg: T): T {
 return arg;
}

let func1: Generics_interface = func_demo;
func1(123); // 正确类型的实际参数
func1('123'); // 错误类型的实际参数 vs Type alias ,国内翻译成接口。 ,类型别名。Typescript 中的 interface 和 type 到底有什么区别
interface User {
 name: string
 age: number
}

type User = {
 name: string
 age: number
};

interface SetUser {
 (name: string, age: number): void;
}
type SetUser = (name: string, age: number): void; 和 type 可以 extends type 。 虽然效果差不多,但是两者语法不同
interface Name { 
 name: string; 
}
interface User extends Name { 
 age: number; 
}
type Name = { 
 name: string; 
}
type User = Name & { age: number };
type Name = { 
 name: string; 
}
interface User extends Name { 
 age: number; 
}
interface Name { 
 name: string; 
}
type User = Name & { 
 age: number; 
}
 不行
// 基本类型别名
type Name = string

// 联合类型
interface Dog {
 wong();
}
interface Cat {
 miao();
}

type Pet = Dog | Cat

// 具体定义数组每个位置的类型
type PetList = [Dog, Pet]
// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div
type StringOrNumber = string | number; 
type Text = string | { text: string }; 
type NameLookup = Dictionary; 
type Callback = (data: T) => void; 
type Pair = [T, T]; 
type Coordinates = Pair; 
type Tree = T | { left: Tree, right: Tree }; 可以而 type 能够声明合并
interface User {
 name: string
 age: number
}

interface User {
 sex: string
}

/*
User 接口为 {
 name: string
 age: number
 sex: string 
}
*/ 有可选属性和只读属性
interface Person {
 name: string;
 age?: number;
 gender?: number;
} 来指定只读属性,如下所示:
interface User {
 readonly loginName: string;
 password: string;
}

3.4 实现与继承: implementsTypeScript

interface IDeveloper {
 name: string;
 age?: number;
}
// OK
class dev implements IDeveloper {
 name = 'Alex';
 age = 20;
}
// OK
class dev2 implements IDeveloper {
 name = 'Alex';
}
// Error
class dev3 implements IDeveloper {
 name = 'Alex';
 age = '9';
}
 class A extends B implements C,D,E 和 type3.5 声明文件与命名空间: declare
// shims-tsx.d.ts
import Vue, { VNode } from 'vue';

declare global {
 namespace JSX {
 // tslint:disable no-empty-interface
 interface Element extends VNode {}
 // tslint:disable no-empty-interface
 interface ElementClass extends Vue {}
 interface IntrinsicElements {
 [elem: string]: any;
 }
 }
}

// shims-vue.d.ts
declare module '*.vue' {
 import Vue from 'vue';
 export default Vue;
} :当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。
  
  • declare function 声明全局方法
  • declare enum 声明全局枚举类型
  • declare module 扩展模块 :“内部模块”现在称做“命名空间” )跟其他 JS 库协同
    declare namespace D3{
     export interface Selectors { ... }
    }
    declare var d3: D3.Base; 中批量命名了数个内部模块。 shims-vue.d.ts 、 public 时,它就不能在声明它的类的外部访问,比如:
    
    class Animal {
     private name: string;
     constructor(theName: string) {
     this.name = theName;
     }
    }
    
    let a = new Animal('Cat').name; //错误,‘name'是私有的 类似,但是, protected
    
    class Animal {
     protected name: string;
     constructor(theName: string) {
     this.name = theName;
     }
    }
    
    class Rhino extends Animal {
     constructor() {
     super('Rhino');
     }  
     getName() {
     console.log(this.name) //此处的name就是Animal类中的name
     }
    } 
    
    function buildName(firstName: string, lastName?: string) {
     return firstName + ' ' + lastName
    }
    
    // 错误演示
    buildName("firstName", "lastName", "lastName")
    // 正确演示
    buildName("firstName")
    // 正确演示
    buildName("firstName", "lastName")
    
    
    
    let s = e!.name; // 断言e是非空并访问name属性官方文档,vue 结合 typescript ,有两种书写方式:
    
     import Vue from 'vue'
    
     const Component = Vue.extend({
     	// type inference enabled
     })
    
    import { Component, Vue, Prop } from 'vue-property-decorator'
    
    @Component
    export default class Test extends Vue {
     @Prop({ type: Object })
     private test: { value: string }
    }
    
    
    
    
    
    
     这个官方支持的库里,提供了函数 **装饰器(修饰符)**语法
    
    test(f){
     console.log("before ...");
     f()
    		console.log("after ...");
     }
    
    @test
    func(){
    	console.log("func was called");
    }
    
    
    after ... t里面的 function a (function () { ... });2. vue-property-decorator 提供的装饰器 的装饰器:
      
  • @Injectvue-class-component)vue-class-component) 的装饰器:
  • @Getter
  • @Mutation
    import {componentA,componentB} from '@/components';
    
    export default {
    	components: { componentA, componentB},
    	props: {
     propA: { type: Number },
     propB: { default: 'default value' },
     propC: { type: [String, Boolean] },
     }
     // 组件数据
     data () {
     return {
     message: 'Hello'
     }
     },
     // 计算属性
     computed: {
     reversedMessage () {
     return this.message.split('').reverse().join('')
     }
     // Vuex数据
     step() {
     	return this.$store.state.count
     }
     },
     methods: {
     changeMessage () {
     this.message = "Good bye"
     },
     getName() {
     	let name = this.$store.getters['person/name']
     	return name
     }
     },
     // 生命周期
     created () { },
     mounted () { },
     updated () { },
     destroyed () { }
    }
    
    import { Component, Vue, Prop } from 'vue-property-decorator';
    import { State, Getter } from 'vuex-class';
    import { count, name } from '@/person'
    import { componentA, componentB } from '@/components';
    
    @Component({
     components:{ componentA, componentB},
    })
    export default class HelloWorld extends Vue{
    	@Prop(Number) readonly propA!: number | undefined
     @Prop({ default: 'default value' }) readonly propB!: string
     @Prop([String, Boolean]) readonly propC!: string | boolean | undefined
     
     // 原data
     message = 'Hello'
     
     // 计算属性
    	private get reversedMessage (): string[] {
     	return this.message.split('').reverse().join('')
     }
     // Vuex 数据
     @State((state: IRootState) => state . booking. currentStep) step!: number
    	@Getter( 'person/name') name!: name
     
     // method
     public changeMessage (): void {
     this.message = 'Good bye'
     },
     public getName(): string {
     let storeName = name
     return storeName
     }
    	// 生命周期
     private created ():void { },
     private mounted ():void { },
     private updated ():void { },
     private destroyed ():void { }
    } 方法,因为这不应该公开给其他组件。 :
    
    import Vue from 'vue';
    import App from './App.vue';
    import router from './router';
    import store from './store';
    
    Vue.config.productionTip = false;
    
    new Vue({
     router,
     store,
     render: (h) => h(App),
    }).$mount('#app');
    
    import Vue from 'vue';
    import App from './App.vue';
    import router from './router';
    import store from './store';
    // 新模块
    import i18n from './i18n';
    
    Vue.config.productionTip = false;
    
    new Vue({
     router, 
     store, 
     i18n, // 新模块
     render: (h) => h(App),
    }).$mount('#app');
    
    // 声明全局方法
    declare module 'vue/types/vue' {
     interface Vue {
     readonly $i18n: VueI18Next;
     $t: TranslationFunction;
     }
    }
    

    Axios的封装千人千面

    $ npm i axios vue-axios
    
    import Vue from 'vue'
    import axios from 'axios'
    import VueAxios from 'vue-axios'
    
    Vue.use(VueAxios, axios)
    
    
    Vue.axios.get(api).then((response) => {
     console.log(response.data)
    })
    
    this.axios.get(api).then((response) => {
     console.log(response.data)
    })
    
    this.$http.get(api).then((response) => {
     console.log(response.data)
    })
    
    
    
    -api
     - main.ts // 实际调用
    -utils
     - request.ts // 接口封装
    
    import * as axios from 'axios';
    import store from '@/store';
    // 这里可根据具体使用的UI组件库进行替换
    import { Toast } from 'vant';
    import { AxiosResponse, AxiosRequestConfig } from 'axios';
     
     /* baseURL 按实际项目来定义 */
    const baseURL = process.env.VUE_APP_URL;
    
     /* 创建axios实例 */
    const service = axios.default.create({
     baseURL,
     timeout: 0, // 请求超时时间
     maxContentLength: 4000,
    });
    
    service.interceptors.request.use((config: AxiosRequestConfig) => {
     return config;
    }, (error: any) => {
     Promise.reject(error);
    });
    
    service.interceptors.response.use(
     (response: AxiosResponse) => {
     if (response.status !== 200) {
      Toast.fail('请求错误!');
     } else {
      return response.data;
     }
     },
     (error: any) => {
     return Promise.reject(error);
     });
     
    export default service;ajax.ts
    
    export interface AjaxResponse {
     code: number;
     data: any;
     message: string;
    } 接口调用:
    
    // api/main.ts
    import request from '../utils/request';
    
    // get
    export function getSomeThings(params:any) {
     return request({
     url: '/api/getSomethings',
     });
    }
    
    // post
    export function postSomeThings(params:any) {
     return request({
     url: '/api/postSomethings',
     methods: 'post',
     data: params
     });
    }5. 编写一个组件
    
    
    
    
    
    
    
    
    
    

    这就是简单的父子组件

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学php网。

    自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

    京ICP备14009008号-1@版权所有www.zixuephp.com

    网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

    添加评论