Vue.js 學習筆記


Vue.js

基礎

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

聲明式渲染

使用插值表達式,基於 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 指令實現雙向綁定

可以在一個 app 塊中綁定多個變量,在賦值的時候使用逗號隔開。這樣就漸漸的相當於 angula.js 使用 ng-app 聲明在 body上占地為王一樣

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

並且可以在瀏覽器調試頁,使用 app.變量名 = 值 ,替換變量的值。

條件與循環

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

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

<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;"

因此:對於經常需要進行顯示/隱藏切換的DOM標簽,使用 v-show 性能更加優異

循環: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/


免責聲明!

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



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