class類(lèi)學(xué)習(xí) — 封裝elementUI的dialog組件

前言

在ES6之前予权,準(zhǔn)確來(lái)說(shuō)JavaScript語(yǔ)言只有對(duì)象站刑,沒(méi)有類(lèi)的概念。生成實(shí)例對(duì)象的傳統(tǒng)方法是通過(guò)構(gòu)造函數(shù)敲街,與傳統(tǒng)的面向?qū)ο笳Z(yǔ)言(比如 C++ 和 Java)差異很大团搞,ES6 提供了更接近傳統(tǒng)語(yǔ)言的寫(xiě)法,引入了 class(類(lèi))這個(gè)概念多艇,作為對(duì)象的模板逻恐。通過(guò)class關(guān)鍵字,可以定義類(lèi)峻黍。但需要清楚的是ES6中class只是構(gòu)造函數(shù)的一種語(yǔ)法糖复隆,并非新鮮玩意,class能實(shí)現(xiàn)的奸披,我們通過(guò)ES5構(gòu)造函數(shù)同樣可以實(shí)現(xiàn)昏名。

一、構(gòu)造函數(shù)與class寫(xiě)法的部分區(qū)別

【1.1】構(gòu)造函數(shù)

  function Person(name, age) {
    this.name = name;
    this.age = age;
  }
  Person.prototype.sayHi = function () {
    console.log("您好");
  };
  let person = new Person("dingFY", 20);
  console.log(person.name) // dingFY
  console.log(person.age) // 20
  person.sayHi() // 您好

【1.2】類(lèi)

  class Person {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    };
    sayHi() {
      console.log("您好");
    };
  };
  let person = new Person('dingFY', 20);
  console.log(person.name) // dingFY
  console.log(person.age) // 20
  person.sayHi() // 您好

【1.3】 主要區(qū)別

  1. 構(gòu)造函數(shù)名Person在class寫(xiě)法時(shí)變成了類(lèi)名阵面,但調(diào)用方式不變轻局,依然通過(guò)new關(guān)鍵字創(chuàng)建實(shí)例
  2. 構(gòu)造函數(shù)中this相關(guān)操作,在class寫(xiě)法時(shí)歸納到了constructor方法中样刷,也就是說(shuō)ES5的構(gòu)造函數(shù)Person對(duì)應(yīng)ES6的Person類(lèi)中的constructor構(gòu)造方法
  3. ES5中原型上的方法sayHi在ES6 class寫(xiě)法中直接寫(xiě)在了內(nèi)部仑扑,同時(shí)省略了function關(guān)鍵字
// 對(duì)于方法添加,下面這兩種寫(xiě)法是等效的
// ES5
function Parent() {};
Parent.prototype = {
    constructor: function () {},
    sayName: function () {},
    sayAge: function () {}
};

// ES6
class Parent {
    constructor() {}
    sayName() {}
    sayAge() {}
};

// constructor()置鼻、sayName()镇饮、sayAge()這三個(gè)方法,其實(shí)都是定義在Parent.prototype上面
// 因此箕母,在類(lèi)的實(shí)例上面調(diào)用方法储藐,其實(shí)就是調(diào)用原型上的方法俱济。

二、類(lèi)的基礎(chǔ)用法

【2.1】類(lèi)定義

  // 匿名類(lèi)
  let Example = class {
    constructor(a) {
      this.a = a;
    }
  }
  // 命名類(lèi)
  let Example = class Example {
    constructor(a) {
      this.a = a;
    }
  }

【2.2】類(lèi)聲明

// 類(lèi)聲明
class Example {
  constructor(a) {
    this.a = a;
  }
}

// 不可重復(fù)聲明
// class Example {}
// class Example {} 
// 報(bào)錯(cuò):Uncaught SyntaxError: Identifier 'Example' has already been declared

// let Example = class {}
// class Example {} 
// 報(bào)錯(cuò):Uncaught SyntaxError: Identifier 'Example' has already been declared

【2.3】注意

  • class不存在變量提升钙勃,所以需要先定義再使用蛛碌。因?yàn)镋S6不會(huì)把類(lèi)的聲明提升到代碼頭部,但是ES5就不一樣辖源,ES5存在變量提升蔚携,可以先使用,然后再定義克饶。
//ES5可以先使用再定義,存在變量提升
new A();
function A(){}

//ES6不能先使用再定義,不存在變量提升 會(huì)報(bào)錯(cuò)
new B(); // Uncaught ReferenceError: Cannot access 'B' before initialization
class B{}
  • 在類(lèi)中聲明方法的時(shí)候酝蜒,千萬(wàn)不要給該方法加上function關(guān)鍵字,方法之間也不要用逗號(hào)分隔矾湃,否則會(huì)報(bào)錯(cuò)
  class Example {
    constructor(a) {
      this.a = a;
    }
    getName() {}      // 不需要逗號(hào)
    function getAge() // 報(bào)錯(cuò)
  }
  • 類(lèi)的內(nèi)部所有定義的方法亡脑,都是不可枚舉的,這與ES5構(gòu)造函數(shù)行為不一致
  class Example {
      constructor(x, y) {}
      getName() {}
  }
  console.log(Object.keys(Example.prototype)) // []
  console.log(Object.getOwnPropertyNames(Example.prototype))  // ["constructor","getName"]
  • constructor()方法是類(lèi)的默認(rèn)方法洲尊,通過(guò)new命令生成對(duì)象實(shí)例時(shí)远豺,自動(dòng)調(diào)用該方法。一個(gè)類(lèi)必須有constructor()方法坞嘀,如果沒(méi)有顯式定義躯护,一個(gè)空的constructor()方法會(huì)被默認(rèn)添加。
class Example {}
// 等同于
class Example {
  constructor() {}
}
  • 通過(guò)class類(lèi)創(chuàng)建實(shí)例必須使用new關(guān)鍵字丽涩,不使用會(huì)報(bào)錯(cuò)棺滞,這點(diǎn)與構(gòu)造函數(shù)不同,在ES5中其實(shí)我們不使用new也能調(diào)用構(gòu)造函數(shù)創(chuàng)建實(shí)例矢渊,雖然這樣做不符合規(guī)范继准。
  // ES6
  class Person {
    constructor() {}
  };
  let person = Person(); // 報(bào)錯(cuò)

  // ES5
  let Person = function (name) {
    this.name = name;
  };
  let person = Person(); // 不符合規(guī)范
  • 與 ES5 一樣,類(lèi)的所有實(shí)例共享一個(gè)原型對(duì)象

  class Person {
    constructor() {}
  };

  let p1 = new Person()
  let p2 = new Person()
  console.log(p1.__proto__ === p2.__proto__) // true
  • ES6 的類(lèi)只是 ES5 的構(gòu)造函數(shù)的一層包裝矮男,所以函數(shù)的許多特性都被Class繼承移必,包括name屬性。name屬性總是返回緊跟在class關(guān)鍵字后面的類(lèi)名毡鉴。
class Person{}
Person.name // "Point"
  • 類(lèi)和模塊的內(nèi)部崔泵,默認(rèn)就是嚴(yán)格模式,所以不需要使用use strict指定運(yùn)行模式

三猪瞬、取值函數(shù)(getter)和存值函數(shù)(setter)

與 ES5 一樣憎瘸,在“類(lèi)”的內(nèi)部可以使用getset關(guān)鍵字,對(duì)某個(gè)屬性設(shè)置存值函數(shù)和取值函數(shù)陈瘦,攔截該屬性的存取行為

class Person {
    constructor() {
        // ...
    }
    get name() {
        return 'getter';
    }
    set name(value) {
        console.log('setter: ' + value);
    }
}

let son = new Person();

son.name = 'dingFY' // setter: dingFY
console.log(son.name) // getter

四幌甘、靜態(tài)屬性和靜態(tài)方法

【4.1】靜態(tài)屬性

靜態(tài)屬性指的是 Class 本身的屬性,寫(xiě)法是在實(shí)例屬性的前面,加上static關(guān)鍵字

class Person {
    static age = 18;
    constructor() {
        console.log(Person.age); 
    }
}
let person = new Person() // 18

【4.2】靜態(tài)方法

類(lèi)相當(dāng)于實(shí)例的原型锅风,所有在類(lèi)中定義的方法酥诽,都會(huì)被實(shí)例繼承。如果在一個(gè)方法前皱埠,加上static關(guān)鍵字盆均,就表示該方法不會(huì)被實(shí)例繼承,而是只能在類(lèi)內(nèi)部使用或者直接通過(guò)類(lèi)來(lái)調(diào)用漱逸,這就稱為“靜態(tài)方法”。如果靜態(tài)方法包含this關(guān)鍵字游沿,這個(gè)this指的是類(lèi)饰抒,而不是實(shí)例。父類(lèi)的靜態(tài)方法诀黍,可以被子類(lèi)繼承袋坑。

  class Foo {
    static classMethod() {
      console.log('test')
    }
  }

  // 類(lèi)調(diào)用靜態(tài)方法
  Foo.classMethod() // 'test'

  // 實(shí)例調(diào)用靜態(tài)方法
  let foo = new Foo();
  foo.classMethod() // TypeError: foo.classMethod is not a function
  class Foo {
    static classMethod() {
      console.log('test')
    }
  }

  // 父類(lèi)的靜態(tài)方法可以被子類(lèi)繼承
  class Bar extends Foo {}
  Bar.classMethod() // 'test'

五、Class 的繼承

  • class 通過(guò) extends 關(guān)鍵字實(shí)現(xiàn)類(lèi)的繼承眯勾,子類(lèi)可以繼承父類(lèi)的所有屬性和方法枣宫。
class Person {}
class Son extends Person {}
  • 子類(lèi) constructor 方法中必須有 super ,且必須出現(xiàn)在 this 之前吃环,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)
    class Person {
        constructor(age) {
            this.age = age
        }
        sayHi() {
            return '您好'
        }
    }

    class Son extends Person {
        constructor(age, name) {
            super(age) // 子類(lèi)繼承必須要有super(), 且必須在this前面
            this.name = name
        }
        sayHi() {
            console.log(super.sayHi() + `也颤,我是${this.name}`)
        }
    }

    let son = new Son(18, 'dingFY');
    console.log(son.age) // 18
    console.log(son.name) // dingFY
    son.sayHi() // 您好,我是dingFY

六郁轻、實(shí)例

【6.1】封裝彈框組件

  // dialog組件封裝
  class Dialog {
    constructor(options) {
      // 合并默認(rèn)配置和用戶傳的配置參數(shù)翅娶;
      this.opts = Object.assign({
        width: "30%",
        height: "200px",
        title: "標(biāo)題",
        content: "內(nèi)容",
        dragable: false, //是否可拖拽
        maskable: true, //是否有遮罩
        isCancel: true, //是否有取消按鈕
        success() {
          console.log('點(diǎn)擊確定按鈕處理邏輯'); //
        },
        cancel() {
          console.log('點(diǎn)擊取消按鈕處理邏輯');
        }
      }, options);
      this.init(); // 自動(dòng)調(diào)用
    }
    init() {
      // 渲染視圖
      this.renderView();
      // 捕獲彈框點(diǎn)擊事件
      this.dialogHtml.onclick = e => {
        switch (e.target.className) {
          case 'k-close': // 關(guān)閉按鈕
            this.close();
            this.opts.cancel();
            break;
          case 'k-cancel': // 取消按鈕
            this.close();
            this.opts.cancel();
            break;
          case 'k-primary': // 確定按鈕
            this.close();
            this.confim();
            break;
        }
      }
    }

    // 確定按鈕操作
    confim(value) {
      this.opts.success(value);
    }

    //關(guān)閉對(duì)話框;
    close() {
      this.dialogHtml.querySelector(".k-wrapper").style.display = "none";
      this.dialogHtml.querySelector(".k-dialog").style.display = "none";
    }

    // 顯示對(duì)話框好唯;
    open() {
      // 是否顯示遮罩層
      if (this.opts.maskable) {
        this.dialogHtml.querySelector(".k-wrapper").style.display = "block";
      }
      // 是否可拖拽
      if (this.opts.dragable) {
        let dialog = this.dialogHtml.querySelector(".k-dialog")
        let drag = new Drag(dialog);
      }
      this.dialogHtml.querySelector(".k-dialog").style.display = "block";
    }

    // 渲染視圖
    renderView() {
      this.dialogHtml = document.createElement("div");
      this.dialogHtml.innerHTML = `<div class="k-wrapper"></div>
                <div class="k-dialog"  style="width:${this.opts.width};height:${this.opts.height}">
                    <div class="k-header">
                        <span class="k-title">${this.opts.title}</span><span class="k-close">X</span>
                    </div>
                    <div class="k-body">
                        <span>${this.opts.content}</span>
                    </div>
                    <div class="k-footer">
                        ${this.opts.isCancel ? '<span class="k-cancel">取消</span>' : ''}
                        <span class="k-primary">確定</span>
                    </div>
                </div>`;
      document.querySelector("body").appendChild(this.dialogHtml);
    }
  }

【6.2】封裝拖拽方法

  // 拖拽方法封裝
  class Drag {
    constructor(ele) {
      this.ele = ele
      this.downFn();
    }

    // 按下鼠標(biāo)
    downFn() {
      this.ele.onmousedown = e => {
        let ev = e || window.event;
        let x = ev.clientX - this.ele.offsetLeft;
        let y = ev.clientY - this.ele.offsetTop;
        this.moveFn(x, y);
        this.upFn();
      }
    }

    // 移動(dòng)鼠標(biāo)
    moveFn(x, y) {
      this.ele.onmousemove = e => {
        let ev = e || window.event;
        let xx = ev.clientX;
        let yy = ev.clientY;
        this.setStyle(xx - x, yy - y);
      }
    }

    // 設(shè)置拖拽后元素的定位
    setStyle(leftNum, topNum) {
      leftNum = leftNum < 0 ? 0 : leftNum;
      topNum = topNum < 0 ? 0 : topNum;
      this.ele.style.left = leftNum + "px";
      this.ele.style.top = topNum + "px";
    }

    // 鼠標(biāo)抬起
    upFn() {
      this.ele.onmouseup = () => {
        this.ele.onmousemove = "";
      }
    }
  }

【6.3】通過(guò)繼承封裝擴(kuò)展彈框組件

  // 擴(kuò)展Dialog, 可輸入內(nèi)容
  class ExtendsDialog extends Dialog {
    constructor(options) {
      super(options);
      this.renderInput();
    }
    renderInput() {
      let myInput = document.createElement("input");
      myInput.type = "text";
      myInput.classList.add("input-inner");
      this.dialogHtml.querySelector(".k-body").appendChild(myInput);
    }
    confim() {
      let value = this.dialogHtml.querySelector(".input-inner").value;
      super.confim(value);
    }
  }

【6.4】完整代碼

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .k-dialog {
      width: 30%;
      z-index: 2001;
      display: block;
      position: absolute;
      background: #fff;
      border-radius: 2px;
      box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
      margin: 0 auto;
      top: 15vh;
      left: 30%;
      display: none;
    }

    .k-wrapper {
      position: fixed;
      left: 0px;
      top: 0px;
      bottom: 0px;
      right: 0px;
      background: black;
      opacity: 0.4;
      z-index: 2000;
      display: none;
    }

    .k-header {
      padding: 10px 20px 30px;
    }

    .k-header .k-title {
      line-height: 24px;
      font-size: 18px;
      color: #303133;
      float: left;
    }

    .k-body {
      padding: 30px 20px;
      color: #606266;
      font-size: 14px;
    }

    .k-footer {
      padding: 10px 20px 30px;
      position: absolute;
      bottom: 0;
      right: 0;
    }

    .k-close {
      color: #909399;
      font-weight: 400;
      float: right;
      cursor: pointer;
    }

    .k-cancel {
      color: #606266;
      border: 1px solid #dcdfe6;
      text-align: center;
      cursor: pointer;
      padding: 12px 20px;
      font-size: 14px;
      border-radius: 4px;
      font-weight: 500;
      margin-right: 10px;
    }

    .k-cancel:hover {
      color: #409eff;
      background: #ecf5ff;
      border-color: #c6e2ff;
    }

    .k-primary {
      border: 1px solid #dcdfe6;
      text-align: center;
      cursor: pointer;
      padding: 12px 20px;
      font-size: 14px;
      border-radius: 4px;
      font-weight: 500;
      background: #409eff;
      color: #fff;
      margin-left: 10px;
    }

    .k-primary:hover {
      background: #66b1ff;
    }

    .k-input {
      width: 100%;
      margin-left: 20px;
      margin-bottom: 20px;
    }

    .input-inner {
      -webkit-appearance: none;
      background-color: #fff;
      background-image: none;
      border-radius: 4px;
      border: 1px solid #dcdfe6;
      box-sizing: border-box;
      color: #606266;
      display: inline-block;
      font-size: inherit;
      height: 40px;
      line-height: 40px;
      outline: none;
      padding: 0 15px;
      transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
      width: 100%;
      margin-top: 20px;
    }
  </style>
</head>

<body>
  <button class="dialog1">dialog1</button>
  <button class="dialog2">dialog2</button>
</body>
<script>
  // 拖拽方法封裝
  class Drag {
    constructor(ele) {
      this.ele = ele
      this.downFn();
    }

    // 按下鼠標(biāo)
    downFn() {
      this.ele.onmousedown = e => {
        let ev = e || window.event;
        let x = ev.clientX - this.ele.offsetLeft;
        let y = ev.clientY - this.ele.offsetTop;
        this.moveFn(x, y);
        this.upFn();
      }
    }

    // 移動(dòng)鼠標(biāo)
    moveFn(x, y) {
      this.ele.onmousemove = e => {
        let ev = e || window.event;
        let xx = ev.clientX;
        let yy = ev.clientY;
        this.setStyle(xx - x, yy - y);
      }
    }

    // 設(shè)置拖拽后元素的定位
    setStyle(leftNum, topNum) {
      leftNum = leftNum < 0 ? 0 : leftNum;
      topNum = topNum < 0 ? 0 : topNum;
      this.ele.style.left = leftNum + "px";
      this.ele.style.top = topNum + "px";
    }

    // 鼠標(biāo)抬起
    upFn() {
      this.ele.onmouseup = () => {
        this.ele.onmousemove = "";
      }
    }
  }

  // dialog組件封裝
  class Dialog {
    constructor(options) {
      // 合并默認(rèn)配置和用戶傳的配置參數(shù)竭沫;
      this.opts = Object.assign({
        width: "30%",
        height: "200px",
        title: "標(biāo)題",
        content: "內(nèi)容",
        dragable: false, //是否可拖拽
        maskable: true, //是否有遮罩
        isCancel: true, //是否有取消按鈕
        success() {
          console.log('點(diǎn)擊確定按鈕處理邏輯'); //
        },
        cancel() {
          console.log('點(diǎn)擊取消按鈕處理邏輯');
        }
      }, options);
      this.init(); // 自動(dòng)調(diào)用
    }
    init() {
      // 渲染視圖
      this.renderView();
      // 捕獲彈框點(diǎn)擊事件
      this.dialogHtml.onclick = e => {
        switch (e.target.className) {
          case 'k-close': // 關(guān)閉按鈕
            this.close();
            this.opts.cancel();
            break;
          case 'k-cancel': // 取消按鈕
            this.close();
            this.opts.cancel();
            break;
          case 'k-primary': // 確定按鈕
            this.close();
            this.confim();
            break;
        }
      }
    }

    // 確定按鈕操作
    confim(value) {
      this.opts.success(value);
    }

    //關(guān)閉對(duì)話框;
    close() {
      this.dialogHtml.querySelector(".k-wrapper").style.display = "none";
      this.dialogHtml.querySelector(".k-dialog").style.display = "none";
    }

    // 顯示對(duì)話框骑篙;
    open() {
      // 是否顯示遮罩層
      if (this.opts.maskable) {
        this.dialogHtml.querySelector(".k-wrapper").style.display = "block";
      }
      // 是否可拖拽
      if (this.opts.dragable) {
        let dialog = this.dialogHtml.querySelector(".k-dialog")
        let drag = new Drag(dialog);
      }
      this.dialogHtml.querySelector(".k-dialog").style.display = "block";
    }

    // 渲染視圖
    renderView() {
      this.dialogHtml = document.createElement("div");
      this.dialogHtml.innerHTML = `<div class="k-wrapper"></div>
                <div class="k-dialog"  style="width:${this.opts.width};height:${this.opts.height}">
                    <div class="k-header">
                        <span class="k-title">${this.opts.title}</span><span class="k-close">X</span>
                    </div>
                    <div class="k-body">
                        <span>${this.opts.content}</span>
                    </div>
                    <div class="k-footer">
                        ${this.opts.isCancel ? '<span class="k-cancel">取消</span>' : ''}
                        <span class="k-primary">確定</span>
                    </div>
                </div>`;
      document.querySelector("body").appendChild(this.dialogHtml);
    }
  }

  // 當(dāng)用戶點(diǎn)擊dialog1按鈕創(chuàng)建彈框
  document.querySelector(".dialog1").onclick = function () {
    let dialog1 = new Dialog({
      width: '30%',
      height: "200px",
      title: "彈框標(biāo)題",
      content: "彈框內(nèi)容",
      dragable: true,
      isCancel: true,
      maskable: true,
      success() {
        console.log('點(diǎn)擊確定按鈕處理邏輯');
      },
      cancel() {
        console.log('點(diǎn)擊確定按鈕處理邏輯');
      }
    })
    dialog1.open();
  }

  // 擴(kuò)展Dialog, 可輸入內(nèi)容
  class ExtendsDialog extends Dialog {
    constructor(options) {
      super(options);
      this.renderInput();
    }
    renderInput() {
      let myInput = document.createElement("input");
      myInput.type = "text";
      myInput.classList.add("input-inner");
      this.dialogHtml.querySelector(".k-body").appendChild(myInput);
    }
    confim() {
      let value = this.dialogHtml.querySelector(".input-inner").value;
      super.confim(value);
    }
  }

  // 當(dāng)用戶點(diǎn)擊dialog2按鈕創(chuàng)建彈框
  document.querySelector(".dialog2").onclick = function () {
    let dialog2 = new ExtendsDialog({
      width: "30%",
      height: "250px",
      title: "擴(kuò)展彈框",
      content: "擴(kuò)展彈框內(nèi)容",
      isCancel: true,
      maskable: true,
      success(val) {
        console.log(val);
      },
      cancel() {
        console.log('點(diǎn)擊取消');
      }
    })
    dialog2.open();
  }
</script>

</html>

【6.5】查看效果

文章每周持續(xù)更新蜕提,可以微信搜索「 前端大集錦 」第一時(shí)間閱讀,回復(fù)【視頻】【書(shū)籍】領(lǐng)取200G視頻資料和30本PDF書(shū)籍資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末靶端,一起剝皮案震驚了整個(gè)濱河市谎势,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌躲查,老刑警劉巖它浅,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異镣煮,居然都是意外死亡姐霍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)镊折,“玉大人胯府,你說(shuō)我怎么就攤上這事『夼撸” “怎么了骂因?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)赃泡。 經(jīng)常有香客問(wèn)我寒波,道長(zhǎng),這世上最難降的妖魔是什么升熊? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任俄烁,我火速辦了婚禮,結(jié)果婚禮上级野,老公的妹妹穿的比我還像新娘页屠。我一直安慰自己,他們只是感情好蓖柔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布辰企。 她就那樣靜靜地躺著,像睡著了一般况鸣。 火紅的嫁衣襯著肌膚如雪牢贸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天懒闷,我揣著相機(jī)與錄音十减,去河邊找鬼。 笑死愤估,一個(gè)胖子當(dāng)著我的面吹牛帮辟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玩焰,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼由驹,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了昔园?” 一聲冷哼從身側(cè)響起蔓榄,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎默刚,沒(méi)想到半個(gè)月后甥郑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荤西,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年澜搅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伍俘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勉躺,死狀恐怖癌瘾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情饵溅,我是刑警寧澤妨退,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站蜕企,受9級(jí)特大地震影響咬荷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轻掩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一萍丐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧放典,春花似錦、人聲如沸基茵。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拱层。三九已至弥臼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間根灯,已是汗流浹背径缅。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烙肺,地道東北人纳猪。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像桃笙,于是被迫代替她去往敵國(guó)和親氏堤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • React中創(chuàng)建組件 第一種 - 創(chuàng)建組件的方式 使用構(gòu)造函數(shù)來(lái)創(chuàng)建組件搏明,如果要接收外界傳遞的數(shù)據(jù)鼠锈,需要在構(gòu)造函數(shù)...
    AizawaSayo閱讀 221評(píng)論 0 0
  • 1.基本語(yǔ)法 JavaScript 語(yǔ)言中,生成實(shí)例對(duì)象的傳統(tǒng)方法是通過(guò)構(gòu)造函數(shù)星著。 ES6引入了Class(類(lèi))的...
    YINdevelop閱讀 1,021評(píng)論 0 1
  • 簡(jiǎn)介 JavaScript語(yǔ)言中购笆,生成實(shí)例對(duì)象的傳統(tǒng)方法是通過(guò)構(gòu)造函數(shù)。 ES6引入了Class(類(lèi))這個(gè)概念虚循,作...
    oWSQo閱讀 365評(píng)論 0 0
  • 前言 雖然class在實(shí)際開(kāi)發(fā)中已經(jīng)被大量使用同欠,仍然打算做一篇整理好好梳理一下样傍。 基本語(yǔ)法 js語(yǔ)言中,生成實(shí)例對(duì)...
    AmazRan閱讀 141評(píng)論 0 0
  • 一行您、class基本知識(shí) 1铭乾、class類(lèi)簡(jiǎn)介 本質(zhì)上,ES6 的類(lèi)只是 ES5 的構(gòu)造函數(shù)的一層包裝娃循,是基于jav...
    黎貝卡beka閱讀 1,894評(píng)論 0 5