前端筆記之Vue(一)初識SPA和Vue&webpack配置和vue安裝&指令

1、單頁面應用(SPA

1.1 C/SB/S頁面架構的轉變

C/S:客戶端/服務器(Client/Server)架構的軟件。javascript

C/S 軟件的特色:css

① 從window桌面雙擊打開html

② 更新的時候會替換原有的,原有的必須刪除,不能刷新。前端

③ 在其餘的設備上使用的時候,也要安裝軟件。vue

B/S :瀏覽器和服務器(Browser/Server)架構java

 

B/S 軟件的特色:node

不須要安裝任何的客戶端,是經過瀏覽器輸入網址打開的。webpack

更新的時候不須要從新安裝軟件,你只須要刷新頁面,程序就能更新。web

在其餘設備端,不須要安裝任何其餘的軟件,瀏覽器足能夠解決全部的問題。正則表達式

 

Dashboard叫作儀表盤項目,通俗的講就是***管理平臺。好比進銷存管理平臺、汽車銷售管理平臺、寵物店管理平臺。

 

特色1:這種項目幾乎都是單頁面應用(Single Page Application)簡稱SPA

將原來PC桌面的應用程序,放到瀏覽器中實現。如今的用人需求很大,不論是政府機構、教育機構、外包機構、銷售機構都在開發本身的新項目,或者把老項目搬到網頁上。好比阿里雲的管理平臺,特別像桌面的app,如今是在瀏覽器中實現的。

 

全部頁面的URL網址,只有#後面的內容在變化,而#以前的內容沒有變化,整個項目就是一個html頁面。

 

 

 

 

 網頁沒有發生跳轉,而是DOM的總體上樹、下樹。這樣的好處是,讓本地變量能夠在本地持久的時間變長。使用頁面內的錨點hash符號來標記的路由,也就是說點擊任何連接,頁面實際上沒有任何跳轉,全部頁面的改變都是JS完成的,JS命令一些組件消失,命令新的一些組件上樹。因此稱爲「單頁面應用」

 

頁面的URL沒有變化,變化的只是hash符號後面的部分:

 

 

特色2:都是組件化的

兩個不一樣的頁面中(其實是一個頁面),都有日期選擇框,發現日期選擇框都是相同的,咱們叫作「組件(components)」。

 

 

 

 

 也就是說,這些日曆組件,不論是HTMLCSSJavaScript都能複用。

 

下圖中的每個紅框均可以認爲是組件:

 

 

特色3:全部的DOM元素都是動態上下樹的

查看頁面源代碼,發現頁面上的全部DOM結構都不在源代碼中,也就是說DOM結構是JavaScript程序控制上樹的,全部的部件,都是組件、組件嵌套組件、集體被JavaScript上樹。

 

 

總結,一個好的單頁面應用的框架,必需要能提供:

優秀的路由機制,能捕獲用戶URLhash部分,決定什麼組件顯示和隱藏;

JavaScript控制組件動態上樹、下樹的能力;

l 組件的建立、複用、嵌套能力;

l 組件的數據傳遞的能力。


1.2三大框架的出現

AngularReactVue都是作什麼的?

它們都是JS架構,都是用來作單頁面應用設計的。

 

Angular

AngularJS 誕生於2009年,由Misko Hevery 等人建立,後爲Google所收購。是一款優秀的前端JS框架,已經被用於Google的多款產品當中。Angular是第一個實現「數據變化,視圖自動變化」的框架,而且獨創了組件化開發模式。Angular有着諸多特性,最爲核心的是:MVC、模塊化、自動化雙向數據綁定、語義化標籤、依賴注入、服務、控制器等等。

Angular的出現,有了前端的組件化。

前端的組件化開發:它是一種易於插拔,模塊化的開發形式。HTMLCSSJS邏輯都封裝到一個組件中,在其餘的頁面能夠輕鬆地顯示。

 AngularAMD模式,項目須要使用require.js配合,和時代的CMD主流背道而馳,2015年開始落寞了。Angular2016年出了22017年出了45,都是CMD模式的,可是用戶已經不買帳了。

 

 

React

React 起源於 Facebook 的內部項目,由於該公司對市場上全部 JavaScript MVC 框架,都不滿意。就決定本身寫一套,用來架設Instagram 的網站。作出來之後,發現這套東西很好用,就在20135月開源了。

React主要用於構建UI。你能夠在React裏傳遞多種類型的參數,如聲明代碼,幫助你渲染出UI、也能夠是靜態的HTML DOM元素、也能夠傳遞動態變量、甚至是可交互的應用組件。

React很是輕,只提供了少許了API,和相關的組件。

React能夠ReduxFlux等框架配合使用。

React 使用 Virtual DOM技術,使他渲染更快速,內存開銷小。

ReactCMD模式的,而且創造性的和webpack進行合做,將全部的js代碼實時構建爲一個js文件,編程的時候很是的清爽,很是利於團隊合做,因此大量的用戶就開始使用React開發本身的項目。

 

 

Vue

Vue是中國人尤雨溪發明的,它的數據驅動視圖的實現是最優雅的。它是一個集大成者,集成了AngularReact的優勢,摒棄了它們的缺點。是一個構建數據驅動的 web 界面的漸進式框架。Vue.js 的目標是經過儘量簡單的 API 實現響應的數據綁定和組合的視圖組件。它不只易於上手,還便於與第三方庫或既有項目整合。

Vue的做者,發現了JS的一個神奇之處,Object.defineProperty的做用,能夠用於視圖的更新。

 

 

AngularJS實現的機理是髒檢查。

React 是setState()。


2、Vue介紹

2.1官網和做者

官網:https://cn.vuejs.org/

Vue是一門mvvm的框架,繼承了Angular的雙向數據綁定和指令的優勢,繼承了React的快速製做組件的能力,同時也擁有很是相似與Redux的單向數據流動的思想,最主要Vueapi都是中文的,很是好學。

 

2.2 Vue是一門mvvm框架

MVVM框架:一切的視圖都是和數據相關聯的。數據變化了,視圖就自動變化。而不須要控制器去命令模塊作什麼而後渲染什麼視圖

 

ReactVueAngular都是簡化了模塊化開發,這些MVVM框架到底簡化了什麼

1)組件方便建立了(建立一個組件只須要寫一個類或者一個函數)

2)組件的可插拔性高

3)組件的數據傳輸簡單了

4)路由,單頁面應用的hash路由

5)只關心數據,不關心DOM

數據叫作model(模型),由於對數據的全部操做都是模型的任務;視圖叫作view。在MVVM中出現了view-model這個層,它能夠「監聽」model 的任何改變,讓視圖自動變化。從而咱們不須要關心DOM操做,只須要關心數據的變化便可。

ReactVueAngular中都提供了view-model層。

 

好比,數據:

[
    {"id":1,"name":"小明","age":12},
    {"id":2,"name":"小紅","age":12},
    {"id":3,"name":"小強","age":12},
]

它有對應的DOM結構:

<table>
    <tr>
        <td>1</td>
        <td>小明</td>
        <td>12</td>
    </tr>
    <tr>
        <td>2</td>
        <td>小紅</td>
        <td>12</td>
    </tr>
    <tr>
        <td>3</td>
        <td>小強</td>
        <td>12</td>
    </tr>
</table>
結構

第一次根據數據建立DOM是很是簡單的,可是若是數據發生變化,咱們必需要手動調整DOM的變化。

很是的不方便,尤爲是系統很大的時候,不方便。

此時MVVM模式,就能簡化這些操做:數據一變化,DOM自動變化。

 

除了MVCMVVM模式,還有MVP。統稱MV*模式。

ReactVueAngular中都提供:

1)路由能力、組件的管理能力、組件的嵌套能力、組件的數據傳遞能力;

2)數據變化視圖自動變化。


2.3 Vue的虛擬DOM

Virtual DOM是什麼呢?

Vue.js(2.0版本)React的其中最大一個類似之處,就是他們都使用了一種叫’Virtual DOM’的東西。所謂的Virtual DOM基本上說就是它名字的意思:虛擬DOMDOM樹的虛擬表現。它的誕生是基於這麼一個概念:改變真實的DOM狀態遠比改變一個JavaScript對象的花銷要大得多。

Virtual DOM是一個映射真實DOMJavaScript對象,若是須要改變任何元素的狀態,那麼是先在Virtual DOM上進行改變,而不是直接改變真實的DOM。當有變化產生時,一個新的Virtual DOM對象會被建立並計算新舊Virtual DOM之間的差異。以後這些差異會應用在真實的DOM上。


2.4src引包體驗Vue魅力

src引入vue.js(如今不是webpack進行CMD規範的構建)來快速認知。

https://vuejs.org/js/vue.js

 

經過vuejs的包學習基礎語法,而後再用webpack

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{a}}</h1>
    </div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
     //Vue全部的組件都是內部建立的,這裏是惟一一次new Vue()
     //無論項目有多大,組件有多少個,必定只有一個new Vue()。
     //這是一個實例
     new Vue({ el:"#app", //掛載點
 data:{ a : 100 } }) </script>
</html>

首先認知一個事情:VueReact的區別,Vue在寫實例,React在寫類。

MVVM框架:一切的視圖都是和數據相關聯,數據變化,視圖就自動變化。


2.5 Vue視圖更新原理

<body>
    <div id="app">
        <h1>{{a}}</h1>
        <button v-on:click="add"></button>
        <button v-on:click="minus"></button>
    </div>
</body>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
     //Vue全部的組件都是內部建立的,這裏是惟一一次new Vue()
     //無論項目有多大,組件有多少個,必定只有一個new Vue()。
     //這是一個實例
     new Vue({
        el:"#app", //掛載點
        data:{
            a : 100
        },
        methods:{
            add(){
                this.a++
            },
            minus(){
                this.a--
            }
        }
     })
</script>

如今數據變化了,視圖就自動變化,這是MVVM框架的最大特色。

由於Vue作數據和視圖相關變化,原理是「數據劫持」。Object.defineProperties()。定義Vue中組件對象data中的全部變量的setter,讓他們在被設置的時候,刷新相關視圖。

<body>
    <button>按我</button>
</body>
<script type="text/javascript">
     var obj = { //只要這個對象被賦值,立馬觸發set函數
        a : 100
     }

     Object.defineProperties(obj, {
        a : {
            set:function(){
                alert("你在修改a"); //監聽這個屬性被從新賦值
            },
            get:function(){
                alert("你在讀取a");
            }
        }
     })

     document.getElementsByTagName("button")[0].onclick = function(){
        obj.a++; //obj.a的值變化Object.defineProperties()函數的set和get就能攔截到
     }
</script>
示例代碼

3、配置webpack和安裝vue

3.1配置webpack

Vue 提供了一個官方的 CLI,能夠瞬間建立一個項目,可是初學者別用cli起步,先本身手動配置。

webpack中文網:https://doc.webpack-china.org/configuration/

VueReact都是CMD架構(importexport),但目前全部瀏覽器都不支持CMD規範

因此如今VueReact的項目都用webpack打包。用webpack打包只是暫時的,也許在幾年內前端就不用webpack了。

 

第一步:先建立項目文件夾,配置webpackCMD規範,建立package.json文件

安裝webpack
npm install -g webpack@4.9.1

webpack4.0以上版本都要安裝webpack-cli依賴
npm install -g webpack-cli

安裝 webpack-dev-server,這是一個前端的模擬小服務器,寫不了接口,可是能靜態化文件夾。
npm install -g webpack-dev-server

配置webpack.config.js文件(複製官網的配置)

 

webpack 4.0以上版本必須增長mode屬性,它有兩個值:

production (上線版)

development (開發版)

 

開發時,設置mode屬性爲development,要否則就混淆加密打包很慢。

const path = require('path');

module.exports = {
     //程序的入口文件
     entry: "./www/app/app.js",

     //程序的出口(打包的文件)
     output : {
        //打包文件輸出的路徑
        path : path.resolve(__dirname, "www/dist"),
        //打包文件的名稱
        filename : "all.js",
        publicPath:"/public/" //這是對webpack-dev-server的配置,配置虛擬路徑
     },
     //讓webpack監聽變化,自動打包
     watch : true,
 mode : "development",
     //配置webpack的模塊插件
     module:{
        //關於模塊的配置規則
        rules : [{
            //模塊規則(配置 loader、解析器等選項)
            test : /\.js$/,  //解析的時候匹配到的都是js文件
            include: [
              path.resolve(__dirname, "www/app")    //翻譯什麼文件夾
            ],
            exclude: [
              path.resolve(__dirname, "node_modules") //不翻譯什麼文件夾
            ],
            // loader : "babel-loader",
            // options : {
            //     presets : ["es2015","es2016"]
            // }
        }]
     }
}

publicPathwebpack-dev-server在內存中生成的臨時文件夾(項目中物理磁盤上沒有這個文件夾),而且把/public/all.js文件路由到了打包的文件,是爲了編譯速度更快,還能保護硬盤,同時webpack-dev-server提供了前端服務器,端口自定義。

 

而後啓動項目:

webpack-dev-server --content-base ./www --port 8080

--content-base表示以www文件夾做爲一個靜態化根目錄

--port 表示端口號

 

以上啓動命令很繁瑣,咱們能夠在package.json中,配置一個快速啓動命令:

{
  "name": "vue_study",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev" : "webpack-dev-server --content-base ./www --port 8080"
  },
  "author": "",
  "license": "ISC"
}

 

之後項目直接能夠用如下命令啓動:

npm run dev

 

之後項目打開http://127.0.0.1:8080,不要直接雙擊index.html頁面了。

webpack-dev-server在作了兩件事:

1) 在打包js文件

2) 靜態化www文件夾,說白了就是幫我寫了一個app.use(express.static('www'))

 

index.html文件,要改變scriptsrc引用:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>

</body>
<script type="text/javascript" src="public/all.js"></script>
</html>


3.2安裝配置Vue

接下來,配置Vue,只須要5個依賴就能起步:

vuevue-loader(安裝Vue時會提醒你安裝css-loadervue-template-compiler

npm install --save vue

 

安裝其它4個開發依賴:

npm install --save-dev vue-loader
npm install --save-dev css-loader
npm install --save-dev vue-style-loader
npm install --save-dev vue-template-compiler

注意:什麼是loader

webpack在打包的時候,順便作的事情,就是loader

 

5個依賴的做用:

 vue 核心(語法)

 css-loader webpack能識別樣式表,打包樣式表到index頁面中

 vue-style-loader 識別內嵌樣式表

 vue-loader 識別.vue組件文件的

 vue-template-compiler 識別<template></template>

 

babel-loader是翻譯ES6語法的,無需安裝,由於vue-loader中含有babel-loader

補充webpackvue配置:

配置webpack.config.js,這裏手冊很坑,是兩個地方告訴你怎麼配置resolvemodule兩個屬性。

resolve屬性:https://cn.vuejs.org/v2/guide/installation.html

module屬性:https://vue-loader-v14.vuejs.org/zh-cn/options.html#loaders

 

var path = require('path');
const {VueLoaderPlugin} =  require("vue-loader"); //最新版webpack須要引入此插件

module.exports = {
    //程序的入口文件
    entry: './www/app/main.js',
    //程序的出口文件(被打包的文件)
    output: {
        //打包文件輸出的路徑
        path: path.resolve(__dirname, './www/dist'),
        //打包文件的名稱
        filename: 'all.js',
        //這是對webpack-dev-server的配置,是一個虛擬路徑
        // publicPath:"public" //這是對webpack-dev-server的配置,配置虛擬路徑
    },
    //自動監聽
    watch:true,
    mode : "development",
    //配置webpack的模塊插件
    module:{
        // 關於模塊配置
        rules: [
            // 模塊規則(配置 loader、解析器等選項)
            {
                test: /\.js?$/,  //解析的時候匹配到的都是js文件
                include: [path.resolve(__dirname, "www/app")], //翻譯什麼文件夾中的文件
                exclude: [path.resolve(__dirname, "node_modules")], //不翻譯什麼文件夾
                // loader: "babel-loader",
                // //翻譯字典
                // options: {
                //   presets: ["es2015","es2016"]
                // }
            },
            { test: /\.vue?$/,  //解析的時候匹配到的都是js文件
                include: [path.resolve(__dirname, "www/app")], //翻譯什麼文件夾中的文件
                exclude: [path.resolve(__dirname, "node_modules")], //不翻譯什麼文件夾
                loader: "vue-loader"
            },
            {
                test: /\.css?$/,  //解析的時候匹配到的都是js文件
                include: [path.resolve(__dirname, "www/app")], //翻譯什麼文件夾中的文件
                exclude: [path.resolve(__dirname, "node_modules")], //不翻譯什麼文件夾
                use: ["vue-style-loader","css-loader"] }
        ]
    },
    resolve: { alias: { //配置別名
          'vue$': 'vue/dist/vue.esm.js' // 用 webpack 1 時需用 'vue/dist/vue.common.js'
        }
    },
    //最新版webpack須要引入此插件
    plugins:[
        new VueLoaderPlugin() ]
};

 藍色部分是配置loader必須的語法,全部以.vue結尾的文件都是vue-loader處理

 紅色是vue必須的配置

 

main.js文件寫vuehello world

import Vue from "vue";

new Vue({
    el:"#app",
    data:{
        a:100
    }
});
示例代碼

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>{{a}}</h1>
    </div>
</body>
<script type="text/javascript" src="dist/all.js"></script>
</html>
示例代碼

 

 

重啓webpack能看看見100,說明配置成功了。


4、Vue指令

下面正式學習vue,先從指令開始學起。官網指令API地址:https://cn.vuejs.org/v2/api/

Vue中全部的指令都是v-開頭的。

指令系統的原理就是正則表達式,全部的指令的值都是引號包裹(引號是正則表達式工做的定界符),正則表達式會進行提取,而後執行。因此不要認爲引號中的值是字符串,裏面的內容是「活」的。

 

4.1模板插值

4.1.1 v-text模板插值

{{}}v-text指令是徹底等價的。

 

 

index.html

<div id="app">
    <h1 v-text="a"></h1>
    <h1>{{a}}</h1>
    <h1>{{100 * 100}}</h1>
    <h1>{{parseInt(Math.random() * 100)}}</h1>
    <h1>{{arr.reduce((a,b)=> a+b)}}</h1>
    <h1>{{ 3 > 8 ? 5 : 10000 }}</h1>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        a : 100,
        arr : [100,200,300]
    }
})

重點注意:

{{}}中只能寫表達式,不能寫語句。

什麼是表達式,調用函數時,能夠稱爲實參的東西,就是表達式。

 

{{}}中可以寫:

 簡單運算

 函數的調用

 三元運算符

 filtermapreduce等函數

 Math對象、Date對象、Number()構造函數

 

不能寫:

 for()語句

 if語句


4.1.2 v-html

v-text不能識別DOM元素,只能用v-html

index.html

<div id="app">
    <h1 v-html="a"></h1>
    <h1 v-html="b"></h1>
</div>

 

main.js

import Vue from 'vue';

new Vue({
    el : "#app",
    data : {
        a : '<h1 style="color:red;">哈哈</h1>',
        b : '<input type="text" />'
    }
})

data中的數據,進行html轉換,樣式寫在行內。


4.2 v-on事件指令

4.2.1鼠標事件

表示添加事件監聽,v-on叫指令 :click叫參數。「v-on:」能夠簡寫爲「@

<div id="app">
    <h1>{{a}}</h1>
    <button @click='add'>按我+</button>
    <button v-on:click='add'>按我+</button>
    <button v-on:mouseenter='add'>觸摸+</button>
    <button v-on:dblclick='jian'>雙擊-</button>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
       a : 100
    },
    methods : {
        add(){ this.a++ },
        jian(){ this.a-- }
    }
})
<button v-on:click.once='add'>只觸發一次+</button>


4.2.2鍵盤事件

index.html

<div id="app">
    <input type="text" v-on:keydown.13='tijiao($event)'>
    <input type="text" v-on:keyup.enter='haha'>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {

    },
    methods : {
        tijiao(e){ console.log(e.target.value) }, haha(){ alert("回車鍵鬆開了") }
    }
})

當按下回車鍵的時候,觸發methods的方法,監聽鍵盤按鍵時,修飾符是13(表示回車鍵)

若是須要用event事件對象,傳入$event便可。

 

內置按鍵修飾符有不少

https://cn.vuejs.org/v2/guide/events.html

 


4.3 v-bind動態指令

v-bind能夠將值變成「動態」的

v-bind:什麼屬性均可以,而且「v-bind:」能夠簡寫成「:

 

好比:

v-bind:value
v-bind:style
v-bind:class
v-bind:name
v-bind:alt
v-bind:disable
v-bind:title
v-bind:src

4.3.1 v-bind:class對象語法

index.html

<head>
    <style type="text/css">
        .cur{color:red;}
        .bgcur{background:pink;}
    </style>
</head>
<body>
<div id="app">
    <h1 v-bind:class="{cur:true, bgcur:true}">哈哈</h1>
        <h1 v-bind:class="{cur:isClass, bgcur:isBgClass}">哈哈</h1>
        <button @click="changeClass">按我切換</button>
    </div>
</body>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        isClass:true,
        isBgClass:true
    },
    methods : {
        changeClass(){ this.isClass = !this.isClass;
            this.isBgClass = !this.isBgClass; }
    }
})


4.3.2 v-bind:class數組語法

index.html

<div id="app">
<h1 v-bind:class="['cur', 'bgcur']">哈哈</h1>
    <h1 v-bind:class="[isClass,isBgClass]">哈哈</h1>
    <button @click="changeClass">按我切換</button>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        isClass:'cur',  //類名
        isBgClass:'bgcur'  //類名
    },
    methods : {
        changeClass(){ this.isClass = !this.isClass;
            this.isBgClass = !this.isBgClass; }
    }
})

4.3.3 v-bind:style對象語法

注意:這些值須要用引號包裹,不然會認爲它是一個函數:

 

index.html

<div id="app">
    <h1 v-bind:style="{background:'red'}">哈哈</h1>
    <h1 :style="{background:'red'}">哈哈</h1>
    <h1 :style="{background:`rgb(${r}, ${g}, ${b})`}">哈哈</h1>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        r : 100,
         g : 200,
         b : 255
    }
})


4.3.4 v-bind:style數組語法

index.html

<div id="app">
<h1 :style="[{'background':'red', 'fontSize':'50px'}]">哈哈</h1>
    <h1 :style="[obj]">哈哈</h1>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        obj : { 'background':'red',
            'fontSize':'50px' }
    }
})

4.3.5 v-bind:其餘屬性

index.html

<div id="app">
    <img :src="url" >
    <a :href="link">百度</a>
    <button :disabled="b">按鈕</button>
    <input type="text" :value="a">
    <input type="text" :placeholder="a">
    <div :style="yangshi"></div>
    <h1 :class="leiming">文字</h1>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : { a : 100,
        b : "disabled",
        url : "images/baby1.jpg",
        link: "http://www.iqianduan.cn",
        yangshi : {
            "background": 'orange',
            "width":'100px',
            "height":'100px',
        },
        leiming : {
            "da" : true,
            "xie" : false,
            "hong" : true } }
})

4.4 v-ifv-else上下樹

v-if是控制DOM上下樹的,v-iftrue則上樹,false則下樹。

v-else必須緊跟着v-if,中間不能有任何間隔,不然報錯,若是有間隔可使用兩個v-if讓他們互反。

 

index.html

<div id="app">
    <h1 v-if="isShow">若是</h1>
    <h2 v-else="isShow">不然</h2>
    <button @click="showClick">按我</button>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
      isShow:true
    },
    methods : {
        showClick(){ this.isShow = !this.isShow; }
    }
})

 

v-ifv-else有間隔就報錯:

 

解決方法:用兩個if

<h1 v-if="isShow">若是</h1>
<h2 v-if="!isShow">不然</h2>
<button @click="showClick">按我</button>

4.5 v-show顯示/隱藏

v-show是控制DOM的隱藏和顯示,原理是CSSdisplay:noneblock

index.html

<div id="app">
    <h1 v-show="isShow">哈哈</h1>
    <h1 v-show="!isShow">嘿嘿</h1>
    <button @click="showClick">{{isShow ? "按我消失" : "按我顯示"}}</button>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el: "#app",
    data: {
        isShow : true
    },
    methods:{
        showClick(){ this.isShow = !this.isShow }
    }
})

通常來講,v-if有更高的切換開銷,而v-show有更高的初始渲染開銷。

所以,若是須要很是頻繁的切換,使用v-show較好,若是在運行時條件不多改變,則使用v-if較好。


4.6 v-for循環指令

用來循環某一個元素,數據必須是數組或類數組對象,使用ofin關鍵字。

4.6.1循環數組

index.html

<div id="app">
    <ul>
        <li v-for="item in arr" :key="item">{{item}}</li>
    </ul>
    <ul>
        <li v-for="(item,index) in arr" :key="item">{{item}} {{index}}</li>
    </ul>
    <table>
       <tr v-for="(item,index) in students" :key="item.id">
           <td>{{item.id}}</td>
           <td>{{item.name}}</td>
           <td>{{item.age}}</td>
       </tr>
    </table>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        arr : ["蘋果","鴨梨","桃子","西瓜"],
        students : [
            {"id":1001, "name":"小明", "age" :12},
            {"id":1002, "name":"小紅", "age" :13},
            {"id":1003, "name":"小剛", "age" :14}
        ]
    }
})
示例代碼

 

index的下標是從0開始


4.6.2循環對象

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
         obj : {"name":"小明","sex":"男","age":12}
    }
})

 

index.html

<div id="app">
     <ul>
         <li v-for="(item,key,index) in obj" :key="index">
             {{index}}
             {{key}}
             {{item}}
         </li>
     </ul>
</div>


4.6.3循環常數

index.html

<div id="app">
     <ul>
         <li v-for="(item,index) in 10">
            {{item}} {{index}}
         </li>
     </ul>
</div>

循環常數,item是從1開始迭代,index是從0開始。

https://cn.vuejs.org/v2/guide/list.html#key


九九乘法表:

<div id="app">
     <table border="1">
        <tr v-for="i in 9">
            <td v-for="j in 9" v-show="i >= j">
                {{i}} * {{j}} = {{i * j}}
            </td>
        </tr>
     </table>
</div>

這些數組方法會從新出發v-for視圖更新渲染:

index.html

<div id="app">
     <input type="text" @keyup.enter="tijiao" v-model="txt">
     <ul>
         <li v-for="item in arr">{{item.title}}</li>
     </ul>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
        arr : [], txt : ''
    },
    methods :{
        tijiao(){
            this.arr.push({"title" : this.txt}) //把輸入的內容插入到數組,會從新渲染視圖
            this.txt = ''
        }
    }
})


4.7 v-model雙向數據綁定

雙向數據綁定借鑑了Angular。全部表單元素(單選、文本框、複選)等都能用v-model雙向和data綁定!

v-model幫表單元素在內部作了兩個事情:

1)添加了監聽

2)添加了value

受控就是雙向綁定:控件從data要值,控件要變化,就改變data的值

React中作表單控件的受控,要寫value={}onChange={};

可是在vue中,只需使用v-model將實現快速的數據雙向綁定。

https://cn.vuejs.org/v2/guide/forms.html

 


4.7.1 input的雙向數據綁定

index.html

<body>
    <div id="app">
        <h3>{{a}}</h3>
        <input type="text" v-model="a">

        <p>
            <input type="radio" name="sex" v-model="b" value="男"><input type="radio" name="sex" v-model="b" value="女"></p>
        <p>你的性別是:{{b}}</p>

        <p>
            <input type="checkbox" v-model="c" value="看書">看書
            <input type="checkbox" v-model="c" value="打球">打球
            <input type="checkbox" v-model="c" value="吃飯">吃飯
        </p>
        <p>你的愛好是:{{c}}</p>

        <p><input type="range" max="100" v-model="d"></p>
        <p>你的音量是:{{d}}</p>
    </div>
</body>
示例代碼

main.js

import Vue from "vue";

new Vue({
    el:"#app",
    data:{
         a:"請輸入內容",
         b:"男",
         c:["打球","看書"],
         d:30
    }
})
實例代碼


4.7.2 input-number

index.html

<div id="app">
    <h1>{{num}}</h1>
    <h1>{{typeof num}}</h1>
    <input type="number" v-model.number="num">
    <h1>{{txt}}</h1>
    <input type="text" v-model.trim='txt'>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
         num : 0,
         txt : ''
    }
})

默認類型:

 

 

輸入內容修改後類型:

 

 

 

v-model添加修飾符限制類型:

<input type="number" v-model.number="num">

 

input添加.trim修飾符,能過濾首位的空格,中間的不行。

<input type="text" v-model.trim="num">

change」時而非「input」時觸發:

<input v-model.lazy="txt" >

4.7.3 textarea

微博發佈框:文本輸入框若是超出140字時,動態添加一些類和屬性,字體變紅,按鈕不可點擊。

index.html

<style type="text/css">
    .danger{color:red;}
</style>
<div id="app">
    <textarea cols="30" rows="10" v-model='txt'></textarea>
    <span :class="{danger: txt.length > 140}">當前共{{txt.length}}字/140字</span>
<button :disabled="txt.length == 0 || txt.length > 140">發佈</button>
<button :disabled="txt.length == 0" @click="clear">清空</button>
</div>

 

main.js

import Vue from 'vue';
new Vue({
    el: "#app",
    data: {
        txt:""
},
methods : {
    clear(){
        this.txt= ""
    }
}
})

4.7.4雙向數據綁定-受控的列

index.html

<div id="app">
    <div>
        <label><input type="checkbox" value="id" v-model="showCols">學號</label>
        <label><input type="checkbox" value="name" v-model="showCols">姓名</label>
        <label><input type="checkbox" value="sex" v-model="showCols">性別</label>
        <label><input type="checkbox" value="age" v-model="showCols">年齡</label>
    </div>
    <table>
       <tr>
           <th v-show="showCols.includes('id')">學號</th>
           <th v-show="showCols.includes('name')">姓名</th>
           <th v-show="showCols.includes('sex')">性別</th>
           <th v-show="showCols.includes('age')">年齡</th>
       </tr>
       <tr v-for="item in arr">
           <td v-show="showCols.includes('id')">{{item.id}}</td>
           <td v-show="showCols.includes('name')">{{item.name}}</td>
           <td v-show="showCols.includes('sex')">{{item.sex}}</td>
           <td v-show="showCols.includes('age')">{{item.age}}</td>
       </tr>
    </table>
</div>
示例代碼

main.js

import Vue from 'vue';
new Vue({
    el : "#app",
    data : {
         showCols : ['id', 'name', 'sex', 'age'],
         arr : [
            {"id":1001, "name":"小明","sex":"男","age":12},
            {"id":1002, "name":"小紅","sex":"女","age":13},
            {"id":1003, "name":"小花","sex":"女","age":14},
            {"id":1004, "name":"小剛","sex":"男","age":15},
            {"id":1005, "name":"小黑","sex":"男","age":16}
         ]
    }
})
示例代碼
相關文章
相關標籤/搜索