VUE基礎

李莲花發表於2024-08-17

1.VUE簡介
它是一個構建使用者介面的框架 Vue是一個前端框架 js jq
Vue (發音為 /vjuː/,類似 view) 是一款用於構建使用者介面的 JavaScript 框架。它基於標準 HTML、CSS 和 JavaScript 構建,並提供了一套宣告式的、元件化的程式設計模型,幫助你高效地開發使用者介面。無論是簡單還是複雜的介面,Vue 都可以勝任

1.1 介紹與描述
宣告式渲染:Vue 基於標準 HTML 擴充了一套模板語法,使得我們可以宣告式地描述最終輸出的 HTML 和 JavaScript 狀態之間的關係。
響應性:Vue 自動跟蹤 JavaScript狀態並在其發生變化時響應式地更新 DOM。
漸進式框架:Vue 是一個框架,也是一個生態。其功能覆蓋了大部分前端開發常見的需求。

1.2 Vue 的特點

  1. 遵循 MVVM 模式
  2. 編碼簡潔, 體積小, 執行效率高, 適合移動/PC 端開發3. 它本身只關注UI, 也可以引入其它第三方庫開發專案

1.3 與其它 JS 框架的關聯

  1. 借鑑 Angular 的模板和資料繫結技術
  2. 借鑑 React 的元件化和虛擬 DOM 技術

1.4 Vue 周邊庫

  1. vue-cli: vue 腳手架
  2. vue-resource
  3. axios :非同步
  4. vue-router: 路由
  5. vuex: 狀態管理
  6. element-ui: 基於 vue 的 UI 元件庫(PC 端)
    ……
  1. MVVM的思想
    2.1 MVVM 設計思想

MVC
|--M Model (domain,service,serviceimpl.utils.pojo.mapper)
|--V view thymeleaf jsp html ${user}
|--C controller 接收前端請求(控制器)

Model:對應資料層的域模型,它主要做域模型的同步。透過 Ajax/fetch 等 API 完成客戶端和服務端業務 Model 的同步。在模型層間關係裡,它主要用於抽象出 ViewModel 中檢視的 Model。個人理解:後端提供API,後端服務架構是 控制器+資料模型 或者 純控制器。
View:View是作為檢視模板,用於定義結構、佈局。它自己不處理資料,只是將ViewModel中的資料展現出來。此外為了和ViewModel產生關聯,那麼還需要做的就是資料繫結的宣告,指令的宣告,事件繫結的宣告。ViewModel和View之間是雙向繫結,意思就是說ViewModel的變化能夠反映到View中,View的變化也能夠改變ViewModel的資料值。
ViewModel:ViewModel起著連線View和Model的作用,同時用於處理View中的邏輯。在MVC框架中,檢視模型透過呼叫模型中的方法與模型進行互動,然而在MVVM中View和Model並沒有直接的關係,在MVVM中,ViewModel從Model獲取資料,然後應用到View中。個人理解:Web前端的webserver對View進行雙向繫結渲染。
整個MVVM實際上實現了前後端分離,透過api來實現前後端互動,前端透過純js或者雙向繫結框架來渲染頁面。
前後端不分離(car 頁面寫在car專案裡面 html thymeleaf(模板引擎) )
前後端分離

大概如:
資料庫(MySQL、PostgreSQL)<—雙向互動—>api(php、java、Python、node)<—雙向互動—>ajax/fetch/websocket(node服務、jQ、js)<—雙向繫結—>html(標籤、css)。
MVVM有利於專案分工和升級,所謂對前後端分離。但也有缺點,就是不利於SEO 。
也就是搜尋引擎最佳化的邏輯,簡單說就是內部最佳化和外部最佳化困難 。
MVC:服務端來渲染資料,老舊模式。MC屬於純後端,V屬於前端,js權重不高,有利於SEO。
萬物基於api,一套api可以針對小程式、app、前端,為何不首先使用。需要SEO對部分,單獨分離出專案,採用MVC渲染靜態頁面或者純html即可。
2.2 MVVM圖例解析

  1. 安裝和部署
    IDEA中直接使用外掛 vue 下載即可
    讓Idea識別vue語法

3.1 直接下載並用<script> 標籤引入
Vue 會被註冊為一個全域性變數。
在開發環境下不要使用壓縮版本,不然你就失去了所有常見錯誤相關的警告!
開發版本包含完整的警告和除錯模式
https://cn.vuejs.org/v2/guide/installation.html

3.2 CDN
對於製作原型或學習,你可以這樣使用最新版本:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
對於生產環境,我們推薦連結到一個明確的版本號和構建檔案,以避免新版本造成的不可預期的破壞:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
3.3 NPM(後面講)
在用 Vue 構建大型應用時推薦使用 NPM 安裝[1]。NPM 能很好地和諸如 webpack 或 Browserify 模組打包器配合使用。同時 Vue 也提供配套工具來開發單檔案元件。

# 最新穩定版
$ npm install vue

3.4 瀏覽器安裝開發者工具
Chrome瀏覽器安裝Vue.js devtools外掛
注意:Chrome瀏覽器版本過低需要找低版本的crx檔案
1、瀏覽器訪問極簡外掛
https://chrome.zzzmh.cn/#/index

2、右上角搜尋框搜尋vue DevTools外掛

3、在本地資料夾中解壓剛剛下載的外掛,解壓後如下所示

4、開啟谷歌瀏覽器--更多工具--擴充程式
注意:開啟開發者模式

5、將解壓的資料夾拉到4中擴充程式頁面

6、安裝成功

  1. VUE的基本格式
<!-- 引入Vue -->
<script type="text/javascript" src="./js/vue.js"></script>
格式:
new Vue({
Key:value,
Key:value,
Key:value,
...
Key:value
})
key是固定值:el,data,methods...我們會逐個介紹

5.Vue的基本語法
Vue.js 使用了基於 HTML 的模板語法,允許開發者宣告式地將 DOM 繫結至底層 Vue 例項的資料。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循規範的瀏覽器和 HTML 解析器解析。
在底層的實現上,Vue 將模板編譯成虛擬 DOM 渲染函式。結合響應系統,Vue 能夠智慧地計算出最少需要重新渲染多少元件,並把 DOM 操作次數減到最少。

5.1 插值語法
格式:{{XXX}}
功能:用於解析標籤體內容。
寫法:xxx是js表示式,且可以直接讀取到data中的所有屬性。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>初識Vue</title>
    <!-- 引入Vue -->
    <script type="text/javascript" src="./js/vue.js"></script>
</head>
<body>
<!-- 準備好一個容器
    root容器裡的程式碼依然符合html規範,只不過混入了一些特殊的Vue語法;
 -->
<div id="demo">
    <h1>Hello,{{name.toUpperCase()}},{{address}}</h1>
</div>
<script type="text/javascript" >
    Vue.config.productionTip = false //阻止 vue 在啟動時生成生產提示。
    /* 想讓Vue工作,就必須建立一個Vue例項,且要傳入一個配置物件;*/
    //建立Vue例項  Vue例項和容器是一一對應的
    new Vue({
        el:'#demo', //el用於指定當前Vue例項為哪個容器服務,值通常為css選擇器字串。
        data:{ //data中用於儲存資料,資料供el所指定的容器去使用,值我們暫時先寫成一個物件。
            name:'dalang',
            address:'北京'
        }
    })
</script>
</body>
</html>

5.2 v-text,v-html,v-pre,v-once指令

<span id=”aaa”></span>
$(“#aaa”).html(‘<font color=red>RED</font>’)
$(“#aaa”).text(‘<font color=red>RED</font>’)

5.2.1 v-text
v-text主要用來更新textContent,可以等同於JS的text屬性。
<span v-text="msg"></span>
這兩者等價:
<span>{{msg}}</span>
5.2.2 v-html
雙大括號的方式會將資料解釋為純文字,而非HTML。為了輸出真正的HTML,可以用v-html指令。它等同於JS的innerHtml屬性。
或者jquery的$().html(aaa)
<div v-html="rawHtml"></div>
這個div的內容將會替換成屬性值rawHtml,直接作為HTML進行渲染。
5.2.3 v-pre
v-pre主要用來跳過這個元素和它的子元素編譯過程。可以用來顯示原始的Mustache標籤。跳過大量沒有指令的節點加快編譯。

<div id="app">
    <span v-pre>{{message}}</span> //這條語句不進行編譯
    <span>{{message}}</span>
</div>

最終僅顯示第二個span的內容
5.2.4 v-once
v-once關聯的例項,只會渲染一次。之後的重新渲染,例項極其所有的子節點將被視為靜態內容跳過,這可以用於最佳化更新效能。

<span v-once>This will never change:{{msg}}</span> //單個元素
<div v-once>//有子元素
    <h1>comment</h1>
    <p>{{msg}}</p>
</div>

上面的例子中,msg即使產生改變,也不會重新渲染。

5.3 資料繫結

1,v-bind 字面意思為繫結。是vue中提供的使用者繫結屬性的指令。
v-bind可簡寫成 :
2,v-model 只能用於表單元素的雙向繫結指令
Vue中有2種資料繫結的方式:
1.單向繫結(v-bind):資料只能從data流向頁面。
2.雙向繫結(v-model):資料不僅能從data流向頁面,還可以從頁面流向data。

備註:

1.雙向繫結一般都應用在表單類元素上(如:input、select等)
2.v-model:value可以簡寫為v-model,v-model預設收集的就是value值。

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <title>資料繫結</title>
      <!-- 引入Vue -->
      <script type="text/javascript" src="./js/vue.js"></script>
   </head>
   <body>
      <!-- 準備好一個容器-->
      <div id="root">
         <!-- 普通寫法 -->
         <!-- 單向資料繫結:<input type="text" v-bind:value="name"><br/>
         雙向資料繫結:<input type="text" v-model:value="name"><br/> -->

         <!-- 簡寫 -->
         單向資料繫結:<input type="text" :value="name"><br/>
         雙向資料繫結:<input type="text" v-model="name"><br/>
         <!-- 如下程式碼是錯誤的,因為v-model只能應用在表單類元素(輸入類元素)上 -->
         <!-- <h2 v-model:x="name">你好啊</h2> -->
      </div>
   </body>
   <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在啟動時生成生產提示。

      new Vue({
         el:'#root',
         data:{
            name:'你好'
         }
      })
   </script>
</html>

5.4 雙向繫結v-model 小練習

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue.js"></script>
</head>

<body>
  <div id ="app">
    <input v-model="number1" />
    <select v-model="opt" >
      <option value="+">+</option>
      <option value="-">-</option>
      <option value="*">*</option>
      <option value="÷">÷</option>
    </select>
    <input v-model="number2"  />
    <button @click="compute">=</button>
    <input v-model="cutNumber"/>
  </div>

  <script>
   //建立Vue例項,得到 ViewModel
   var vm = new Vue({
    el: '#app',
    data: {
      number1:0,
      number2:0,
      opt:'+',
      cutNumber:0
    },
    methods: {
      compute(){
        switch(this.opt){
          case '+':
            this.cutNumber=parseInt(this.number1)+parseInt(this.number2)
            break;
          case '-':
            this.cutNumber=parseInt(this.number1)-parseInt(this.number2)
            break;
          case '*':
            this.cutNumber=parseInt(this.number1)*parseInt(this.number2)
            break;
          case '÷':
            this.cutNumber=parseInt(this.number1)/parseInt(this.number2)
            break;
        }
      }
    }
   });
  </script>
</body>

</html>

5.5 El和data的兩種格式
data與el的2種寫法
> 1.el有2種寫法

  (1).new Vue時候配置el屬性。
  (2).先建立Vue例項,隨後再透過vm.$mount('#root')指定el的值。

2.data有2種寫法
(1).物件式
(2).函式式
如何選擇:目前哪種寫法都可以,
以後學習到元件時,data必須使用函式式,否則會報錯。
3.一個重要的原則:
由Vue管理的函式,一定不要寫箭頭函式,一旦寫了箭頭函式,this就不再是Vue例項了。

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <title>el與data的兩種寫法</title>
      <!-- 引入Vue -->
      <script type="text/javascript" src="./js/vue.js"></script>
   </head>
   <body>
      <!-- 準備好一個容器-->
      <div id="root">
         <h1>你好,{{name}}</h1>
      </div>
   </body>

   <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在啟動時生成生產提示。
      //el的兩種寫法
      /* const v = new Vue({
         //el:'#root', //第一種寫法
         data:{
            name:'世界1'
         }
      })
      console.log(v)
      v.$mount('#root') //第二種寫法 */

      //data的兩種寫法
      new Vue({
         el:'#root',
         //data的第一種寫法:物件式
         /* data:{
            name:'世界'
         } */

         //data的第二種寫法:函式式
         data(){
            console.log('@@@',this) //此處的this是Vue例項物件
            return{
               name:'世界2'
            }
         }
      })
   </script>

5.6 事件繫結
5.6.1 基本使用

在以前的開發中。我們使用onclick等屬性去設定點選事件,在vue 中可以使用v-on去設定方式,可簡寫成@
使用v-on:xxx 或 @xxx 繫結事件,其中xxx是事件名;
事件的回撥需要配置在methods物件中,最終會在vm上

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <title>事件的基本使用</title>
      <!-- 引入Vue -->
      <script type="text/javascript" src="../js/vue.js"></script>
   </head>
   <body>
      <!-- 準備好一個容器-->
      <div id="root">
         <h2>歡迎來到{{name}}</h2>
         <!-- <button v-on:click="showInfo">點我提示資訊</button> -->
         <button @click="showInfo1">點我提示資訊1(不傳參)</button>
         <button @click="showInfo2($event,66)">點我提示資訊2(傳參)</button>
      </div>
   </body>

   <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在啟動時生成生產提示。
      const vm = new Vue({
         el:'#root',
         data:{
            name:'英雄聯盟',
         },
         methods:{
            showInfo1(event){
               // console.log(event.target)
               // console.log(event.target.innerText)
               // console.log(this) //此處的this是vm
               alert('召喚師你好!')
            },
            showInfo2(event,number){
               console.log(event,number)
               // console.log(event.target.innerText)
               // console.log(this) //此處的this是vm
               alert('青銅嘴強王者--你好!!')
            },
           /*show1:()=>{
                alert("show1")
              console.log("show1是被誰呼叫的:",this)//箭頭函式的this指向window
             }*/
         }
      })
   </script>
</html>

注意:methods中配置的函式,不要用箭頭函式!否則this就不是vm了;
@click="demo" 和 @click="demo($event)" 效果一致,但後者可以傳參;
函式的呼叫和$event
事件的方法名不帶圓括號 的形式,event物件將被自動當做實參傳入;
事件的方法名帶圓括號的形式,我們需要把$event變數作為引數,顯式傳入方法中。

<body>
   <div id="app">
      <input type="checkbox"  @click="click" > 方法名稱,不帶括號 <br>
      <input type="checkbox"  @click="click2()" > 方法名稱,後面有括號  <br>
<input type="checkbox"  @click="click4(233)" > clickMe <br>
   </div>
</body>
<script>
   var app = new Vue({
      el: '#app',
      methods: {
         click(event) {
            console.log("方法名稱,不帶括號",event);    // object
         },
         click2(event) {
            console.log("方法名稱,後面有括號",event);    // undefined
         },
click4(val) {
         console.log("傳參沒有傳遞$event",event);    // object
        alert(val)
       }
      }
   });
</script>

$event:傳遞引數使用 傳參時不寫$event可以嗎?
以前不可以!
既沒有傳入實參,也沒有接收的形參,這個 event物件的來源,window.event。
5.6.2 事件修飾符

  1. prevent:阻止預設事件(常用)
    本身含有事件阻止本身事件,觸發vue繫結的事件
    2.stop:阻止事件冒泡(常用)
    當父子元素中都有點選事件的時候,為了讓觸發子元素中的事件時,不去觸 發父元素中的事件,可以在子元素事件中新增stop來阻止事件冒泡;
    3.once:事件只觸發一次(常用);
    4.capture:使用事件的捕獲模式;
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <title>事件修飾符</title>
      <!-- 引入Vue -->
      <script type="text/javascript" src="./js/vue.js"></script>
      <style>
         *{
            margin-top: 20px;
         }
         .demo1{
            height: 50px;
            background-color: skyblue;
         }
         .box1{
            padding: 5px;
            background-color: skyblue;
         }
         .box2{
            padding: 5px;
            background-color: orange;
         }
         .list{
            width: 200px;
            height: 200px;
            background-color: peru;
            overflow: auto;
         }
         li{
            height: 100px;
         }
      </style>
   </head>
   <body>
      <!-- 準備好一個容器-->
      <div id="root">
         <h2>歡迎來到{{name}}</h2>
         <!-- 阻止預設事件(常用) -->
         <a href="http://www.baidu.com" @click.prevent="showInfo">點我提示資訊</a>
         <!-- 阻止事件冒泡(常用) -->
         <div class="demo1" @click="showInfo">
            <button @click.stop="showInfo">點我提示資訊</button>
            <!-- 修飾符可以連續寫 -->
            <!-- <a href="http://www.baidu.com" @click.prevent.stop="showInfo">點我提示資訊</a> -->
         </div>
         <!-- 事件只觸發一次(常用) -->
         <button @click.once="showInfo">點我提示資訊</button>
         <!-- 使用事件的捕獲模式 -->
         <div class="box1" @click.capture="showMsg(1)">
            div1
            <div class="box2" @click="showMsg(2)">
               div2
            </div>
         </div>
      </div>
   </body>

   <script type="text/javascript">
      Vue.config.productionTip = false //阻止 vue 在啟動時生成生產提示。
      new Vue({
         el:'#root',
         data:{
            name:'德萊聯盟'
         },
         methods:{
            showInfo(e){
               alert('嘴強王者--你好!')
               // console.log(e.target)
            },
            showMsg(msg){
               console.log(msg)
            }
         }
      })
   </script>
</html>

5.6.3 滑鼠鍵盤事件(玩玩)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue.js"></script>
</head>

<body>
  <div id ="app">
    <img :src="src"  width="200" height="200"  v-bind:title="title" />
    <img src="images/bmw.png" width="250" height="250" :title="title" />
    <div>{{title}}</div>
    <br>
    <a href="http://www.baidu.com">去百度</a>
    <a :href="baidu">去百度</a>
    <br>
    <input :value="title" />
    <!-- 事件繫結 -->
    <img :src="src" v-on:click="toBadu"  width="200" height="200" v-bind:title="title" />
    <img :src="src" @click="toBadu"  width="200" height="200" v-bind:title="title" />
    <br />
    <select @change="chageCity">
      <option value="">請選擇</option>
      <option value="武漢">武漢</option>
      <option value="北京">北京</option>
      <option value="上海">上海</option>
      <option value="廣州">廣州</option>
    </select>
    <input type="text" @focus="getFocus" @blur="lostFocus" :value="currentSelectCity">

    <div style="width: 300px;height: 300px;background-color: blue;"
      @mouseEnter="mouseEnterfun"
      @mouseMove="mouseMovefun"
      @mouseOut="mouseOutfun"
      @mouseDown="mouseDownfun"
      @mouseUp="mouseUpfun"
    ></div>
<hr>
<input type="text" v-model="msg" />
<div>{{msg}}</div>
<button @click="chageMsg">使用JS改成msg的值</button>
  </div>

  <script>
   //建立Vue例項,得到 ViewModel
   var vm = new Vue({
    el: '#app',
    data: {
      title:'BMW',
      baidu:"http://www.baidu.com",
      src:"images/bmw.png",
      currentSelectCity:undefined,
      msg:"的是輸入框的內容"
    },
    methods: {
      toBadu(){
        window.location.href=this.baidu
      },
      chageCity(x){
        console.log(x.srcElement.value);
        this.currentSelectCity=x.srcElement.value
      },
      getFocus(){
        console.log("得到焦點")
      },
      lostFocus(){
        console.log("失去焦點")
      },
      mouseEnterfun(){
        console.log("滑鼠進入")
      },
      mouseMovefun(obj){
        console.log("滑鼠移動x:"+obj.x+" y"+obj.y)
      },
      mouseOutfun(){
        console.log("滑鼠出去")
      },
      mouseDownfun(){
        console.log("滑鼠按下")
      },
      mouseUpfun(){
        console.log("滑鼠彈起")
      },
      chageMsg(){
        this.msg="我是改變之後的值"
      }
      
    }
   });
  </script>
</body>
</html>

5.6.4 練習:陣列操作

<!--給按鈕新增單擊事件,完成按鈕中的功能-->
<div id="app">
    <button v-on:click="mth1">在下標為2的地方新增一條記錄資料</button>
    <button v-on:click="mth2">在最後面新增一條記錄資料</button>
    <button v-on:click="mth3">刪除2的一條記錄資料</button>
    <button v-on:click="mth4">刪除最後一條記錄資料</button>
    <button @click="mth5">在console控制檯遍歷userList陣列</button>
</div>
<script type="text/javascript">
    let vue = new Vue({
        el:"#app",
        data:{
            userList:[
                {id:1,name:"小明",address:"武漢",sex:1},
                {id:2,name:"小紅",address:"東莞",sex:0},
                {id:3,name:"小芳",address:"佛山",sex:0},
                {id:4,name:"小麗",address:"深圳",sex:0}
            ]
        },
        methods:{
            mth1:function(){
                this.userList.splice(2,-1,{id:5,name:"小麗力",address:"深圳",sex:1})
            },
            mth2:function(){
                this.userList.push({id:6,name:"小麗力1",address:"深圳",sex:1})
            },
            mth3:function(){
                this.userList.splice(2,1)
            },
            mth4:function(){
                this.userList.pop();
            },
            mth5:function(){
                for(let index in this.userList){
                    console.log(this.userList[index]);
                }
            }
        }
    });</script>

5.7 判斷屬性
v-if

格式:
(1)v-if="表示式"
(2)v-else-if="表示式"
(3)v-else="表示式"
適用於:切換頻率較低的場景。
特點:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-if、v-else一起使用,要求結構不能被“打斷”。

<div id="app">
    <button v-on:click="mth1">修改flag值</button>
    <p v-if="flag==true">我是true</p>
    <p v-else>我是false</p>
</div>
 new Vue({
    el:"#app",
    data: {
        flag: false
    },
    methods:{
        mth1:function(){
            this.flag = !this.flag;
        }
    }
});
<div id="app">
    請輸入成績: <input type="text" v-model="score">
    <hr>
    <p v-if="score>'90'">優秀</p>
    <p v-else-if="score>'80'">良好</p>
    <p v-else-if="score>'70'">一般</p>
    <p v-else-if="score>='60'">及格</p>
    <p v-else>不及格</p>
</div>
new Vue({
    el:"#app",
    data:{
        score:'99'
    }});

v-show

寫法:v-show="表示式"
適用於:切換頻率較高的場景。
特點:不展示的DOM元素未被移除,僅僅是使用樣式隱藏掉
備註:使用v-if的時,元素可能無法獲取到,而使用v-show一定可以獲取到。

<p v-show="flag">我是show方法</p>
<p v-show="n==1">我是show方法</p>

5.8 迴圈屬性
v-for:
> 1.用於展示列表資料

2.語法:v-for="(item, index) in xxx" :key="yyy"
3.可遍歷:陣列、物件、字串(用的很少)、指定次數(用的很少)

<div id="root">
    <!-- 遍歷陣列 -->
    <h2>人員列表(遍歷陣列)</h2>
    <ul>
        <li v-for="(p,index) of persons" :key="index">
            {{p.name}}-{{p.age}}
        </li>
    </ul>
    <!-- 遍歷物件 -->
    <h2>汽車資訊(遍歷物件)</h2>
    <ul>
        <li v-for="(value,k) of car" :key="k">
            {{k}}-{{value}}
        </li>
    </ul>
    <!-- 遍歷字串 -->
    <h2>測試遍歷字串(用得少)</h2>
    <ul>
        <li v-for="(char,index) of str" :key="index">
            {{char}}-{{index}}
        </li>
    </ul>
    <!-- 遍歷指定次數 -->
    <h2>測試遍歷指定次數(用得少)</h2>
    <ul>
        <li v-for="(number,index) of 5" :key="index">
            {{index}}-{{number}}
        </li>
    </ul>
</div>

<script type="text/javascript">
    Vue.config.productionTip = false
    new Vue({
        el:'#root',
        data:{
            persons:[
                {id:'001',name:'張三',age:18},
                {id:'002',name:'李四',age:19},
                {id:'003',name:'王五',age:20}
            ],
            car:{
                name:'奧迪A8',
                price:'70萬',
                color:'黑色'
            },
            str:'hello'
        }
    })
</script>

5.9 表單資料
<input type="text"/>
則v-model收集的是value值,使用者輸入的就是value值。
<input type="radio"/>
則v-model收集的是value值,且要給標籤配置value值。
<input type="checkbox"/>

1.沒有配置input的value屬性,那麼收集的就是checked(勾選 or 未勾選,是布林值)
2.配置input的value屬性:
(1)v-model的初始值是非陣列,那麼收集的就是checked(勾選 or 未勾選,是布林值)
(2)v-model的初始值是陣列,那麼收集的的就是value組成的陣列
備註:v-model的三個修飾符:
lazy:失去焦點再收集資料
number:輸入字串轉為有效的數字
trim:輸入首尾空格過濾

<div id="root">
      <form @submit.prevent="demo">
         賬號:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
         密碼:<input type="password" v-model="userInfo.password"> <br/><br/>
         年齡:<input type="number" v-model.number="userInfo.age"> <br/><br/>
         性別:
         男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
         女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
         愛好:
         學習<input type="checkbox" v-model="userInfo.hobby" value="study">
         打遊戲<input type="checkbox" v-model="userInfo.hobby" value="game">
         吃飯<input type="checkbox" v-model="userInfo.hobby" value="eat">
         <br/><br/>
         地址
         <select v-model="userInfo.city">
            <option value="">請選擇校區</option>
            <option value="beijing">北京</option>
            <option value="shanghai">上海</option>
            <option value="shenzhen">深圳</option>
            <option value="wuhan">武漢</option>
         </select>
         <br/><br/>
         其他資訊:
         <textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
         <input type="checkbox" v-model="userInfo.agree">閱讀並接受<a href="http://www.baidu.com">《使用者協議》</a>
         <button>提交</button>
      </form>
   </div>
</body>

<script type="text/javascript">
   Vue.config.productionTip = false

   new Vue({
      el:'#root',
      data:{
         userInfo:{
            account:'',
            password:'',
            age:18,
            sex:'female',
            hobby:[],
            city:'beijing',
            other:'',
            agree:''
         }
      },
      methods: {
         demo(){
            console.log(JSON.stringify(this.userInfo))
         }
      }
   })
  1. 過濾器(瞭解)
    6.1 過濾器:
    定義:對要顯示的資料進行特定格式化後再顯示(適用於一些簡單邏輯的處理)。
    語法:

1.註冊過濾器:Vue.filter(name,callback) 或 new Vue{filters:{}}
2.使用過濾器:{{ xxx | 過濾器名}} 或 v-bind:屬性 = "xxx | 過濾器名"

備註:
1.過濾器也可以接收額外引數、多個過濾器也可以串聯
2.並沒有改變原本的資料, 是產生新的對應的資料
6.1.1 區域性過濾器

<div id="app">
//過濾器傳參是直接把前面的引數傳遞給過濾器  利用管道符
    <p>性別: {{sex==1?"男":"女"}}</p>
    <p>性別: {{sex|sexFilter}}</p>
    <p>系統時間: {{date|dateFilter}}</p>
    <p>薪資: {{money|moneyFilter}}</p>
<!-- 多個過濾器串聯  引數會傳遞給第一個過濾器  第一個過濾器過濾後的結果再傳給第二個過濾器 -->
<h3>現在是:{{time | dateFilter | moneyFilter}}</h3>
</div>
<script type="text/javascript">
    let vue = new Vue({
        el:"#app",
        data:{
            sex:1,
            date:new Date(),
            money:3.1415926
        },
        filters:{
            /*性別格式化過濾器*/
            sexFilter:function(value){
                return value==1?"男":"女";
            },
            /*時間格式化過濾器*/
            dateFilter:function(value){
                return value.getFullYear()+"年"+(value.getMonth()+1)+"月"+value.getDate()+"日";
            },
            /*薪資格式化過濾器*/
            moneyFilter(value){
                return value.toFixed(2)+"¥";
            }
        },
        methods:{}
    });

6.1.2 全域性過濾器
把過濾器註冊到vue物件上

<div id="app">
    <p>性別: {{sex==1?"男":"女"}}</p>
    <p>性別: {{sex|sexFilter}}</p>
    <p>系統時間: {{date|dateFilter}}</p>
    <p>薪資: {{money|moneyFilter}}</p>
</div>
/*性別格式化過濾器*/
Vue.filter("sexFilter",function(value){
    return value==1?"男":"女";
});
/*時間格式化過濾器*/
Vue.filter("dateFilter",function(value){
    return value.getFullYear()+"年"+(value.getMonth()+1)+"月"+value.getDate()+"日";
});
/*薪資格式化過濾器*/
Vue.filter("moneyFilter",function(value){
    return value.toFixed(2)+"¥";
});
let vue = new Vue({
    el:"#app",
    data:{
        sex:1,
        date:new Date(),
        money:3.1415926
    }
});
  1. Vue的生命週期
    Vue的生命週期就是vue例項從建立到銷燬的全過程,也就是new Vue() 開始就是vue生命週期的開始。Vue 例項有⼀個完整的⽣命週期,也就是從開始建立、初始化資料、編譯模版、掛載Dom -> 渲染、更新 -> 渲染、解除安裝 等⼀系列過程,稱這是Vue的⽣命週期。鉤子函式是Vue生命週期中每個階段對外開放讓程式設計師操作Vue的介面。Vue有8個鉤子函式。
    beforeCreate( 建立前 )
    這個時候,在例項被完成建立出來,el和data都沒有初始化,不能訪問data、method,一般在這個階段不進行操作。
    created( 建立後 )
    這個時候,vue例項中的data、method已被初始化,屬性也被繫結,但是此時還是虛擬dom,真是dom還沒生成,$el 還不可用。這個時候可以呼叫data和method的資料及方法,created鉤子函式是最早可以呼叫data和method的,故一般在此對資料進行初始化。
    beforeMount( 掛載前)
    此時模板已經編譯完成,但還沒有被渲染至頁面中(即為虛擬dom載入為真實dom),此時el存在則會顯示el。在這裡可以在渲染前最後一次更改資料的機會,不會觸發其他的鉤子函式,一般可以在這裡做初始資料的獲取。
    當vue例項中,el為掛載目標,未對el進行定義,則this.el顯示undefined,但頁面中存在template也能識別掛載目標,因為template可以被看成佔位符。如果對其進行定義則顯示
    ,故所以,beforeMount讀取不了真實的el,在mounted才能讀取到真實的el,因為el只有渲染完成後才會存在。這裡講的el是真實的el。在真實的el之前存在前,在beforeMount中的其實是頁面中的#app,是掛載的目標。
    Mounted( 掛載後)
    此時模板已經被渲染成真實DOM,使用者已經可以看到渲染完成的頁面,頁面的資料也是透過雙向繫結顯示data中的資料。 這例項建立期間的最後一個生命週期函式,當執行完 mounted 就表示,例項已經被完全建立好了,此時,如果沒有其它操作的話,這個例項,就靜靜的躺在我們的記憶體中,一動不動。
    beforeUpdate
    更新前狀態(view層的資料變化前,不是data中的資料改變前),重新渲染之前觸發,然後vue的虛擬dom機制會重新構建虛擬dom與上一次的虛擬dom樹利用diff演算法進行對比之後重新渲染。只有view上面的資料變化才會觸發beforeUpdate和updated,僅屬於data中的資料改變是並不能觸發。
    updated
    資料已經更改完成,dom也重新render完成。
    beforeDestroy
    銷燬前執行($destroy方法被呼叫的時候就會執行),一般在這裡善後:清除計時器、清除非指令繫結的事件等等…’)
    destroyed
    銷燬後(Dom元素存在,只是不再受vue控制),解除安裝watcher,事件監聽,子元件。
<body>
    <div id="app">
        <p>{{num}}</p>
        <button @click="addNum()">num++</button>
        <button @click="killVue();">銷燬</button>
    </div>
    <script>
        new Vue({
            el:"#app",
            data(){
                return {
                    num:1,
                }
            },
            methods:{
                addNum(){
                    console.log("執行add方法")
                    this.num++;
                },
                killVue(){
                    this.$destroy();
                }
            },
            beforeCreate(){
                console.log("beforeCreate",this.num)
            },
            created(){
                console.log("create",this.num)
            },
            beforeMount(){
                console.log("beforeMount",this.num)
            },
            mounted(){
                console.log("Mount",this.num)
            },
            beforeUpdate(){
                console.log("beforeUpdate:",this.num)
                //debugger  斷點模式
            },
            updated(){
                console.log("Updated:",this.num)
               // debugger
            },
            //主動銷燬   被動銷燬
            beforeDestroy(){
                console.log("beforeDestroy",this.num)
                this.addNum()
            },
            destroyed(){
                console.log("destroyed",this.num)
            }
        });
    </script>