vue中如何實現數據的雙向綁定


vue中如何實現數據的雙向綁定

實現視圖變化數據跟着變:分兩步,上面get中的為第二步(即再次讀取的時候會調用get方法得到之前設置的值,以此來實現動態改變)
由於直接寫obj.name = this.value;會導致循環調用set方法,所以要借助中間對象的形式把值賦給中間對象,獲取obj.name的時候我們獲取中間對象的最新值即可
let  obj = {name:'zhufeng',age:9};//數據
let temp = {name:"lily"};//借助中間對象
let input1 = document.getElementById("box2");//視圖
//對某一個對象使用了Object.defineProperty方法之后就要寫對應的get和set方法了,不然無法像操作普通對象一樣訪問或者設置它的屬性
//此方法不兼容IE8及以下
Object.defineProperty(obj,"name",{
    configurable:true,//屬性是否可刪除
    writable:false,//屬性是否可修改
    enumerable:false,//屬性是否可枚舉
    get(){//獲取obj的屬性名對應的屬性值時會調用該方法
       /*2*/ return temp['name'];
    },
    set(val){//設置obj的屬性名對應的屬性值時會調用此方法

        //實現視圖變化數據跟着變:分兩步,上面get中的為第二步(即再次讀取的時候會調用get方法得到之前設置的值,以此來實現動態改變)
        //由於直接寫obj.name = this.value;會導致循環調用set方法,所以要借助中間對象的形式把值賦給中間對象,獲取obj.name的時候我們獲取中間對象的最新值即可
        /*1、*/ temp.name=val;

        //實現數據變化視圖改變
        input1.value=val;
    }
});
//為了初始化的時候讓視圖中(文本框中)有值:出現obj.name說明要訪問這個屬性就會用到defineProperty中的get方法
input1.value=obj.name;
//實現視圖改變數據跟着改變
input1.addEventListener("input",function(){
    obj.name = this.value;//當值變化時會調用set方法
},false);

vue中的指令

dom元素的行間屬性,vue提供了內置的指令,必須以v-開頭,后面的值均為變量

v-cloak

消除頁面剛加載時會看到{{}}閃一下的效果,可加給最外層的根元素;

 //需要添加對應的css樣式
    [v-cloak]{
      display: none;
    }

v-model(表單元素設置了之后會忽略掉value,checked,selected)

讓表單元素和數據實現雙向綁定(映射關系)

 <input type="text" v-model="msg">

v-text:代替 {{}} 渲染成文本(不會識別html標簽)可以防止網速卡慢時{{}}出現在頁面上

{{}} 中的值都會解析成文本內容;

{{msg}}等價於<div v-text="msg"><!--此處不能再寫內容,防止出現閃的效果--></div>

v-html:把html字符渲染成html

 <div v-html="msg"></div>

v-once:只綁定一次(不能寫成v-once=”msg”)

    <div v-once>{{msg}}</div>

v-bind:動態地綁定一個或多個特性

// 綁定一個屬性
<img v-bind:src="imageSrc">
//可縮寫為如下形式,此時:src后面的值就可以是變量、表達式、賦值運算、計算、三元運算符(盡量少寫邏輯運算)
<img :src="imageSrc">//此時imageSrc就代表一個變量

v-for:遍歷數組、對象、字符串、數字

解決了循環問題,更高效,會在原有的基礎上進行修改,會復用原有的結構,不會修改所有DOM

要循環創建哪一個標簽就在那一個標簽上加v-for,后面的循環最好用in,用of有時會報錯循環數組或對象使用v-for指令
  <div v-for="(val,index) in msg">
          {{val,index}}//msg為數組時,val為數組中的每一項,index為索引
  </div>  
  <div v-for="(value,key,index) in msg">
      {{key}}={{value}}{{index}};//msg為對象時,key為對象中的每個屬性名,value為屬性值,index為索引
  </div>  

條件渲染:v-if v-else-if v-elsev-show

v-if v-else-if v-else:條件滿足才渲染v-if所在標簽以及標簽內的內容;(操作的是DOM結構)

  • 設置條件判斷的DOM元素必須是連續的
  • 操作的是DOM元素
  • key 管理復用的元素 若不想復用DOM元素,只需要給相應的DOM元素增加不同的key值
  • 支持 template 標簽
  • 頻繁的顯示和隱藏用v-if會很浪費性能(操作的是DOM結構),此時要用v-show(操作的是CSS樣式)
<div id= "app">
<button @click="flag=!flag">請點擊</button>
//template標簽是vue提供給我們的沒有任何實際意義,用來包裹元素用的(v-show不支持template標簽)
<template v- if="flag">
<label>登錄</label>
<input type= "text" key="1">//key 管理復用的元素 若不想復用DOM元素,只需要給相應的DOM元素增加不同的key值
< /template>
<template v-else>
<label>注冊</label>
<input type="text" key="2">
</template>
< /div>
let vm=new Vue({
el:'#app',
data:{
flag:true
}
});

v-show

條件滿足才讓v-show所在標簽以及標簽內的內容顯示(操作的是元素的css樣式),不支持 template 標簽

 <input type="text" v-show="flag">//flag為true時,input框才顯示

v-on:監聽 DOM 事件(v-on:click可縮寫為@click)

可以用 v-on 指令監聽 DOM 事件,並在觸發時運行一些 JavaScript 代碼(在 methods 對象中定義的方法,而且methods中的方法名不能和data中的變量名一樣)

 <div v-on:click ="fn1('zhaosi,$event')">{{msg}}</div>
    <div @click ="fn1('zhaosi,$event')">{{msg}}</div>//上面的簡寫 
    方法后面可加()可不加。不加的話默認會傳入事件對象e,
    加()代表要傳參數,如果要用事件對象,則需要傳$event

自定義指令

可通過在vue實例的directives:{}屬性中賦予自定義指令意義

<div id="app">
     <button v-color="flag">變色</button>
  </div>
  let vm=new Vue({
     el:'#app',
     data:{
         flag:true
     },
     directives:{//在這里賦予對應自定義指令意義
         //可直接寫對應的指令不用寫v-
         color(el,val){
         //el和val都是默認給的:el指的是指令所綁定的DOM元素,val是一個對象,里面存儲的是有關指令的信息,可用val.value獲取到指令綁定的變量(或者表達式)所代表的值,這里就是flag所代表的值 'red'
         el.style.background=val.value;
         }
     }
  });

vue中的修飾符

表單修飾符

  • v-model.number:將用戶的輸入值轉為數值類型
  • v-model.lazy:在表單觸發change事件時更新數據,而非觸發input事件時更新數據
  • v-model.trim:自動過濾用戶輸入的首尾空白字符

事件修飾符

  • @click.stop:阻止點擊事件的傳播(往上傳播和往下傳播都會被阻止)
  • @submit.prevent:阻止點擊提交按鈕時的默認行為(阻止事件的默認行為)
  • @click.capture:點擊的時候讓事件在捕獲階段執行;
  • @click.once:只在第一次點擊的時候讓綁定的事件執行;
  • @click.self:只有點擊的事件源是自己的時候觸發事件;(判斷事件源)

表單元素雙向數據綁定(雙向同步)

使用v-model屬性可讓input中的內容和數據實現雙向同步,但是使用了v-model屬性之后,input的value、checked、select屬性都會失效

<div id="app">
    <input type="text" v-model="msg">
</div>
<script src="vue.js"></script>
<script>
    let vm=new Vue({
        el:'#app',//vue的屬性和方法對哪個DOM根元素起作用(對它的后代元素也起作用)
        //數據
    如果data中屬性的值是一個數組,如果想改變數組中內容,只能使用原生的會修改原數組的方法進行修改,普通的 數組[索引]=值 不行;
        data:{//寫在data中的屬性都會掛載到當前實例上
            msg:'zhufeng'
        }
    });
    console.log(vm.msg);//'zhufeng'
</script>

單選框

對於單選框和復選框來說,加了v-mdel屬性后,初始設置的value屬性不會失效;

 <div id="app">
      <input type="radio" v-model="msg" value="男"><input type="radio" v-model="msg" value="女">女
      {{msg}}
   </div>
  let app3=new Vue({
     el:'#app',
     data:{
       msg:'男'//默認選中的項,值與value的值對應,點擊女的時候msg就會動態改為女
     }
   });

復選框

單個復選框:

 <div id="app">
    //復選框中加了v-model后value依然可用
        <input type="checkbox" v-model="msg">
    </div>
    let app3=new Vue({
        el:'#app',
        data:{
        //如果是復選框且只有一個的時候,會把msg的值轉化為布爾值,如果為true,代表選中
            msg:false//為false時代表默認不選中
        }
    });

多個復選框,需要綁定到同一個數組,而且要給input設置初始value值,為了在后面選中的時候獲取到對應的選中框的值

 <div id="app">
      //復選框中加了v-model后value依然可用
        <input type="checkbox" v-model="msg" value="吃飯">吃飯
        <input type="checkbox" v-model="msg" value="睡覺">睡覺
        <input type="checkbox" v-model="msg" value="敲代碼">敲代碼
        {{msg}}
    </div>
        new Vue({
          el: '#app',
          data: {
            msg: [] //此處的msg需要是一個數組
          }
        })

下拉框

   <div id="app">
    //加了multiple后就變為多選框,用ctrl+左鍵點擊多選,msg也要換為一個數組
        <select v-model="msg" multiple>
        //加了disabled時候用戶就不能選中此項了
        //option中的value是給寫代碼的人看的
            <option value="0" disabled>請選擇地區</option>
            <option value="1">北京</option>
            <option value="2">上海</option>
            <option value="3">浙江</option>
        </select>
        {{msg}}//如果option的value屬性不寫,則取的是option中的內容
    </div>
    let app3=new Vue({
        el:'#app',
        data:{
            msg:'0'//默認選中的某一項,值與每一個option的value值對應
        }
    });

Vue中的Class樣式與style樣式動態綁定(動態的優先級高於原來的)

:class=”{}”或者:class=”[]: 
通過:class=”{}”或者:class=”[]來動態的綁定class樣式,與原來的class樣式不沖突。 
有兩種方式: 
1、對象的方式綁定 
2、數組的方式綁定

 <div id="app">
<!--以對象的方式動態綁定class樣式:當flag為true時,z樣式生效。y樣式不生效-->
        <div class="x" :class="{z:flag,y:false}">我的世界</div>
<!--以數組的方式動態綁定class樣式:y,z兩個樣式都會生效-->
       <div class="x" :class="[y,z]">我的世界</div>
    </div>
    let vm=new Vue({
        el:'#app',
        data:{
            flag:true
        }
    });

:style=”{}”或者:style=”[]”:綁定行內的樣式 
通過上述的方式來動態綁定行內的樣式

<div id="app">
 //第一種是對象的方式
     <div :style="{backgroundColor:'red',color:'pink'}">我是誰</div>
//第二種是數組的方式
     <div :style="[str1,str2]">我的世界</div>
 </div>
    let vm=new Vue({
        el:'#app',
        data:{
            str1:{backgroundColor:'blue'},
            str2:{color:'yellow'}
        }
    });

根據hash實現單頁面開發

通過hash記錄跳轉的路徑(可以產生歷史管理) 
瀏覽器自帶的歷史管理方法history(history.pushState(),push到哪里就跳轉到哪里),可能會導致404錯誤(因為用戶可能會隨意輸入路徑) 
開發時使用hash的方式,上線的時候使用history的方式 
[使用hash存儲]

//存儲:存儲的時候要把存儲的對象轉換成字符串
 localStorage.setItem('todo',JSON.stringify(obj));
//獲取:獲取的時候要把字符串轉換成對象
JSON.parse(localStorage.getItem('todo'));

 


免責聲明!

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



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