Vue.js 學習筆記

Vue.js

基礎

一套用於構建用戶界面的漸進式框架, 核心庫只關注視圖層,易於上手,便於與第三方庫或現有項目整合,且輕量。html

聲明式渲染

使用插值表達式,基於 MVVM 來動態的影響頁面與變量前端

# 頁面上鍵入插值表達式
<div id="app">
  {{ message }} # View 角色
</div>
# 而後,進行 ViewModle 數據綁定。是 VM 角色
var app = new Vue({ # 新建 Vue 實例
  el: '#app', # 經過ID選擇器,來接管 div 區域
  data: { 
    message: 'Hello Vue!' # 是 Model 角色
  }
})

雙向綁定

使用 v-modle 指令實現雙向綁定vue

能夠在一個 app 塊中綁定多個變量,在賦值的時候使用逗號隔開。這樣就漸漸的至關於 angula.js 使用 ng-app 聲明在 body上佔地爲王同樣node

var app = new Vue({
    el:'#app',
    data:{
        flag:true,
        user:"張三"
    }
});

而且能夠在瀏覽器調試頁,使用 app.變量名 = 值 ,替換變量的值。webpack

條件與循環

條件:v-if="變量名";

當變量的值爲 true 時,顯示被 v-if 指令所在標籤包裹的HTML內容。當值爲 false 刪除其所在html標籤web

<div id="app-3">
    <span v-if="flag">
        你能看見我嗎?
    </span>
</div>
var app3 = new Vue({
    el:'#app-3',
    data:{
        flag:true
    }
});

隱藏:v-show = "變量名";

當變量的值爲 false 時,爲DOM的HTML標籤添加CSS屬性: style="display: none;"vue-cli

所以:對於常常須要進行顯示/隱藏切換的DOM標籤,使用 v-show 性能更加優異npm

循環:v-for="臨時變量 in 變量"

<div id="app">
    <ur v-for="user in users">
        <li>{{user.name}}---{{user.age}} </li>
    </ur>
</div>
var app = new Vue({
    el:'#app',
    data:{
        users:[
            {"name":"張三","age":23}, # JSON格式定義對象
            {"name":"李四","age":24},
            {"name":"王五","age":25},
            {"name":"趙六","age":26}
        ]
    }
});
  • 在調試頁中可使用 app.users.push({"name":"xxx","age":23}) 動態添加數據
  • 定義一個惟一的字段做爲 key ,能夠提升遍歷效率
  • 在遍歷時以以下方式使用 index
<ur v-for="(user, index) in users":key="index">
    <li>{{index + 1}} {{user.name}}---{{user.age}}</li>
</ur>

處理用戶輸入

組件化

組件:頁面上的某一部分,當一個網頁很是大時,能夠將該網頁的內容拆分紅幾個部分,便於維護編程

定義組件

  1. 定義全局組件
Vue.component('todo-item', { # 經過 Vue.component('組件名',{組件內容}) 定義組件
   template : "<li>Item</li>" # 經過 template 屬性定義組件的內容
});
<ul>
    <todo-item></todo-item> <!-- 在頁面以標籤的方式使用組件 -->
</ul>
  1. 定義局部組件
// 定義局部組件
var TodoList = {
    template : "<li>Item</li>"
};
// 註冊局部組件
new Vue({
    el: '#app',
    components : {
        "todo-item" : TodoList # 仍然在頁面使用 todo-item 這個名字來使用組件
    })

利用組件實現 todolist

<ul>
    <!-- 在使用組件的時候,能夠進行傳值,使用 : 變量名 = 「值」 -->
    <todo-item
            v-for="(content, index) in list"  
            :key="index" 
            :content="content" 
    ></todo-item>
</ul>
// 全局組件
Vue.component('todo-item', {
    props : ['content'], # 用來接收傳過來的值
    template: "<li>{{content}}</li>" # 使用插值表達式來顯示值
});

組件和實例的關係

一個組件也是一個實例瀏覽器

​ 組件裏面也能夠寫:methods / data / computed 屬性

任何Vue項目都是由 n 個實例構成的

​ 對於根實例,雖然沒有顯式的定義 template 模板屬性,可是Vue會根據 el 屬性,去找掛載點,將掛載點裏面的所有內容做爲模板

組件之間的交互

父子組件之間的交互

父組件向子組件傳遞數據:

​ 使用 : 屬性名 = 「值」 的方式傳遞,子組件 使用 props : ["屬性名1", "屬性名2"] 的方式接收

子組件向父組件傳遞數據:

​ 使用 : this.$emit("消息名", 參數) 的方式來發送消息,在父組件的模板中使用 @消息名 = 「函數名」 的方式來接收消息並處理。

具體的使用見練習2.

掛載點、模板、實例

掛載點: el 屬性綁定的DOM標籤。用來聲明Vue的做用域。不包含標籤內部的變量

模板: 掛載點內部的HTML內容統稱爲模板。模板的定義方式有兩種:

  • 直接定義在掛載點所在的標籤體內
  • 在 Vue 實例裏使用 template 定義:
var app = new Vue({
    el:'#app',
    # 模板內容會覆蓋本來掛載點裏面的內容,請注意
    template:"<h1>Hello {{msg}}</h1>", # 定義模板時,須要用標籤來包裝內容,不然沒法識別
    data:{
        msg:"Hello World"
    }
});

實例:建立的 Vue 對象

使用

安裝

Vue.js 不支持IE8及如下版本,由於他使用了IE8不支持的 ECMAScript5 的特性。

引入核心庫

<!-- 開發環境下引入完成包,生產環境引 min.js 包 -->
<script src="./vue.js"></script>

指令

以 v- 做爲前綴,vue指令會在渲染的DOM上應用特殊的響應行爲。

v-text

綁定DOM標籤內的text文本內容。若是內容中存在HTML標籤,會被原樣展現

v-html

綁定DOM標籤內HTML內容

v-on:click = "functionName"

  • 綁定單擊事件。注意:單擊調用的方法只寫方法名,不寫小括號
  • 在實例中定義 methods 對象,對象內部能夠定義方法
  • 另外, v-on:click 也能夠簡寫成: @click
var app = new Vue({
    el:'#app',
    data:{
        text:"Hello"
    },
    methods:{ # 這個屬性用來定義實例中的方法
        changeText : function () {
            app.text = "World"
        }
    }
});
// 或者能夠採用 this.text 的方式來更改 text
changeText : function () {
    this.text = "World"
}

屬性綁定

v-bind:title="title"

爲 title 屬性後面的內容賦予了特殊的意義。例如此例中 「」 內的 title 表示Vue實例中的title變量的值

v-bind: 能夠簡寫爲 :

計算屬性

computed

用來對變量進行一些運算操做。

優勢:當參與運算的變量沒有改變時,結果會採用上一次的緩存值

<div id="app">
    姓:<input v-model="firstName"/>
    名:<input v-model="lastName"/>
    <div>{{fullName}}</div>
</div>

使用 computed 屬性來定義參計算結果的函數

new Vue({
    el:'#app',
    data:{
        firstName:"", # 必須提早定義爲 「」 不然頁面會顯示fullName爲 undefined
        lastName:""
    },
    computed:{ # 定義計算屬性
        fullName : function () {
            return this.firstName + " " + this.lastName; # 返回字符串拼接結果
        }
    }
});

偵聽器

watch

監聽某個數據的變化,當它產生變化時,執行回調函數

watch: { # 定義偵聽器
    fullName : function () { # 偵聽的變量爲 fullName 
        this.count ++ ; # 回調函數方法體
    }
}

練習1

vue1

需求:如上面的動圖,當輸入框輸入內容後,點擊提交就會在下面的列表展現新添加的數據,若是用戶沒有寫任何數據點擊提交,提示他應該輸入以後才能點擊

<div id="app">
    <input v-model="num" ref="id"/>  <!-- 添加ref屬性,以便使用Vue選擇器來獲取該輸入框的 -->
    <button @click="add">提交</button>

    <ul>  <!-- 添加key屬性,提升遍歷速度 -->
        <li v-for="(entity, index) in list":key="index">{{entity.num}}</li>
    </ul>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data:{
            num:"",
            list:[
                {num:1},
                {num:2},
                {num:3},
                {num:4}
            ]
        },
        methods:{
            add : function () {
                if(this.num){
                    this.list.push({num:this.num});
                    this.num = ""; # 添加完成後,刪除原來的數據
                }else {
                    alert("請輸入要添加的內容後重試!");
                    this.$refs.id.focus(); # vue語法,讓輸入框得到焦點,提升用戶體驗
                }
            }
        }
    });
</script>

練習2

完成 TodoList 中點擊某個 li 刪除它的功能

<div id="app">
    <input v-model="num" ref="id"/>
    <button @click="add">提交</button>

<ul>
    <todo-item
            v-for="(content, index) in list"
            :key="index"  
            :content="content"   父組件向子組件傳遞數據
            :index="index"
            @delete = "handleDelete" 父組件的訂閱方法
    ></todo-item>
</ul>
</div>
<script>
    // 全局組件
    Vue.component('todo-item', {
        props : ['content', 'index'], # 子組件接收數據
        template: '<li @click="deleteItem">{{content}}</li>', # 綁定點擊事件
        methods:{
            deleteItem:function () {
                this.$emit("delete", this.index); # 子組件向父組件發送消息,攜帶該 li 的index 數據
            }
        }
    });

    new Vue({
        el: '#app',
        data: {
            num: "",
            list: []
        },
        methods: {
            add: function () {
                if (this.num) {
                    this.list.push(this.num);
                    this.num = "";
                } else {
                    alert("請輸入要添加的內容後重試!");
                    this.$refs.id.focus();
                }
            },
            handleDelete : function (index) { # 父組件收到消息後執行刪除方法,刪除對應 index 的 li 標籤
                // alert(index);
                this.list.splice(index, 1);
            }
        }
    });
</script>

Vue 腳手架工具 vue-cli

首先安裝 node.js

1564726440925

下載地址:

https://nodejs.org/en/download/

下載對應系統的版本,雙擊安裝便可。安裝完成後會自動添加全局變量。使用 node -v 來確認是否安裝成功

安裝 NPM

(Node Package Manager)他是node包管理和分發的工具,使用NPM能夠對應用的依賴進行管理,NPM的功能和服務端項目構建工具maven差很少,咱們經過npm 能夠很方便地下載js庫,打包js文件。
node.js已經集成了npm工具,在命令提示符輸入 npm -v 可查看當前npm版本

設置包路徑,

包路徑就是npm從遠程下載的js包所存放的路徑。使用 npm config ls 查詢NPM管理包路徑(NPM下載的依賴包所存放的路徑)

使用下面的命令來設置:

npm config set prefix "C:\develop\nodeJS\npm_modules"
npm config set cache "c:\develop\nodeJS\npm_cache"
  1. 安裝淘寶的鏡像。鏡像默認是使用國外的網絡來下載的。網速很慢,所以咱們配置一個國內的鏡像
npm install -g cnpm --registry=https://registry.npm.taobao.org

安裝完成後使用:cnpm -v 來查看

注意:若是安裝後,出現 cnpm 不是內部或外部命令,也不是可運行的程序。就須要檢查cnpm 的路徑是否正確。將 cnpm包的全部文件複製和 npm.cmd 文件在同一級目錄下便可。

究其緣由:是由於環境變量中僅僅配置了 npm.cmd 所在文件夾路徑,咱們也能夠將 npm_modules 目錄添加到環境變量中,這樣也不會出現這個問題。推薦使用該方法

添加環境變量:

1564731885562

在 PATH 中添加:

1564731919317

安裝 nrm

cnpm install -g nrm

切換鏡像

查看已安裝的鏡像 : nrm ls 切換鏡像 nrm use XXX

最後,安裝 vue-cli 客戶端

npm install --global vue-cli

建立新的Vue項目

  1. 建立一個文件夾,用於存放和維護 Vue 項目,這裏我建立的是 c:\develop\VueProjects
  2. 切換到該文件夾,打開cmd。而後輸入: vue init webpack 項目名
  3. 配置按照下圖設置
    1564734104979

最後一行選項選擇的是包/依賴安裝方式

  1. 建立完成後,切換到項目路徑。使用 npm run dev 命令啓動項目

將項目導入IDEA

這裏由於我電腦上只有IDEA而且懶得安裝前端編程IDE,因此就使用IDEA來編程

安裝後會存在一個問題,IDEA 並不能正確識別 .vue 文件(我是2018.2版本,不知新版解決沒有),所以會將.vue文件識別成普通文本文件,給咱們編碼帶來很大的不便,解決辦法如圖:

1564735407072

另外,IDEA也不能識別ES6語法,咱們也須要進行一些配置:

1564735699406

經過上面的兩個設置,就能夠愉快的使用 IDEA 進行 Vue 項目編程啦!

Vue-Cli 中編輯的項目是支持熱部署的,耶!

Vue項目結構

項目根目錄下有一個 index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>todolist</title>
  </head>
  <body>
    <div id="app"></div> <!-- 這裏定義了一個 app 的掛載點 -->
    <!-- built files will be auto injected -->
  </body>
</html>

src 目錄下有 main.js 是 Vue 項目的入口js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App }, # 這裏採用 ES6 的語法,若是某 key 和 value 是同樣的,能夠簡寫成 key
  template: '<App/>'
})

能夠看出,入口文件引入了同目錄下的 App.vue 文件,那麼這個文件裏面有什麼內容呢?

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <HelloWorld/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

因而可知,Vue 項目對各個模塊進行了拆分,以達到解耦的目的。具體的好處且往下看

練習3

使用 vue-cli 實現 TodoList

  1. 打開上面建立的 TodoList 項目,修改 App.vue 文件名稱爲 TodoList.vue , 並修改其餘文件中的引用名
  2. 編輯 TodoList.vue 的模板文件,代碼以下:
<template>
  <div>
    <input>
    <button>提交</button>
  </div>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
</template>

這時打開瀏覽器會發現報錯了

1565001521769

所以咱們對模板文件進行修改,使用一個 div 包裹上面的兩個標籤,發現瀏覽器能夠正常顯示了

數據綁定

在 vue-cli 中,數據綁定採用另一種語法:此時數據不是直接綁定,而是間接經過函數來返回

<script>
    export default {
      <!-- 如下是 data : function(){} 的縮寫 -->  
      data(){
        return {
          inputValue : ""
        }
      }
    }
</script>

單擊事件

給提交按鈕添加單擊事件:

<button @click="handleClick">提交</button>

定義函數:依然能夠採用 ES6 的語法,簡略的寫成 handleClick(){}

<script>
    export default {
      methods:{
        handleClick (){
          alert(123)
        }
      }
    }
</script>

創建子組件

vue-cli 的子組件放在 compontents 目錄下:

1565002961390

  1. 複製一份乾淨的 .vue 代碼,起名 TodoItem.vue
<template>

</template>

<script>
export default {

}
</script>

<style>

</style>
  1. 添加模板數據,在 TodoList.vue 實例中引入 TodoItem.vue 組件,並註冊
<script>
// 引入組件, import 組件名 from 組件路徑
import TodoItem from './components/TodoItem'

export default {
  // 註冊組件, ‘組件標籤名’:組件名 
  components:{
    'todo-item' : TodoItem
  },
......
  1. 找到合適的位置,添加組件標籤
<ul>
    <todo-item></todo-item>
</ul>

父組件向子組件傳值

經過定義屬性的方式來給子組件傳值

定義 content 屬性,index 屬性傳給子組件

<ul>
    <todo-item
    v-for="(item, index) of list"
        :key="index"
        :content="item"
        :index="index"
    ></todo-item>
</ul>

子組件聲明接收的值:

<script>
    export default {
      props:['content']
    }
</script>

經過插值表達式來顯示值:

<template>
    <li>{{content}}</li>
</template>

子組件向父組件傳值

經過發佈/訂閱的方式來實現子組件向父組件傳值

在子組件的單擊方法中定義發佈消息的事件,事件名 delete, 參數:當前 li 元素的 index

handleDelete(){
    this.$emit('delete', this.index)
}

父組件接收消息:並觸發函數的執行

<ul>
      <todo-item
        v-for="(item, index) of list"
        :key="index"
        :content="item"
        :index="index"
        @delete="handleDelete" // 接收消息
      ></todo-item>
</ul>

handleDelete (index){
    this.list.splice(index, 1) // 刪除對應的元素
}

全局樣式與局部樣式

對於每個 vue 文件都包含 style 標籤,這個 style 標籤有一個屬性 scoped 若是添加此屬性則該標籤內全部的樣式僅對當前文件有效。開發中儘可能都添加上使得文件間的耦合性更低

結語

這個筆記僅涵蓋了 Vue 的一點點基礎知識,若是讀者想要深刻學習,能夠前往官網參考文檔繼續學習:https://cn.vuejs.org/v2/guide/

相關文章
相關標籤/搜索