【轉】 前端筆記之Vue(一)初識SPA和Vue&webpack配置和vue安裝&指令
【轉】 前端筆記之Vue(一)初識SPA和Vue&webpack配置和vue安裝&指令
一、單頁面應用(SPA)
1.1 C/S到B/S頁面架構的轉變
C/S:客戶端/伺服器(Client/Server)架構的軟體。
C/S 軟體的特點:
① 從window桌面雙擊開啟
② 更新的時候會替換原有的,原有的必須刪除,不能重新整理。
③ 在其他的裝置上使用的時候,也要安裝軟體。
B/S :瀏覽器和伺服器(Browser/Server)架構
B/S 軟體的特點:
不需要安裝任何的客戶端,是通過瀏覽器輸入網址開啟的。
更新的時候不需要重新安裝軟體,你只需要重新整理頁面,程式就能更新。
在其他裝置端,不需要安裝任何其他的軟體,瀏覽器足可以解決所有的問題。
Dashboard叫做儀表盤專案,通俗的講就是***管理平臺。比如進銷存管理平臺、汽車銷售管理平臺、寵物店管理平臺。
特點1:這種專案幾乎都是單頁面應用(Single Page Application)簡稱SPA
將原來PC桌面的應用程式,放到瀏覽器中實現。現在的用人需求很大,不管是政府機構、教育機構、外包機構、銷售機構都在開發自己的新專案,或者把老專案搬到網頁上。比如阿里雲的管理平臺,特別像桌面的app,現在是在瀏覽器中實現的。
所有頁面的URL網址,只有#後面的內容在變化,而#之前的內容沒有變化,整個專案就是一個html頁面。
網頁沒有發生跳轉,而是
頁面的URL沒有變化,變化的只是hash符號後面的部分:
特點2:都是元件化的
兩個不同的頁面中(實際上是一個頁面),都有日期選擇框,發現日期選擇框都是相同的,我們叫做“元件(components)”。
也就是說,這些日曆元件,不管是HTML、CSS、JavaScript都能複用。
下圖中的每一個紅框都可以認為是元件:
特點3:所有的DOM元素都是動態上下樹的
檢視頁面原始碼,發現頁面上的所有DOM結構都不在原始碼中,也就是說DOM結構是JavaScript程式控制上樹的,所有的部件,都是元件、元件巢狀元件、集體被JavaScript上樹。
總結,一個好的單頁面應用的框架,必須要能提供:
l優秀的路由機制,能捕獲使用者URL中hash部分,決定什麼元件顯示和隱藏;
l用JavaScript控制組件動態上樹、下樹的能力;
l元件的建立、複用、巢狀能力;
l元件的資料傳遞的能力。
1.2三大框架的出現
Angular、React、Vue都是做什麼的?
它們都是JS架構,都是用來做單頁面應用設計的。
Angular
AngularJS誕生於2009年,由Misko Hevery 等人建立,後為Google所收購。是一款優秀的前端JS框架,已經被用於Google的多款產品當中。Angular是第一個實現“資料變化,檢視自動變化”的框架,並且首創了元件化開發模式。Angular有著諸多特性,最為核心的是:MVC、模組化、自動化雙向資料繫結、語義化標籤、依賴注入、服務、控制器等等。
Angular的出現,有了前端的元件化。
前端的元件化開發:它是一種易於插拔,模組化的開發形式。HTML、CSS、JS邏輯都封裝到一個元件中,在其他的頁面可以輕鬆地顯示。
Angular是AMD模式,專案需要使用require.js配合,和時代的CMD主流背道而馳,2015年開始落寞了。Angular2016年出了2,2017年出了4、5,都是CMD模式的,但是使用者已經不買賬了。
React
React 起源於 Facebook 的內部專案,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意。就決定自己寫一套,用來架設Instagram 的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。
React主要用於構建UI。你可以在React裡傳遞多種型別的引數,如宣告程式碼,幫助你渲染出UI、也可以是靜態的HTML DOM元素、也可以傳遞動態變數、甚至是可互動的應用元件。
React非常輕,只提供了少量了API,和相關的元件。
React可以Redux、Flux等框架配合使用。
React 使用 Virtual DOM技術,使他渲染更快速,記憶體開銷小。
React是CMD模式的,並且創造性的和webpack進行合作,將所有的js程式碼實時構建為一個js檔案,程式設計的時候非常的清爽,非常利於團隊合作,所以大量的使用者就開始使用React開發自己的專案。
Vue
Vue是中國人尤雨溪發明的,它的資料驅動檢視的實現是最優雅的。它是一個集大成者,集成了Angular和React的優點,摒棄了它們的缺點。是一個構建資料驅動的 web 介面的漸進式框架。Vue.js 的目標是通過儘可能簡單的 API 實現響應的資料繫結和組合的檢視元件。它不僅易於上手,還便於與第三方庫或既有專案整合。
Vue的作者,發現了JS的一個神奇之處,Object.defineProperty的作用,可以用於檢視的更新。
AngularJS實現的機理是髒檢查。
React是setState()。
二、Vue介紹
2.1官網和作者
Vue是一門mvvm的框架,繼承了Angular的雙向資料繫結和指令的優點,繼承了React的快速製作元件的能力,同時也擁有非常類似與Redux的單向資料流動的思想,最主要Vue的api都是中文的,非常好學。
2.2 Vue是一門mvvm框架
MVVM框架:一切的檢視都是和資料相關聯的。資料變化了,檢視就自動變化。而不需要控制器去命令模組做什麼然後渲染什麼檢視。
React、Vue、Angular都是簡化了模組化開發,這些MVVM框架到底簡化了什麼:
1)元件方便建立了(建立一個元件只需要寫一個類或者一個函式)
2)元件的可插拔性高
3)元件的資料傳輸簡單了
4)路由,單頁面應用的hash路由
5)只關心資料,不關心DOM
資料叫做model(模型),因為對資料的所有操作都是模型的任務;檢視叫做view。在MVVM中出現了view-model這個層,它可以“監聽”model 的任何改變,讓檢視自動變化。從而我們不需要關心DOM操作,只需要關心資料的變化即可。
React、Vue、Angular中都提供了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自動變化。
除了MVC、MVVM模式,還有MVP。統稱MV*模式。
React、Vue、Angular中都提供:
1)路由能力、元件的管理能力、元件的巢狀能力、元件的資料傳遞能力;
2)資料變化檢視自動變化。
2.3 Vue的虛擬DOM
Virtual DOM是什麼呢?
Vue.js(2.0版本)與React的其中最大一個相似之處,就是他們都使用了一種叫’Virtual DOM’的東西。所謂的Virtual DOM基本上說就是它名字的意思:虛擬DOM,DOM樹的虛擬表現。它的誕生是基於這麼一個概念:改變真實的DOM狀態遠比改變一個JavaScript物件的花銷要大得多。
Virtual DOM是一個對映真實DOM的JavaScript物件,如果需要改變任何元素的狀態,那麼是先在Virtual DOM上進行改變,而不是直接改變真實的DOM。當有變化產生時,一個新的Virtual DOM物件會被建立並計算新舊Virtual DOM之間的差別。之後這些差別會應用在真實的DOM上。
2.4用src引包體驗Vue魅力
src引入vue.js(現在不是webpack進行CMD規範的構建)來快速認知。
通過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>
首先認知一個事情:Vue和React的區別,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>示例程式碼
三、配置webpack和安裝vue
3.1配置webpack
Vue 提供了一個官方的 CLI,可以瞬間建立一個專案,但是初學者別用cli起步,先自己手動配置。
webpack中文網:https://doc.webpack-china.org/configuration/
Vue和React都是CMD架構(import和export),但目前所有瀏覽器都不支援CMD規範
所以現在Vue和React的專案都用webpack打包。用webpack打包只是暫時的,也許在幾年內前端就不用webpack了。
第一步:先建立專案資料夾,配置webpack的CMD規範,建立package.json檔案
安裝webpack
npm install -g [email protected]
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屬性,它有兩個值:
lproduction (上線版)
ldevelopment (開發版)
開發時,設定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"] // } }] } }
publicPath是webpack-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檔案,要改變script的src引用:
<!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個依賴就能起步:
vue、vue-loader(安裝Vue時會提醒你安裝css-loader、vue-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
補充webpack的vue配置:
配置webpack.config.js,這裡手冊很坑,是兩個地方告訴你怎麼配置resolve和module兩個屬性。
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檔案寫vue的hello 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,說明配置成功了。
四、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] } })
重點注意:
{{}}中只能寫表示式,不能寫語句。
什麼是表示式,呼叫函式時,可以稱為實參的東西,就是表示式。
{{}}中能夠寫:
簡單運算
函式的呼叫
三元運算子
filter、map、reduce等函式
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-if和v-else上下樹
v-if是控制DOM上下樹的,v-if為true則上樹,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-if和v-else有間隔就報錯:
解決方法:用兩個if
<h1 v-if="isShow">如果</h1> <h2 v-if="!isShow">否則</h2> <button @click="showClick">按我</button>
4.5 v-show顯示/隱藏
v-show是控制DOM的隱藏和顯示,原理是CSS的display:none和block
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迴圈指令
用來迴圈某一個元素,資料必須是陣列或類陣列物件,使用of或in關鍵字。
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值
l受控就是雙向繫結:控制元件從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} ] } })示例程式碼