VUE(相關簡介及初始)


1.什么是vue

Vue.js(讀音 /vjuː/, 類似於 view) 是一套構建用戶界面的 漸進式框架。與其他重量級框架不同的是,Vue 采用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,並且非常容易學習
,非常容易與其它庫或已有項目整合。另一方面,Vue 完全有能力驅動采用單文件組件和 Vue 生態系統支持的庫開發的復雜單頁應用。其實說白了Vue.js就是一個用於搭建類似於網頁版知乎這種
表單項繁多,且內容需要根據用戶的操作進行修改的網頁版應用。 Vue.js 的目標是通過盡可能簡單的 API 實現響應的數據綁定和組合的視圖組件。

Vue.js 自身不是一個全能框架——它只聚焦於視圖層。因此它非常容易學習,非常容易與其它庫或已有項目整合。另一方面,在與相關工具和支持庫一起使用時,Vue.js 也能完美地驅動復雜的單
頁應用。

Vue是一個數據驅動頁面的一個框架,基於MVVM模式,M指的是數據,V值得是視圖,VM是視圖模型,將數據綁定視圖上(雙向綁定)

這個框架着重於VM部分

技術分享

2.VUE誕生的背景

近幾年來,得益於手機設備的普及和性能的提升,移動端的web需求大量增加,產生了一種叫webapp的東西,也就是移動端的網頁應用。

它們功能越來越復雜,交互也越來越酷炫,功能與效果越來越接近於原生的APP。比如下面這些:

(效果直逼原生APP)

這種webapp它們不僅僅像h5營銷網頁一樣有酷炫的效果,它們還有復雜的點擊、輸入、下拉選擇,視圖切換等復雜的交互。在這樣的業務需求下,我們還是沿用PC端的開發方案,難免會不太合適。比如:視圖切換。

在PC端,視圖切換我們會用<a>標簽進行頁面的跳轉,但如果在移動端,那就歇菜了,你會遇到這樣的畫面:

(等到花兒都謝了)

這個時候用戶只能等.....3秒,5秒,8秒.......很難想象,在一個需要頻繁切換視圖的webapp里面,使用<a>標簽去實現,對用戶來說是很不友好的,換你你也不願意等那么久,反正我是不願意了....

此外,接收用戶輸入的同時,很可能要及時更新視圖,比如用戶輸入不同的內容,頁面就會相對應進行更新,點擊不同的選項,就會顯示不同的狀態等等交互效果。一旦這種交互多了,你要手動地進行操作,代碼就容易變得復雜和難以維護。

為了解決webapp這些的體驗和開發上的不足,我們決定學習並使用一個MVVM框架——Vue.js

2.什么是MVVM

MVVM可以拆分成:View --- ViewModel --- Model三部分 ,看下面的視圖:

那么,我們怎么理解MVVM呢?

上圖中,左側的View相當於我們的DOM內容,我們所看到的頁面視圖,右側的Model相當於我們的數據對象,比如一個對象的信息:

{
    name:'張三',
    age:30
}

而中間的監控者就負責監控兩側的數據,並相對應地通知另一側進行修改。比如:你在Model層中修改了name的值為:“李四”,那么View視圖層顯示的“張三”也會自動變成了“李四”,而這個過程就是有ViewModel來操作的,不需要你手動地去寫代碼去實現(你不用再手動操作DOM了)。

如果你寫過復雜的DOM操作,你就可以感受到它帶來的便利。

這就是MVVM框架,屬於MVVM的JS框架除了Vue.js,還有React.js,Angular.js。

3.Vue.js的優點

(1) 簡潔 (2) 輕量 (3)快速 (4) 數據驅動 (5) 模塊友好 (6) 組件化Vue

vue技術雙向綁定原理使我們開發頁面更簡單,比如我們以前用源生js開發頁面時候,書寫復雜可讀性差,后來用jquery開發頁面業務邏輯重復,可復用差,Vue通過數據雙向綁定是這一一切變得更簡單

Eg:(改變值)

Js:

<div></div>

 document.getElementsByTagName(‘div‘)[0].innerHTML = ‘韓國‘;

document.getElementsByTagName(‘div‘)[0].innerHTML = ‘中國‘

Jq

<div></div>

$(‘div‘).html(‘韓國‘)

$(‘div‘).html(‘中國‘)

Vue

Vue只提供一個Api就是Vue,它是類,我們要想獲取Vue實例化對象,只能通過new關鍵字創建

 通過el定義一個Vue視圖的容器元素,可以傳遞css選擇器,id選擇,類選擇器,元素名稱選擇器等等

 頁面中有多個符合條件選擇器,vue只會捕獲第一個符合條件的選擇器對應的元素選擇器

實現了將視圖到視圖模型的綁定

 

 <div>{{msg}}</div>

var data = {

  msg: ‘韓國‘

}

new Vue({

 el: ‘div‘,

  data: data

})

data.msg = ‘中國‘

 

通過data屬性可以為Vue實例化對象添加屬性,添加的屬性與外部的data中的數據是同步的
不論是修改外部data中的數據還是修改Vue實例化對象中的數據,他們的數據始終同步的
數據綁定實現了將模型到視圖模型的綁定
var data = {
msg: ‘國‘,
obj: {
color: ‘red‘
}
}
var app = new Vue({
el: ‘#app‘, 
data: data
})
console.log(data.msg === app.msg)   //true
console.log(app.obj === data.obj)   //true
// data.msg = ‘下周‘

4.Vue.js的兩大核心

鋪墊了這么多,終於講到了Vue的核心。

那么,我們就來認識一下Vue.js,這里摘取一段官網對它的介紹:

通過盡可能簡單的API實現響應的數據綁定和組合的視圖組件

這句話有兩個關鍵詞:數據綁定視圖組件

Vue的數據驅動:數據改變驅動了視圖的自動更新,傳統的做法你得手動改變DOM來改變視圖,vuejs只需要改變數據,就會自動改變視圖,一個字:爽。再也不用你去操心DOM的更新了,這就是MVVM思想的實現。

視圖組件化:把整一個網頁的拆分成一個個區塊,每個區塊我們可以看作成一個組件。網頁由多個組件拼接或者嵌套組成。看下圖:

具體在開發過程中怎樣實現一個組件,到底哪些區塊可以划分成一個組件,后面的章節我們再一一介紹,這里你只需要知道,在Vue.js中,網頁是可以看成多個組件組成的即可。

5.Vue.js的適用場景

如果你還在用jquery頻繁操作你的DOM來更新頁面的話,那么,你可以用Vue.js來解放你的DOM操作了。

如果你的項目中有多個部分是相同的,並可以封裝成一個組件,那么,你可以試試用Vue.js。

此外,Vue.js的核心實現中使用了ES5的Object.defineProperty特性,IE8及以下版本瀏覽器是不兼容的,所以,你的項目需要兼容這些較低版本的瀏覽器的話,那么,Vue.js就不適用了。

畢竟,開發一個項目的目的不是為了使用某個框架。

6.VUE.js安裝

我們可以在 Vue.js 的官網上直接下載 vue.min.js 並用 <script> 標簽引入。

下載 Vue.js

下載好以后,將文件保存到制定位置使用時直接引入即可

我們能發現,引入vue.js文件之后,Vue被注冊為一個全局的變量,它是一個構造函數。

7.相關學習准備

ES5和ES6

說到ES的時候順嘴說一下JavaScript

JavaScript一種動態類型、弱類型、基於原型的客戶端腳本語言,用來給HTML網頁增加動態功能。(好吧,概念什么最討厭了)

動態:

在運行時確定數據類型。變量使用之前不需要類型聲明,通常變量的類型是被賦值的那個值的類型。

弱類:

計算時可以不同類型之間對使用者透明地隱式轉換,即使類型不正確,也能通過隱式轉換來得到正確的類型。

原型:

新對象繼承對象(作為模版),將自身的屬性共享給新對象,模版對象稱為原型。這樣新對象實例化后不但可以享有自己創建時和運行時定義的屬性,而且可以享有原型對象的屬性。

PS:新對象指函數,模版對象是實例對象,實例對象是不能繼承原型的,函數才可以的。

JavaScript由三部分組成:

1. ECMAScript(核心)

作為核心,它規定了語言的組成部分:語法、類型、語句、關鍵字、保留字、操作符、對象

PS:*不完全兼容的實現

2. DOM(文檔對象模型)

DOM把整個頁面映射為一個多層節點結果,開發人員可借助DOM提供的API,輕松地刪除、添加、替換或修改任何節點。

PS:DOM也有級別,分為DOM1、DOM2、DOM3,拓展不少規范和新接口。

3. BOM (瀏覽器對象模型)

支持可以訪問和操作瀏覽器窗口的瀏覽器對象模型,開發人員可以控制瀏覽器顯示的頁面以外的部分。

PS:BOM未形成規范

什么是ES5

作為ECMAScript第五個版本(第四版因為過於復雜廢棄了),瀏覽器支持情況可看第一副圖,增加特性如下。

1. strict模式

嚴格模式,限制一些用法,'use strict';

2. Array增加方法

增加了every、some 、forEach、filter 、indexOf、lastIndexOf、isArray、map、reduce、reduceRight方法

PS: 還有其他方法 Function.prototype.bind、String.prototype.trim、Date.now

3. Object方法

Object.getPrototypeOf
Object.create
Object.getOwnPropertyNames
Object.defineProperty
Object.getOwnPropertyDescriptor
Object.defineProperties
Object.keys
Object.preventExtensions / Object.isExtensible
Object.seal / Object.isSealed
Object.freeze / Object.isFrozen
PS:只講有什么,不講是什么。

什么是ES6

ECMAScript6在保證向下兼容的前提下,提供大量新特性,目前瀏覽器兼容情況如下:

ES6特性如下:

1.塊級作用域 關鍵字let, 常量const

2.對象字面量的屬性賦值簡寫(property value shorthand)

var obj = {
    // __proto__
    __proto__: theProtoObj,
    // Shorthand for ‘handler: handler’
    handler,
    // Method definitions
    toString() {
    // Super calls
    return "d " + super.toString();
    },
    // Computed (dynamic) property names
    [ 'prop_' + (() => 42)() ]: 42
};

3.賦值解構

let singer = { first: "Bob", last: "Dylan" };
let { first: f, last: l } = singer; // 相當於 f = "Bob", l = "Dylan"
let [all, year, month, day] =  /^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec("2015-10-25");
let [x, y] = [1, 2, 3]; // x = 1, y = 2

4.函數參數 - 默認值、參數打包、 數組展開(Default 、Rest 、Spread)

//Default
function findArtist(name='lu', age='26') {
    ...
}

//Rest
function f(x, ...y) {
  // y is an Array
  return x * y.length;
}
f(3, "hello", true) == 6

//Spread
function f(x, y, z) {
  return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6

5.箭頭函數 Arrow functions

(1).簡化了代碼形式,默認return表達式結果。

(2).自動綁定語義this,即定義函數時的this。如上面例子中,forEach的匿名函數參數中用到的this。

6.字符串模板 Template strings

var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
// return "Hello Bob, how are you today?"

7. Iterators(迭代器)+ for..of

迭代器有個next方法,調用會返回:

(1).返回迭代對象的一個元素:{ done: false, value: elem }

(2).如果已到迭代對象的末端:{ done: true, value: retVal }

for (var n of ['a','b','c']) {
  console.log(n);
}
// 打印a、b、c

8.生成器 (Generators)

9.Class

Class,有constructor、extends、super,但本質上是語法糖(對語言的功能並沒有影響,但是更方便程序員使用)。

class Artist {
    constructor(name) {
        this.name = name;
    }

    perform() {
        return this.name + " performs ";
    }
}

class Singer extends Artist {

    constructor(name, song) {
        super.constructor(name);
        this.song = song;
    }

    perform() {
        return super.perform() + "[" + this.song + "]";
    }
}

let james = new Singer("Etta James", "At last");
james instanceof Artist; // true
james instanceof Singer; // true

james.perform(); // "Etta James performs [At last]"

10.Modules

ES6的內置模塊功能借鑒了CommonJS和AMD各自的優點:

(1).具有CommonJS的精簡語法、唯一導出出口(single exports)和循環依賴(cyclic dependencies)的特點。

(2).類似AMD,支持異步加載和可配置的模塊加載。

// lib/math.js
export function sum(x, y) {
  return x + y;
}
export var pi = 3.141593;

// app.js
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));

// otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));

Module Loaders:
// Dynamic loading – ‘System’ is default loader
System.import('lib/math').then(function(m) {
  alert("2π = " + m.sum(m.pi, m.pi));
});

// Directly manipulate module cache
System.get('jquery');
System.set('jquery', Module({$: $})); // WARNING: not yet finalized

11.Map + Set + WeakMap + WeakSet

四種集合類型,WeakMap、WeakSet作為屬性鍵的對象如果沒有別的變量在引用它們,則會被回收釋放掉。

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

//WeakMap
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });//Because the added object has no other references, it will not be held in the set

12.Math + Number + String + Array + Object APIs

一些新的API

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

"abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior

[0, 0, 0].fill(7, 1) // [0,7,7]
[1, 2, 3].find(x => x == 3) // 3
[1, 2, 3].findIndex(x => x == 2) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"

Object.assign(Point, { origin: new Point(0,0) })

13. Proxies

使用代理(Proxy)監聽對象的操作,然后可以做一些相應事情。

var target = {};
var handler = {
  get: function (receiver, name) {
    return `Hello, ${name}!`;
  }
};

var p = new Proxy(target, handler);
p.world === 'Hello, world!';

可監聽的操作: get、set、has、deleteProperty、apply、construct、getOwnPropertyDescriptor、defineProperty、getPrototypeOf、setPrototypeOf、enumerate、ownKeys、preventExtensions、isExtensible。

14.Symbols

Symbol是一種基本類型。Symbol 通過調用symbol函數產生,它接收一個可選的名字參數,該函數返回的symbol是唯一的。

var key = Symbol("key");
var key2 = Symbol("key");
key == key2  //false

15.Promises

Promises是處理異步操作的對象,使用了 Promise 對象之后可以用一種鏈式調用的方式來組織代碼,讓代碼更加直觀(類似jQuery的deferred 對象)。

function fakeAjax(url) {
  return new Promise(function (resolve, reject) {
    // setTimeouts are for effect, typically we would handle XHR
    if (!url) {
      return setTimeout(reject, 1000);
    }
    return setTimeout(resolve, 1000);
  });
}

// no url, promise rejected
fakeAjax().then(function () {
  console.log('success');
},function () {
  console.log('fail');
});

ES6簡單語法

****VUE相關編輯工具:Sublime text3****

let和const

es6新增了let命令,用來聲明變量。它的用法類似於var,但是所聲明的變量,只在let命令所在的代碼塊內有效。

 

上面代碼在代碼塊之中,分別用letvar聲明了兩個變量。然后在代碼塊之外調用這兩個變量,結果let聲明的變量報錯,var聲明的變量返回了正確的值。這表明,let聲明的變量只在它所在的代碼塊有效

<script type='text/javascript'   src='vue.min.js'></script>
<script type='text/javascript'> { //let聲明的變量是塊兒級作用域且使用let不能重復聲明變量 let a = 12; // 正確 } console.log(a); { let a = 10; // 錯誤,不可以重復聲明同一個變量 } console.log(a); // 報錯:Identifier 'a' has already been declared
</script>

下面我們來看一下var和let有什么區別

1 var a = [];
2 for (var i = 0; i < 10; i++) {
3   a[i] = function () {
4     console.log(i);
5   };
6 }
7 a[6]();

上面代碼中,變量ivar命令聲明的,在全局范圍內都有效,所以全局只有一個變量i。每一次循環,變量i的值都會發生改變,而循環內被賦給數組a的函數內部的console.log(i),里面的i指向的就是全局的i。也就是說,所有數組a的成員里面的i,指向的都是同一個i,導致運行時輸出的是最后一輪的i的值,也就是 10

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();

上面代碼中,變量ilet聲明的,當前的i只在本輪循環有效,所以每一次循環的i其實都是一個新的變量,所以最后輸出的是6。你可能會問,如果每一輪循環的變量i都是重新聲明的,那它怎么知道上一輪循環的值,從而計算出本輪循環的值?這是因為 JavaScript 引擎內部會記住上一輪循環的值,初始化本輪的變量i時,就在上一輪循環的基礎上進行計算

不存在變量提升

var命令會發生”變量提升“現象,即變量可以在聲明之前使用,值為undefined。這種現象多多少少是有些奇怪的,按照一般的邏輯,變量應該在聲明語句之后才可以使用。

為了糾正這種現象,let命令改變了語法行為,它所聲明的變量一定要在聲明后使用,否則報錯。

// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;

上面代碼中,變量foovar命令聲明,會發生變量提升,即腳本開始運行時,變量foo已經存在了,但是沒有值,所以會輸出undefined。變量barlet命令聲明,不會發生變量提升。這表示在聲明它之前,變量bar是不存在的,這時如果用到它,就會拋出一個錯誤。

不允許重復聲明 

let不允許在相同作用域內,重復聲明同一個變量。

// 報錯
function func() {
  let a = 10;
  var a = 1;
}

// 報錯
function func() {
  let a = 10;
  let a = 1;
}

因此,不能在函數內部重新聲明參數

function func(arg) {
  let arg; // 報錯
}

function func(arg) {
  {
    let arg; // 不報錯
  }
}

為什么需要塊級作用域?

ES5 只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。

 第一種場景,內層變量可能會覆蓋外層變量。

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}

f(); // undefined

上面代碼的原意是,if代碼塊的外部使用外層的tmp變量,內部使用內層的tmp變量。但是,函數f執行后,輸出結果為undefined,原因在於變量提升,導致內層的tmp變量覆蓋了外層的tmp變量。

第二種場景,用來計數的循環變量泄露為全局變量。

復制代碼
var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5
復制代碼

上面代碼中,變量i只用來控制循環,但是循環結束后,它並沒有消失,泄露成了全局變量。

 

const命令

基本語法

const聲明一個只讀的常量。一旦聲明,常量就會初始化且常量的值就不能改變。

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

上面代碼表明改變常量的值會報錯

const聲明的變量不得改變值,這意味着,const一旦聲明變量,就必須立即初始化,不能留到以后賦值

const foo;
// SyntaxError: Missing initializer in const declaration

上面代碼表示,對於const來說,只聲明不賦值,就會報錯

 

const的作用域與let命令相同:只在聲明所在的塊級作用域內有效。

if (true) {
  const MAX = 5;
}

MAX // Uncaught ReferenceError: MAX is not defined

模板字符串

<script type='text/javascript'  src='vue.min.js'></script>
<script type='text/javascript'>
    var a  = 1;
    var b =  2;
    var str =`哈哈${a}嘿嘿${b}`;
    console.log(str);

//如果想要在字符串中插入變量的話,只需插入變量名即可

</script>

箭頭函數

說到函數我們肯定不會感到陌生,之前就大量的接觸到了函數我們再來回顧一下

def  函數名(形參):
    '''
    形參1:
    形參2:
    return  返回值
   '''
   函數體
res = 函數名(實參)
print(res)

那么什么是箭頭函數呢?箭頭函數又該怎么寫呢?

基本語法:

ES6允許使用“箭頭”(=>)定義函數

var f = a = > a

//等同於
var f = function(a){
   return a;  
}

如果箭頭函數不需要參數或需要多個參數,就使用一個圓括號代表參數部分。

//無形參
var f = () => 5;
// 等同於
var f = function () { return 5 };

//多個形參
var sum = (num1, num2) => num1 + num2;
// 等同於
var sum = function(num1, num2) {
  return num1 + num2;
};

使用箭頭函數注意點:

箭頭函數有幾個使用注意點。

(1)函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。

 1  var name = '張三';   
 2  var person = {
 3         name:'小馬哥',
age:18,   4 fav:function(){ 5 console.log(this) 6 console.log(this.name) 7 } 8 } 9 10 person.fav();

我們發現,打印的結果為

此時this指向的是使用它的對象,也就是person對象

 var person2 = {
    name:'小馬哥',
    age:18,
    fav: ()=>{
         // 當前this指向了定義時所在的對象(window)
         console.log(this);
      }
    }

 person2.fav();

打印的結果:

使用箭頭函數,它表示定義時所在的對象window。

再看一個例子吧!

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 });
// id: 42

上面代碼中,setTimeout的參數是一個箭頭函數,這個箭頭函數的定義生效是在foo函數生成時,而它的真正執行要等到 100 毫秒后。如果是普通函數,執行時this應該指向全局對象window,這時應該輸出21。但是,箭頭函數導致this總是指向函數定義生效時所在的對象(本例是{id: 42}),所以輸出的是42

(2)不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。

         var person3 = {
             name:'小馬哥',
             age:18,
             fav: ()=>{
                 console.log(argument);
             }
         }

         person3.fav('把妹','把爺');

報出如下❎:

對象的單體模式

為什么要有對象單體模式?

為了解決箭頭函數this指向的問題 推出來一種寫法 對象的單體模式

1     var person = {
2         name:'小馬哥',
3         age:12,
4         fav(){
5             console.log(this.name,this.age);
6         }
7       }
8  person.fav();

ES6的面向對象

JavaScript 語言中,生成實例對象的傳統方法是通過構造函數。

       function Animal(name,age){
            this.name = name;
            this.age = age;

        }
        Animal.prototype.showName = function(){
            console.log(this.name);
            console.log(this.age);
        }

        var a = new Animal('小黃',5);
        a.showName();

上面這種寫法跟傳統的面向對象語言(比如 C++ 和 Java)差異很大,很容易讓新學習這門語言的程序員感到困惑。

ES6 提供了更接近傳統語言的寫法,引入了 Class(類)這個概念,作為對象的模板。通過class關鍵字,可以定義類。

基本上,ES6 的class可以看作只是一個語法糖,它的絕大部分功能,ES5 都可以做到,新的class寫法只是讓對象原型的寫法更加清晰、更像面向對象編程的語法而已。上面的代碼用 ES6 的class改寫,就是下面這樣

          class Animal{
            
            // 構造器  當你創建實例之后 constructor()方法會立刻調用 通常這個方法初始化對象的屬性
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
            showName(){
                console.log(this.name);
            }
        }
        var a2 = new Animal('點點',3);

上面代碼定義了一個“類”,可以看到里面有一個constructor方法,這就是構造方法,而this關鍵字則代表實例對象。也就是說,ES5 的構造函數Animal,對應 ES6 的Animal類的構造方法。

Animal類除了構造方法,還定義了一個showName方法。注意,定義“類”的方法的時候,前面不需要加上function這個關鍵字,直接把函數定義放進去了就可以了。另外,方法之間不需要逗號分隔,加了會報錯。

ES6 的類,完全可以看作構造函數的另一種寫法。

console.log(Animal2===Animal2.prototype.constructor);//true

上面代碼表示,類本身就指向了類的構造函數。

使用的時候,也是直接對類使用new命令,跟構造函數的用法完全一致。

constructor方法

constructor方法是類的默認方法,通過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,如果沒有顯式定義,一個空的constructor方法會被默認添加。

class Animal {
}

// 等同於
class Animal {
  constructor() {}
}

上面代碼中,定義了一個空的類Point,JavaScript 引擎會自動為它添加一個空的constructor方法。

NodeJs介紹

Nodejs英文網:https://nodejs.org/en/

中文網:http://nodejs.cn/

在這里我們會發現這樣一句話:

翻譯成中文如下:

Node.js 是一個基於 Chrome V8 引擎的 JavaScript 運行環境。 
Node.js 使用了一個事件驅動、非阻塞式 I/O 的模型,使其輕量又高效。 
Node.js 的包管理器 npm,是全球最大的開源庫生態系統。

上面的這段譯文也就說明了什么是NodeJs,當然了這只是比較官方的解釋,那么NodeJs究竟是什么呢?

什么是node?

    根據官方文檔可以知道,node就是一個給予谷歌v8引擎的一個javascript的運行時,可以理解為運行js的一個虛擬機。他使用的是一個 事件驅動,非阻塞I/O模型 ,他是將js的運行環境搬到了服務器端,和客戶端沒有一點關系。是一個純服務端的東西,node只是為js提供了一個平台。node里面其實還分了兩塊,一是封裝了v8引擎,目的是為了執行es(如定義變量,定義函數等),另外一個提供了大量的工具庫,是幫助node實現各種功能的,提供了一些以前js的環境辦不到的事情,比如文件操作,網絡操作,操作系統的操作。
    既然node是一個平台(所謂的平台就是用來運行特定語言的),也就意味着node是用來運行語言的,那么java也是語言,node能運行java嗎?據nodejs創始人Ryan Dahl回憶,他最初是選擇了Ruby這門語言,但是Ruby這門語言的虛擬機效率不怎么樣最終放棄了,按照這種思路,貌似node將java的虛擬機集成進來應該可以運行java,但node作者最終選擇了javascript。這樣js就實現了在服務端運行的可能,js運行在node平台上(分為v8部分,用來執行es,和大量的工具庫組件(API)稱之為libuv,提供了以前js的環境辦不到的事,如文件操作,網絡操作等等)。
知道了什么是node,應該還要清楚node在web中有什么用途?
    (1)node可以接受客戶端用戶的所有請求,並且能夠快速的給出響應,因此node可以用來做網站。
    (2)node可以作為一個中間層來來分發調用數據接口,比如有一個網站數據是有java提供的,我們可以讓node作為一個中間曾,來接受用戶的請求,然后通過node來調用java數據接口,獲取到數據后直接在node層面做html的瓶裝,然后將渲染好的頁面直接給用戶。為什么要這樣做,直接請求java接口不行嗎,這是因為node被稱之為高性能的web服務器,在並發和抗壓方面都比傳統的平台要好很多,因此這樣一包裝可以極大的減輕服務器的開發。
    通過上面的兩點,可以總結出,node在web中要么從前端頁面到后端服務全包了,一個是只做其中的一點。
    一言以蔽之,node就是一個javascript的運行環境(平台),他不是一門語言,也不是javascript的框架。可以用來開發服務端應用程序,web系統。其特點是體積小,快速,高性能。

Node中的NPM

首先我們先來了解一下什么是NPM?

簡單的說,npm就是JavaScript的包管理工具。類似Java語法中的maven,gradle,python中的pip

安裝

傻瓜式的安裝。

第一步:打開https://nodejs.org/en/

第二步:

第三步:我們為了統一版本,雖然node.js更新到了8.11.1的版本,但對於我個人而言,還是比較喜歡6.10.*版本的。

第四步:

第五步:點點點。為了避免環境變量出現額外的問題,winodows用戶將nodejs統一安裝在c盤中,mac電腦直接安裝。

 

 

npm是和Nodejs一起並存的,只要安裝了Nodejs,npm也安裝好了,安裝好Nodejs之后。打開終端,執行如下命令,檢查是否安裝成功

但是由於npm自身的更新頻率比Node.js高很多,所以通過上面安裝的npm可能不是最新版本,可以通過下面的命令單獨更新npm。在這里不簡易大家更新了。

針對mac電腦的用戶,如果執行

 

會出現如下錯誤;

解決方案:只需要

 

ok,到目前為止,我們的軟件都安裝好了。

既然我們知道npm它能夠管理我們的包,也就是我們所謂的模塊。

那么,比如在之前我們使用到的jquery框架,bootstrap框架。都可以使用npm去下載了。

 

安裝包

我們在桌面上創建一個文件夾/01-studyNpm。

注意:千萬不要起名成:node、npm這樣的文件夾,以免與系統軟件產生不必要的沖突。

打開終端,切換到當前創建的文件夾目錄下,一定是當前目錄。

 

npm 初始化

在去下載包之前,首先先讓當前項目的包進行初始化操作,執行命令:

npm init

運行這個命令后,它會詢問一些關於包的基本信息,根據實際情況回答即可。如果不喜歡這種方式,可以使用npm init --yes命令直接使用默認的配置來創建package.json文件,最后根據需要修改創建好的package.json文件即可。

復制代碼
{
  "name": "01-studynpm",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
復制代碼

主要字段的含義如下:

  • name: 模塊名, 模塊的名稱有如下要求:

    • 全部小寫
    • 只能是一個詞語,沒有空格
    • 允許使用破折號和下划線作為單詞分隔符
  • version: 模塊版本信息

  • description:關於模塊功能的簡單描述,如果這個字段為空的話,默認會從當前目錄的READMD.mdREADME文件讀取第一行內容作為它的默認值。

  • main: 模塊被引入后,首先加載的文件,默認為index.js

  • scripts: 定義一些常用命令入口

關於最后一個英文的意思,我們可以證明,當我執行npm init之后,會自動的生成package.json的文件。

 

安裝模塊

使用npm install會讀取package.json文件來安裝模塊。安裝的模塊分為兩類
dependenciesdevDependencies,分別對應生產環境需要的安裝包和開發環境需要的安裝包。

 

同樣在安裝模塊的時候,可以通過指定參數來修改package.json文件,以jquery和webpack做例子

npm install jquery --save

npm install webpack --save-dev

來將新安裝的模塊信息記錄到package.json文件.

我們正式操作一遍,下載jquery包

npm install jquery --save

 

執行以上命令,便可以安裝對應的包到執行命令的當前目錄,並創建一個node_modules的文件夾,然后把需要安裝的安裝包下載到里面。

 

打開package.json文件會發現:

 

下載不同版本的模塊

npm install jquery@2.0.1 --save

 

卸載模塊

npm uninstall jquery --save

 

使用cnpm(淘寶鏡像)

使用npm下載依賴時,由於是從國外的網站上下載內容,所以可能經常會出現不穩定的情況,所以需要下載cnpm代替npm,cnpm是國內淘寶的做的,在國內使用穩定。 

1.下載cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

2.使用cpm

cnpm install jquery --save

 

 

 

 

模塊化

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM