TypeScript 重学之—实战笔记

523 阅读4分钟

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

1, 实战前奏

实例属性必须通过实例去访问

静态属性必须通过类去访问

class Person1 {
    // 定义实例属性
    name: string = 'zlm';
    // 在属性前面使用static 关键字定义的为: 静态属性,是类的方法
    static age: number = 12;
    // 只读属性,无法修改
    readonly sex: boolean = false;

    sayHello() {
        console.log("hello world")
    }
}
const person = new Person1()
console.log(person.name)
console.log(Person1.age)
console.log(person.sayHello())

构造函数:在 new Person()的时候,constructor执行

在实例方法中,this就表示当前的实例

可以通过this 向新建的对象中添加属性

class Dog {
    name: string;
    age: number;
    // 构造函数,在对象创建的时候调用,
    constructor(name:string, age:number) {
        this.name = name;
        this.age = age;
    }
    bark() {
        alert(123)
    }
}
const dog = new Dog('小河', 4)

继承:使用继承之后,子类将会拥有所有父类的方法和属性

重写:如果子类中添加类父类相同的方法,父类会被覆盖,这叫重写

一个子类想调用父类的方法: super.sayHello()

子类如果写了构造函数,必须要调用super()

抽象类:以abstract开头的类是抽象类,抽象类和其他区别: 抽象类不能用来创建对象,抽象类是专门用来继承的类, 抽象方法,没有方法体,子类必须对抽象方法进行实现

**接口:**用来定义一个类结构,定义一个类中应该包含哪些属性和方法,同时也可以当成类型声明去使用

type myType2 = {
    name: string,
    age: number
}
interface myInterface {
    name: string;
    age: number
}
const Obj:myType2 = {
    name: 'zlm',
    age: 19
}
const Obj2:myInterface = {
    name: 'zlm',
    age: 20
}

Type 和 interface 可以同样的使用

Type 和 interface的区别: 接口可以限制类的结构,接口只定义,不能有实际的值,

**实现接口 ** :必须实现接口中所有的方法

class myInter implements myInterface {
    name: string;
    age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
}

语法糖:

class myInter implements myInterface {
    constructor(public name: string, public age: number) {
        this.name = name
        this.age = age
    }
}

泛型: 遇到类型不明确的就可以使用泛型

// 不规范的写法
function fnn(a:any): any {
   return a;
}

// 定义一个泛型T 来实现
function fnnn<T>(a: T): T {
   return a;
}
function fun<T,K>(a:T, b:K) :T {
   return a;
}
// 对泛型进行控制
interface Inter {
   length: number;
}
// 表示泛型T继承接口Inter, 实现类
function fn3<T extends Inter>(a: T): number {
   return a.length
}

2,项目实战

下面是一个贪吃蛇的代码,还没有完全实现,一遍学习一遍开发,持续更新

样式文件:index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇</title>
</head>
<body>
    <!-- 创建游戏的主容器-->
    <div id="main">
        <!--游戏舞台-->
        <div id="stage">
            <div id="snake">
                 <div></div>
            </div>
            <!-- 设置食物-->
            <div id="food">
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
        </div>
        <!-- 游戏积分牌-->
        <div id="socre-panel">
            <div>
                SCORE: <span id="score">0</span>
            </div>
            <div>
                LEVEL: <span id="level">1</span>
            </div>

        </div>

    </div>
</body>
</html>

CSS文件

// 设置颜色变量
@bg-color: #b7d4a8;
// 清除默认样式
* {
    margin: 0;
    padding: 0;
    // 改变盒子模型的计算方式
    box-sizing: border-box;
}
body {
    font: bold 20px "Courier"
}
// 设置主窗口的样式
#main {
 width: 360px;
 height: 420px;
 background-color: @bg-color;
 margin: 100px auto;
 border: 10px solid black;
 border-radius: 10px;
 // 开启弹性盒模型
 display: flex;
 // 设置主轴方法
 flex-flow: column;
 // 设置辅轴的对齐方式
 align-items: center;
 // 设置主轴的对齐方式
 justify-content: space-around;
 #stage {
     width: 304px;
     height: 304px;
     border: 2px solid black;
     margin: 0 auto;
     position: relative;
     // 设置蛇的样式
     #snake {
         &>div {
           width: 10px;
           height: 10px;
           background-color: #000;
           border: 1px solid @bg-color;
           // 开启绝对定位
           position: absolute;
         }
     }
     #food {
        width: 10px;
        height: 10px;
        position: absolute;
        left: 40px;
        top: 100px;
        display: flex;
        // 设置横轴为主轴,wrap 表示自动换行
        flex-flow: row wrap;
        justify-content: space-between;
        align-content: space-between;
        &>div {
            width: 4px;
            height: 4px;
            background-color: black;
            transform: rotate(45deg);
        }
     }
 }
 // 计分牌
 #socre-panel {
     width: 300px;
     display: flex;
     justify-content: space-around;
 }
}

TS文件

// 引入央视 
import './style/index.less'
// 定义食物类
class Food {
    // 定义一个食物所对应的元素
    element: HTMLElement;
    constructor() {
        this.element = document.getElementById('food')!; // 加!表示ID不可能为空
    }
    // 获取食物X轴坐标
    get X() {
        return this.element.offsetLeft
    }
    // 获取食物Y轴坐标
    get Y() {
        return this.element.offsetTop
    }
    // 修改食物的位置
    change() {
        // 生成一个随机数字, 最大290, 最小0, 并且是10的整数倍
        let top = Math.round(Math.random() * 29) * 10
        let left = Math.round(Math.random() * 29) * 10
        this.element.style.left = left + 'px';
        this.element.style.top = top + 'px';
    }
}

// 测试代码
const food = new Food()
console.log(food.X, food.Y)
food.change()
console.log(food.X, food.Y)

// 定义计分牌类
class ScorePanel {
    score = 0;
    level = 1;
    scoreEle: HTMLElement;
    levelEle: HTMLElement;
    constructor() {
        this.scoreEle = document.getElementById('score')!;
        this.levelEle = document.getElementById('level')!;
    }
    // 设置加分方法
    addScore() {
        this.score ++;
        this.scoreEle.innerHTML = ++this.score + '';
    }
    // 升级的方法
    levelUp() {
        if(this.level < 10) {
            this.levelEle.innerHTML = ++this.level + '';
        }
    }
}

附上webpack的配置文件

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// webpack 中的所有配置信息都应该写在module.exports中
module.exports = {
    // 指定入口文件
    entry: './src/index.ts',
    // 指定打包文件所在的目录
    output: {
         // 打包后的文件
         filename: "bundle.js",
         // 指定打包文件的目录
         path: path.resolve(__dirname, 'dist'),
        //  environment: { // 配置打包环境,,告诉webpack不用箭头函数
        //      arrowFunction: true, // 不用箭头函数
        //      const: false
        //  }
    },
    // 指定webpack 打包时要使用的模块
    module: {
        // 指定加载的规则
        rules: [
            {
                test: /\.ts$/,    // test指定的是规则生效的文件
                 // 要使用的loader
                use: [
                 // 配置babel
                   {
                      // 指定加载去
                      loader: "babel-loader",
                      // 设置babel
                      options: {
                          // 设置预定义的环境
                          presets: [
                              [
                                  // 指定环境的插件
                                  "@babel/preset-env",
                                  // 配置信息
                                  {   
                                      // 要兼容的目标浏览器
                                      targets: {
                                          "chrome": "88",
                                      },
                                      // 指定corejs的版本
                                      "corejs": "3",
                                      // 使用corejs的方法,"usage" 表示按需加载
                                      "useBuiltIns": "usage"
                                  }
                              ]
                          ]
                      }
                   },
                   'ts-loader'
                ],
                exclude: /node_modules/ // 要排查的文件
            },
            // 设置less 文件的处理
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    // 引入postcss
                    {
                       loader: "postcss-loader",
                       options: {
                           postcssOptions: [
                               [
                                   "postcss-preset-env",
                                   {
                                       browsers: 'last 2 versions'
                                   }
                               ]
                           ]
                       }
                    },
                    "less-loader"
                ]
            }
        ]
    },
    // 配置webpack 插件
    plugins: [
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
          title: '这是自定义Title',
          template: "./src/index.html"
      })
    ],
    // 用来设置引入模块
    resolve: {
        extensions: ['.ts', '.js']
    }
}

后话

这是typeScript的实战笔记,目前这个游戏还在学习开发中,后续会持续更新,并附上完整的github地址