vue

vue基礎(chǔ)知識(shí)部分

扯淡前言

  • 這個(gè)筆記是關(guān)于vue的所有重點(diǎn)基礎(chǔ)知識(shí),大部分配的有實(shí)例,這些實(shí)例都是我自己一個(gè)個(gè)敲上去的,我基本都是先在jsfiddle上敲完,代碼直接粘貼過(guò)來(lái)的,嘔心瀝血有木有...
  • 弄這個(gè)的目的一是為了大家能夠更好的掌握vue,因?yàn)榭丛蹅內(nèi)豪锏娜藬?shù)慢慢多了,其實(shí)最開(kāi)始就想著弄一個(gè)這樣的筆記,后來(lái)時(shí)間原因就擱置了.目前我個(gè)人覺(jué)得,如果不是構(gòu)建大型應(yīng)用,我覺(jué)得vue仍然是三大框架中最好用的,但是構(gòu)建大型應(yīng)用,肯定首選react,所以vue仍然是very,very重要的,必須無(wú)理由的熟練掌握;第二是這段時(shí)間有很多同學(xué)因?yàn)镃NODE的原因問(wèn)我一些問(wèn)題,從很多人的問(wèn)題來(lái)看,還是基礎(chǔ)知識(shí)并不是那么牢固,所以也就想為大家補(bǔ)一課;
  • 不懂的群里問(wèn),但是大家問(wèn)問(wèn)題可以,提倡的是大家先思考,再仔細(xì)檢查代碼,還是不會(huì)就谷歌,百度,如果都做完了再來(lái)問(wèn)老濕,有時(shí)候大家問(wèn)我問(wèn)題,我不是不回答,是真沒(méi)看到,因?yàn)槲乙灿泻芏喙ぷ饕?不可能一天盯著,在這里也向很多同學(xué)道個(gè)歉,因?yàn)橛袝r(shí)候我可能是一天盯著電腦,但不可能自己一天盯著手機(jī),真的很抱歉...
  • 最后祝愿大家都能前程似錦,一路繁花,好,開(kāi)始正文了....

構(gòu)造器

  • 實(shí)例化vue時(shí),需傳入一個(gè)選項(xiàng)對(duì)象,它可以包括 數(shù)據(jù)、模板、掛載元素、方法和生命周期鉤子

    屬性與方法

  • 每個(gè)vue實(shí)例都會(huì)代理其data對(duì)象里所有的屬性

  • vue實(shí)例暴露了一些有用的實(shí)例屬性與方法,這些屬性與方法都有前綴$,以便與代理的data屬性區(qū)分

    實(shí)例生命周期

  • created鉤子------在實(shí)例被創(chuàng)建后被調(diào)用

  • mounted----當(dāng)編譯好的HTML被掛載到對(duì)應(yīng)的位置,這個(gè)操作完成后觸發(fā)

  • updated----當(dāng)data中的數(shù)據(jù)改變,并且虛擬DOM重新渲染完成后觸發(fā)

  • destroyed

  • 概要: 鉤子的this 指向調(diào)用它的實(shí)例

    生命周期圖示

  • https://cn.vuejs.org/images/lifecycle.png

    插值

  • 文本

    • 雙大括號(hào)
    • v-text
  • 純HTML

    • v-html
  • 屬性

    • v-bind(大雙括號(hào)不能在屬性中使用,因此需使用v-bind)
  • 使用JavaScript表達(dá)式

    指令

  • 哪些指令?

    • v-bind

    • v-on

    • v-if

    • v-for(特殊)

                           v-if  
      <div id="app">
      <template v-if="ok==='username'">
      用戶名: <input type="text" placeholder="請(qǐng)輸入用戶名" key="name-input">
      </template>
      <template v-else>
      密碼: <input type="text"  placeholder="請(qǐng)輸入密碼" key="psd-input">
      </template>
      <button @click="toggle">點(diǎn)擊切換類型</button>
      </div>
      
      new Vue({
        el: "#app",
        data: {
          ok:'username'
        },
        methods: {
        toggle: function(todo){
            if(this.ok==='username'){
            this.ok = 'psd'
          }else{
            this.ok = 'username';
          }
        }
        }
      })
      
      
                         v-for
      <div id="app">
      <ul>
        <li v-for="item in items">{{item}}</li>
      </ul>
      </div>
      
      new Vue({
      el: "#app",
      data: {
      items:['a','b','c']
      },
      methods: {
        toggle: function(todo){
            todo.done = !todo.done
        }
      }
      })
      
      
  • 修飾符

    • v-on
      • .stop 阻止單擊事件冒泡 <a v-on:click.stop="doThis"></a>

      • .prevent 提交事件不再重載頁(yè)面

      • .capture 添加事件偵聽(tīng)器時(shí)使用時(shí)間捕獲模式

      • .self 只當(dāng)事件在該元素本身(而不是子元素)觸發(fā)時(shí)觸發(fā)回調(diào)

      • 太多了,不再總結(jié).這些都不重要,大家有空自己搜一下吧~~~~哈哈

        過(guò)濾器

  • 過(guò)濾器的目的是用于文本轉(zhuǎn)換,轉(zhuǎn)化成你想要的格式,還是給大家來(lái)個(gè)例子

                             filters
     <div id="app">
          <p>{{message | changeChar}}</p>
         <button @click="changeFirstChar">改變</button>
      </div>
    
     new Vue({
      el: "#app",
      data: {
        message:'nihao'
      },
      methods: {
          changeFirstChar: function(todo){
              this.message = 'good evening'
          }
        },
        filters:{
          changeChar(value){
                  if(!value){
              return '';
            }else{
              return value.charAt(0).toUpperCase()+value.substring(1)
            }
          }
        }
      })
    
    

縮寫

  • v-bind縮寫

    • 原有: <a v-bind:href="url"></a> 縮寫: <a :href="url"></a>
  • v-on縮寫

    • 原有:<button v-on:click="doSomeThing"></button> 縮寫:<button @click="doSomeThing"></button>

      計(jì)算屬性

      計(jì)算屬性(減少模板{{}}的復(fù)雜度)

  • 基礎(chǔ)例子1

  • 計(jì)算屬性的兩種寫法

    
    
                  computed
    
    
    <div id="app">
    {{fullName}}
    </div>
    
    

new Vue({
el: "#app",
data: {
firstName:'Ji',
lastName:'RenGu'
},
computed:{
fullName(){
return this.firstName+'----'+this.lastName;
}
}
})

* 計(jì)算緩存vs方法(Methods)
    * 計(jì)算屬性computed具有緩存,而methods無(wú)緩存
* Computed屬性vs 偵聽(tīng)器(Watch屬性)
    * watch方法--觀察Vue實(shí)例上的數(shù)據(jù)變動(dòng),只要指定的數(shù)據(jù)改變就會(huì)執(zhí)行預(yù)定的函數(shù)

                            watch
<div id="app">
    {{msg}} <br> 
    改變了嗎? {{isChange}}
    <button @click="change">改變</button>
</div>

new Vue({
  el: "#app",
  data: {
        msg:'欲窮千里目',
      isChange:'No'
  },
    watch:{
    //只要msg改變,這個(gè)方法就會(huì)執(zhí)行
    msg(val,oldVal){
        this.isChange = 'Yes'
    }
  },
  methods:{//不得不說(shuō)ES6寫起來(lái)真爽
    change(){
        this.msg = '更上一層樓'
    }
  }
})
  • computed方法

*   計(jì)算setter 和getter
    *   get和set,顧名思義,一個(gè)是獲得,一個(gè)是設(shè)置,常規(guī)上來(lái)講,計(jì)算屬性中都是有g(shù)et和set方法的,默認(rèn)是只有g(shù)etter方法,如果需要的話,自然,你也可以寫一個(gè)setter方法.來(lái)個(gè)例子,諸位往下看:
        ```

        ```
                      get和set

        ```

        <div id="app">
        此時(shí)的onpiece: {{onepiece}} <br>
        此時(shí)的msg: {{msg}} <br><br>
        <button @click="setName">設(shè)置name</button>
        </div>

new Vue({
el: "#app",
data: {
name:'Kobe',
msg:''
},
methods:{
setName(){
this.onepiece = 'JorDan'
}
},
computed:{
onepiece:{
get(){
return this.name +'Bryant';
},
set(newVal){
//當(dāng)你給onepiece設(shè)置值的時(shí)候set就就會(huì)調(diào)用
this.msg = newVal+'is the greatest basketball player';
}
}
}
})

class與style綁定

綁定HTML class

  • 對(duì)象語(yǔ)法
    • 基本
    • 在對(duì)象中傳入多個(gè)class屬性(其會(huì)與原有class共存)
    • 直接傳入對(duì)象
    • 與計(jì)算屬性一起使用(綁定返回對(duì)象的計(jì)算屬性)
  • 數(shù)組語(yǔ)法
    • 簡(jiǎn)單例子
    • 三元表達(dá)式
    • 當(dāng)有多個(gè)條件class時(shí),可以在數(shù)組語(yǔ)法中使用對(duì)象語(yǔ)法
  • 用在組件上
    • 簡(jiǎn)單例子

    • 綁定HTML class例子


     綁定class的幾種方式

.classC{
color:red;
}
.classD{
font-weight:bold;
}
.classE{
font-size:20px;
}
.classF{
color:blue;
}
.classM{
display:block;
}
.classN{
display:none;
}

<div id="app">
<h2>class屬性綁定</h2>
-------------------綁定變量-------------------------
<div :class="{classA:a,classB:b}">
綁定變量
</div>
-------------------綁定對(duì)象-------------------------
<div :class="styleObj">
綁定對(duì)象
</div>
-------------------綁定數(shù)組-------------------------
<div :class="arrClass">
綁定數(shù)組
</div>
-------------------綁定三元運(yùn)算符-------------------------
<div :class="m==true?'classM':'classN'">
綁定變量
</div>
<button @click="toggle">toggle</button>
</div>



    new Vue({
      el: "#app",
      data: {
       a:true,
       b:false,
       styleObj:{
        classC:true,
        classD:true
       },
       m:true,
       arrClass:['classE','classF']
      },
      methods:{
        toggle(){
            this.m=!this.m;
        }
      }
    })

綁定內(nèi)聯(lián)樣式

  • 對(duì)象語(yǔ)法
    • 內(nèi)聯(lián)式對(duì)象語(yǔ)法
    • 樣式對(duì)象式對(duì)象語(yǔ)法(更推薦)
  • 數(shù)組語(yǔ)法
  • 自動(dòng)添加前綴
    • v-bind:style 當(dāng)需要特定的前綴時(shí)如transform,vue.js會(huì)自動(dòng)添加
  • 多重值
    • 從vue2.3+后,可以為一個(gè)屬性添加多個(gè)值的數(shù)組,常用于含有多個(gè)前綴的情況
      例子跟上邊差不了多少,懶得寫了.相信大家應(yīng)該也都會(huì),哈哈哈哈~~~

條件渲染

v-if(v-else)是真正的渲染

  • template元素與v-if

  • v-else(需要緊跟在v-if后邊)

  • v-else-if(vue2.1.0新增)

  • 用key管理可復(fù)用的元素---(如果這個(gè)例子看不懂的話.可以在群里問(wèn)我!!!)

    • 例子:用戶名和郵箱登錄界面 如果有key就不會(huì)復(fù)用,大家可以把key去試一下,然后輸入看一下效果!!!

        <div id="app">
          <template v-if="ok==='username'">
              用戶名: <input type="text" placeholder="請(qǐng)輸入用戶名" key="name-input">
          </template>
          <template v-else>
             密碼: <input type="text"  placeholder="請(qǐng)輸入密碼" key="psd-input">
          </template>
          <button @click="toggle">點(diǎn)擊切換類型</button>
        </div>
      
        new Vue({
          el: "#app",
          data: {
           ok:'username'
          },
          methods: {
            toggle: function(todo){
                if(this.ok==='username'){
                this.ok = 'psd'
              }else{
                this.ok = 'username';
              }
            }
          }
        })
      
      

      v-show(其只是簡(jiǎn)單的切換display屬性)

  • v-show不支持template語(yǔ)法

  • v-show不支持v-else

    v-if VS v-show

  • v-if

    • 當(dāng)條件不成立時(shí)不會(huì)渲染
    • 切換開(kāi)銷較大,適合不太可能變化的場(chǎng)景
  • v-show

    • 無(wú)論成不成立都會(huì)渲染

    • 首次渲染開(kāi)銷較大,但切換開(kāi)銷小,因此適合經(jīng)常變化的場(chǎng)景

      列表渲染

      v-for

  • 基本用法

    • 簡(jiǎn)單例子
    • 帶有index參數(shù)
    • 使用of 替代 in
  • template v-for

    • 簡(jiǎn)單例子
  • 對(duì)象迭代 v-for

    • 基礎(chǔ)用法
    • 帶其他參數(shù)用法
  • 整數(shù)迭代 v-for

    • 例子
  • 組件和v-for
    包含所有類型的例子

    <div id="app">
        <hr>
        <strong style="border:2px solid #ccc;">遍歷數(shù)組:</strong>
        <ul>
          <li v-for="item in items" >{{item}}</li>
        </ul>
         <hr>
        <strong style="border:2px solid #ccc;">遍歷對(duì)象數(shù)組:</strong>
        <ul>
          <li v-for="(item,index) in pers">{{index}}--我是{{item.name}},今年{{item.age}}歲</li>
        </ul>
           <hr>
        <strong style="border:2px solid #ccc;">遍歷對(duì)象:</strong>
        <ul>
          <li v-for="(value,key) in obj">
            key:{{key}} |
            value:{{value}}
          </li>
        </ul>
    </div>
    
    new Vue({
        el: "#app",
        data: {
          isOK:'true',
              items:['香蕉','蘋果','烤肉'],
          pers:[{
              name:'Kobe',
            age:'40'
          },
          {
              name:'James',
            age:'38'    
          }],
          obj:{
              1:'one',
            2:'two'
          }
        }
      })
    
    

key

  • 作用

    • 用v-for更新已渲染過(guò)的列表時(shí),它默認(rèn)采用的是“就地復(fù)用”的原則,也就是如果數(shù)據(jù)項(xiàng)順序發(fā)生了改變,vue將不是移動(dòng)DOM元素來(lái)匹配數(shù)據(jù)項(xiàng)的順序,而是簡(jiǎn)單復(fù)用此處的元素。如果想跟蹤每個(gè)節(jié)點(diǎn)的身份,從而重用或重新排列現(xiàn)有元素,可使用key。(key還可用在v-if中,詳見(jiàn)v-if中的郵箱名和用戶名切換的例子)
  • 好吧,可能大家看到這里是一頭霧水,不知所以,憂心忡忡,到底key有什么卵用,剛才上邊的例子不是沒(méi)有加key嗎?好吧,不扯那沒(méi)用的,通過(guò)一個(gè)例子告訴大家key到底有啥用!!!

      <div id="app">
        KEY: <input type="text" v-model="id"> VALUE: <input type="text" v-model="name">
        <button @click="add">添加</button>
        <ul>
      <li v-for="item in list" :key="item.id"> //此處你可以吧key去了,先勾選一條,在追加一條試一下,然后加上key,勾選一條追加一條再試一下,一目了然
        <input type="checkbox" >
        {{item.id}}---{{item.name}}
      </li>
        </ul>
      </div>
    
    
    new Vue({
    el: "#app",
    data: {
      id:"",
      name:"",
      list:[
        {id:1, name:'李斯'},
        {id:2, name:'嬴政'},
        {id:3, name:'趙高'},
        {id:4, name:'韓非'},
        {id:5, name:'荀子'},
      ]
    },
    methods: {
        add: function(){
          this.list.unshift({id:this.id,name:this.name})
      }
    }
    })
    
    

因?yàn)榧由蟢ey默認(rèn)采取的就是就地復(fù)用策略,這個(gè)例子,如果不懂,可以在群里問(wèn)我


### 數(shù)組更新檢測(cè)

*   變異方法(會(huì)改變?cè)袛?shù)組)
    *   push()
    *   pop()
    *   shift()
    *   unshift()
    *   splice()
    *   sort()
    *   reverse()
*   重塑數(shù)組
    *   filter()
    *   concat()
    *   slice()
*   注意事項(xiàng)
    利用索引直接設(shè)置一個(gè)項(xiàng)時(shí),vue不能檢測(cè)變動(dòng),如: vm.items[indexOfItem] = newValue
    那如果設(shè)置某一項(xiàng)的該怎么設(shè)置呢?

    ```
      * Vue.set(example1.items, indexOfItem, newValue)
      * example1.items.splice(indexOfItem, 1, newValue)

    ```

    ```

    <div id="app">
    <button @click="setZF">設(shè)置第二項(xiàng)為張飛</button>
    <button @click="setGY">設(shè)置第三項(xiàng)為關(guān)羽</button>
    <ul>
    <li v-for="item in list">
    <input type="checkbox" >
    {{item.id}}---{{item.name}}
    </li>
    </ul>
    </div>

var vmm = new Vue({
el: "#app",
data: {
id:"",
name:"",
list:[
{id:1, name:'李斯'},
{id:2, name:'嬴政'},
{id:3, name:'趙高'},
{id:4, name:'韓非'},
{id:5, name:'荀子'},
]
},
methods: {
setZF: function(){
Vue.set(this.list,1,{id:2,name:'張飛'})
},
setGY:function(){
this.list.splice(2,1,{id:3,name:'關(guān)羽'})
}
}
})

* 修改數(shù)組長(zhǎng)度時(shí),vue不能檢測(cè)變動(dòng),如:vm.items.length = newLength
* 只能用example1.items.splice(newLength)

對(duì)與顯示過(guò)濾/排序結(jié)果的兩種方法

  • 過(guò)濾數(shù)組--計(jì)算屬性computed例子

  • 過(guò)濾數(shù)組--方法methods例子


          計(jì)算屬性應(yīng)用于過(guò)濾

<div id="app">
{{specialNum}}
</div>

new Vue({
el: "#app",
data: {
nums:[1,2,3,4,5,6,7,8,9]
},
computed:{
specialNum(){
return this.nums.filter((item,index)=>{
return item%3==0;
})
}
}
})

<div id="app">
<ul>
在v-for循環(huán)中直接嵌入方法
<li v-for="item in fil(numbers)">{{item}}</li>
</ul>
</div>

new Vue({
el: "#app",
data: {
numbers:[1,2,3,4,5,6,7,8,9]
},
methods:{
fil(nums){
return nums.filter((item,index)=>{
return item%3==0;
})
}
}
})

兩個(gè)簡(jiǎn)單的事件處理器


先來(lái)一個(gè)簡(jiǎn)單小李子,v-on用來(lái)綁定事件

1

<div id="app">
<button @click="num+=1">增加1</button>
{{num}}
</div>

* * *

2

<div id="app">
<button @click="sayHello">點(diǎn)擊sayHello</button>
</div>
new Vue({
el: "#app",
methods: {
sayHello: function(){
alert('sayHello')
}
}
})
`### 內(nèi)聯(lián)處理器方法 * 訪問(wèn)原生DOM事件的例子,如果click事件不傳參數(shù),就默認(rèn)把原生DOM傳遞進(jìn)去`
<div id="app"> //沒(méi)有傳參數(shù),就是原生的!!!
<button @click="showBtnname">顯示按鈕的名字</button> <br><br>
{{msg}}
</div>

new Vue({
el: "#app",
data: {
msg:''
},
methods: {
showBtnname: function(e){
this.msg = e.target.innerText;
}
}
})

  • 未訪問(wèn)原生DOM事件的例子,如果傳了參數(shù).那么方法中接受的第一個(gè)參數(shù)就是該參數(shù),在vue中所有的事件綁定都是這樣的

----------------------------html---------------------------------
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<label>
<input type="checkbox" v-on:change="toggle(todo)" v-bind:checked="todo.done">

  <del v-if="todo.done">
    {{ todo.text }}
  </del>
  <span v-else>
    {{ todo.text }}
  </span>
</label>

</li>
</ol>


</div>
----------------------------js---------------------------------
new Vue({
el: "#app",
data: {
todos: [
{ text: "Learn JavaScript", done: false },
{ text: "Learn Vue", done: false },
{ text: "Play around in JSFiddle", done: true },
{ text: "Build something awesome", done: true }
]
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
----------------------------css---------------------------------
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}

#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}

li {
margin: 8px 0;
}

h2 {
font-weight: bold;
margin-bottom: 15px;
}

del {
color: rgba(0, 0, 0, 0.3);
}

事件修飾符

  • .stop
    • 阻止單擊事件冒泡
  • .prevent
    • 提交事件不再重載頁(yè)面
  • .capture
    • 使用事件捕獲模式
  • .self
    • 只有當(dāng)事件在該元素本身被觸發(fā)時(shí)(不包含子元素)才觸發(fā)回調(diào)
  • .once
    • 事件只觸發(fā)一次(vue 2.1.4新增)
  • 修飾符串聯(lián)
    • 例子

按鍵修飾符

  • .enter

    • keyCode
    • .enter
  • .tab

  • .delete

    • (捕獲 “刪除” 和 “退格” 鍵)
  • .esc

  • .space

  • .up

  • .down

  • .left

  • .right

  • 組合使用,單獨(dú)是使用的話,和click都是一樣的,這里組合使用有點(diǎn)特殊,使用 . 進(jìn)行連接簡(jiǎn)單給個(gè)例子


<div id="app">
<button @click.ctrl="num++">num+1</button>
{{num}}
</div>

new Vue({
el: "#app",
data: {
num:0
}
})


vue2.1.0新增 按鍵修飾符

  • .ctrl

  • .alt

  • .shift

  • .meta

    表單控件綁定

    基礎(chǔ)用法

  • 文本

      <div id="app">
        <h2>{{msg}}</h2>
        <br>
        <input type="text" v-model="msg">
      </div>
    
      new Vue({
        el: "#app",
        data: {
         msg:'萬(wàn)年的msg'
        }
      })
    
    
  • 多行文本---注意了啊:在文本區(qū)域插值( <textarea></textarea> ) 并不會(huì)生效,應(yīng)用 v-model 來(lái)代替

      <div id="app">
      <p  style="white-space: pre">
        {{msg}}
      </p>
        <br>
        <textarea type="text" v-model="msg"></textarea>
      </div>
    
    
  • 復(fù)選框

    • 單個(gè)復(fù)選框(直接綁定true,false)

      <div id="app">
      <input type="checkbox" id="checkbox" v-model="checked">
      <label for="checkbox">{{ checked }}</label>
      </div>
      
      new Vue({
        el: "#app",
        data: {
         checked:true
        }
      })
      
      
    • 多個(gè)復(fù)選框(將選中的所有value綁定到一個(gè)數(shù)組)

      <div id="app">
          <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
          <label for="jack">Jack</label>
          <input type="checkbox" id="john" value="John" v-model="checkedNames">
          <label for="john">John</label>
          <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
          <label for="mike">Mike</label>
          <br>
          {{checkedNames}}
      </div>
      
      new Vue({
        el: "#app",
        data: {
          checkedNames:[]
        }
      })
      
      
  • 單選按鈕(綁定選中的單選框的value)

      <div id="app">
      <input type="radio" id="one" value="One" v-model="picked">
      <label for="one">One</label>
      <br>
      <input type="radio" id="two" value="Two" v-model="picked">
      <label for="two">Two</label>
      <br>
      <span>Picked: {{ picked }}</span>
      </div>
    
      new Vue({
        el: "#app",
        data: {
          picked:''
        }
      })
    
    
  • 選擇列表(不管是單選還是多選,v-model都要綁定到select元素上)

    • 單選列表(綁定到被選中項(xiàng)的value)

        <div id="app">
            <select v-model="selected">
              <option>A</option>
              <option>B</option>
              <option>C</option>
            </select>
            <span>Selected: {{ selected }}</span>
        </div>
      
        new Vue({
          el: "#app",
          data: {
            selected:''
          }
        })
      
      
* 多選列表(綁定一個(gè)數(shù)組,數(shù)組的內(nèi)容是所有的選中項(xiàng)的value)

    ```
    <div id="app">
    <select v-model="selected" multiple>
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
    <br>
    <span>Selected: {{ selected }}</span>
    </div>

    new Vue({
      el: "#app",
      data: {
        selected: []
      }
    })
    ```

* 動(dòng)態(tài)選項(xiàng)
    ```
    <div id="app">
    <select v-model="selected">
      <option v-for="option in options" v-bind:value="option.value">
        {{ option.text }}
      </option>
    </select>
    <span>Selected: {{ selected }}</span>
    </div>

    new Vue({
      el: "#app",
      data: {
             selected: 'A',
        options: [
          { text: 'One', value: 'A' },
          { text: 'Two', value: 'B' },
          { text: 'Three', value: 'C' }
        ]
      }
    })
    ```

修飾符

  • .lazy

    • 由原有的input事件變更為change事件

        <div id="app">
          <input type="text" v-model.lazy="msg">
          {{msg}}
        </div>
      
        new Vue({
          el: "#app",
          data: {
            msg:'萬(wàn)年的msg'
          }
        })
      
      
  • .number

    • 將輸入的類型轉(zhuǎn)換成數(shù)字類型(NaN則還是原有類型)
  • .trim

    • 去除兩端空白

算了,這點(diǎn)太簡(jiǎn)單了,不給例子了,自己寫去吧,別來(lái)煩我,有不會(huì)的群里問(wèn)......

v-model與組件

組件

使用組件

  • 注冊(cè)

    • 注意事項(xiàng)

      • 在初始化根實(shí)例前一定要確保注冊(cè)了組件

      • 名稱最好 小寫(可以使用短桿)

        
        <div id="app">
        <my-comp></my-comp>
        </div>
        
        
    Vue.component('my-comp',{
        template:'<h3>我是新出爐的組件</h3>'
    })
    new Vue({
      el: "#app",
      data: {

      }
    })
    ```

  • 局部注冊(cè)

      <div id="app">
        <my-comp></my-comp>
      </div>
    
      new Vue({
        el: "#app",
        components:{
            'my-comp':{template:'<h3>我是新出爐的組件</h3>'}
        },
        data: {
    
        }
      })
    
    
  • DOM模板解析說(shuō)明

    • 自定義組件在這些元素內(nèi)受限

      • ul

      • ol

      • table

      • select

      • 概要: 解決方案是 使用 特殊的is屬性

        <div id="app">
        <table>
        
        

        <tr>
        <my-comp></my-comp>//注意:這樣寫是絕對(duì)錯(cuò)誤的,因?yàn)閠r中只允許有td,這樣寫他是不認(rèn)識(shí)滴
        </tr>

        
        </table>
        </div>
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 上邊是錯(cuò)誤的
        
        
        ---------------------------------下邊是正確的-----------------------------------
        <div id="app">
         <table>
           <tr>
             <td is="my-comp"></td>
           </tr>
         </table>
        </div>

        new Vue({
          el: "#app",
          components:{
              'my-comp':{
                    template:'<td>我是組件td</td>'
            }
          },
          data: {

          }
        })
        ```

* 不受限的情況--使用字符串模板
    * <script type="text/x-template">  怎么用呢?給大家來(lái)個(gè)例子吧!

      ```
      -------------------------------HTML-----------------------------------------
      <div id="app">
       <table>
         <tr>
         <template>
             <my-comp></my-comp>
         </template>
         </tr>
       </table>
      </div>

      <script type="text/x-template" id="myComponent">
                  <td>This is a component!</td>
      </script>

      -----------------------------------JS----------------------------------
      new Vue({
        el: "#app",
        components:{
            'my-comp':{
                  template:'#myComponent'
          }
        },
        data: {

        }
      })
      ```

    * JavaScript內(nèi)聯(lián)模板字符串(第二種也給大家解釋一下是什么意思,什么是字符串模板)

      ```
      <div id="app">
       <table>
         <tr>
         <template>  //這個(gè)就是字符串模板
             <my-comp></my-comp>
         </template>
         </tr>
       </table>
      </div>
      ```

    * .vue組件  (第三種不解釋了,用了那么多遍了,要是還不會(huì),我就開(kāi)始瘋狂嘲笑你)

* data必須是函數(shù),在組件中使用data中定義的數(shù)據(jù),必須使用函數(shù)返回,其實(shí)這事要說(shuō)為啥,還得從根上說(shuō),我自己的理解,最根本的三個(gè)字就是作用域,目的就是為了防止組件中使用的data和vue實(shí)例中的data進(jìn)行相互污染,有機(jī)會(huì)的話可以給大家講一下,但是這不是三句兩句就能講清楚的,門票一人5毛怎么樣?

    ```
    <div id="app">
    <mycomp></mycomp>
    </div>

    new Vue({
      el: "#app",
      components:{
          'mycomp':{
                template:'<button>{{btncount}}</button>',
           data(){
              return {btncount:8}
            }
        }
      },
      data:{
          btncount:10
      }
    })
    ```

Prop(子組件從父組件獲得數(shù)據(jù))

  • 使用prop傳遞數(shù)據(jù)

    •   <div id="app">
            <child msg="我是來(lái)自于父組件的內(nèi)容"></child>
        </div>
      
        new Vue({
          el: "#app",
          components:{
              'child':{
                props:['msg'],
                template:'<h2>{{msg}}</h2>'
            }
          }
        })
      
      
    •           動(dòng)態(tài)綁定父組件中的數(shù)據(jù)
        <div id="app">
          <input type="text" v-model="fathertext">
              {{fathertext}}
          <child :childText="fathertext"></child>
        </div>
      
        new Vue({
          el: "#app",
          components:{
              'child':{
                props:['childtext'],
                template:'<h1>{{childtext}}</h1>'
            }
          },
          data: {
              fathertext:''
          }
        })
      
      
    • props注意事項(xiàng)

      • 一般情況下是數(shù)組形式,如果要想規(guī)定props的數(shù)據(jù)類型(后面用中括號(hào) [ ])。默認(rèn)值等(見(jiàn)props驗(yàn)證),則是對(duì)象了(后面用花括號(hào) { })
  • 關(guān)于命名:要不然全小寫,要不然kebabCase(駝峰式),kebab-case(短橫線隔開(kāi)式)Vue 能夠正確識(shí)別出小駝峰和下劃線命名法混用的變量,如這里的forChildMsgfor-child-msg是同一值。

  • ,如果出不來(lái),先檢查一下命名,看個(gè)例子:

      老濕老濕,幫我看下我寫的這個(gè)哪里錯(cuò)了?---呵呵呵,我哪知道,我也不會(huì)
    
      <div id="app">
        <input type="text" v-model="msg">
        <child :childMsg="msg"></child>
      </div>
    
      new Vue({
        el: "#app",
        components:{
            child:{
              template:'<h1>{{childMsg}}</h1>',
                props:['childMsg']
          }
        },
        data: {
         msg:'apple'
        }
      })
    
    
  • 動(dòng)態(tài)Prop(使用v-bind):在模板中,要?jiǎng)討B(tài)地綁定父組件的數(shù)據(jù)到子組件模板的 props,和綁定 Html 標(biāo)簽特性一樣,使用v-bind綁定

    • 局部注冊(cè)組件
    • 全局注冊(cè)組件
  • 字面量語(yǔ)法vs動(dòng)態(tài)語(yǔ)法

  • 單向數(shù)據(jù)流

    • 解釋

      • 父組件數(shù)據(jù)更新后,子組件的所有prop都會(huì)更新為最新值,但是反過(guò)來(lái)就不會(huì)。(注意 :如果prop為數(shù)組或?qū)ο髸r(shí),子組件改變prop,父組件的狀態(tài)也會(huì)受到影響,因?yàn)閿?shù)組或?qū)ο笫且妙愋?,他們指向同一個(gè)內(nèi)存空間。)如果子組件的prop值被修改,則vue會(huì)給出警告。試一下下邊這個(gè)例子

        <div id="app">
        <parent></parent>
        </div>
        
        let childNode = {
         template: `
             <div class="child">
              <div>
               <span>子組件數(shù)據(jù)</span>
               <input v-model="forChildMsg"/>
              </div>
              <p>{{forChildMsg}}</p>
             </div>`,
         props: {
          "for-child-msg": String
         }
        };
        let parentNode = {
         template: `
             <div class="parent">
              <div>
               <span>父組件數(shù)據(jù)</span>
               <input v-model="msg"/>
              </div>
              <p>{{msg}}</p>
              <child :for-child-msg="msg"></child>
             </div>
            `,
         components: {
          child: childNode
         },
         data() {
          return {
           msg: "default string."
          };
         }
        };
        
        new Vue({
          el: "#app",
          components:{
              parent:parentNode
          }
        })
        
        
    • 特殊情況應(yīng)對(duì)方法

      • prop作為初始值傳入后,可能子組件想把它當(dāng)做局部數(shù)據(jù)來(lái)用的情況

        • 方法:定義一個(gè)局部變量,并用prop的值初始化它

          props: ['initialCounter'],
          data: function () {
            return { counter: this.initialCounter }
          }
          //直接使用counter作為子組件的局部變量就可以了
          
          
      • prop作為初始值傳入,可能子組件處理成其他數(shù)據(jù)輸出的情況,比如處理成去空格并大寫

        • 方法:定義一個(gè)計(jì)算屬性,處理prop的值并返回

          props: ['size'],
          computed: {
            normalizedSize: function () {
              return this.size.trim().toLowerCase()
            }
          }
          
          
  • prop驗(yàn)證

    • 例子--代碼篇

      Vue.component('example', {
        props: {
          // 基礎(chǔ)類型檢測(cè) (`null` 意思是任何類型都可以)
          propA: Number,
          // 多種類型
          propB: [String, Number],
          // 必傳且是字符串
          propC: {
            type: String,
            required: true
          },
          // 數(shù)字,有默認(rèn)值
          propD: {
            type: Number,
            default: 100
          },
          // 數(shù)組/對(duì)象的默認(rèn)值應(yīng)當(dāng)由一個(gè)工廠函數(shù)返回
          propE: {
            type: Object,
            default: function () {
              return { message: 'hello' }
            }
          },
          // 自定義驗(yàn)證函數(shù)
          propF: {
            validator: function (value) {
              return value > 10
            }
          }
        }
      })
      
      

自定義事件(子組件將數(shù)據(jù)傳回父組件)

  • 使用v-on綁定自定義事件

    • 給組件綁定自定義事件例子(用v-on來(lái)監(jiān)聽(tīng)子組件觸發(fā)的事件)

    • 給組件綁定原生事件例子--使用native修飾符

      <div id="app">
        <btncomp @click.native="alertE"></btncomp>
      </div>
      
      new Vue({
        el: "#app",
           components:{
            btncomp:{
              template:'<button>點(diǎn)擊我彈出</button>'
          }
        },
        methods:{
            alertE(){
              alert(777)
          }
        }
      })
      
      
  • .sync修飾符(vue 2.3)

    • 目的:使父子組件實(shí)現(xiàn)prop類似“雙向數(shù)據(jù)綁定”(默認(rèn)子組件無(wú)法更改prop的值,上邊已經(jīng)說(shuō)到了,但是使用sync后子組件可以改變prop 的值,并傳回父組件)

    • 使用范例

        <div id="app">
            <child :name.sync="name"></child>  //其實(shí)不加也能更改,但是會(huì)報(bào)錯(cuò)
            <button type="button" @click="changePropsInFather">在父組件中將props值改變?yōu)?props'</button>
          </div>
      
            Vue.component('Child', {
              template: `<h1 @click="changePropsInChild">hello, {{name}}</h1>`,
              props: {
                name: String,
              },
              methods:{
                changePropsInChild(){
                  this.name = 'I am from child'
                }
              },
            })
            // 實(shí)例化一個(gè)Vue對(duì)象
            const app = new Vue({
              el: '#app',
              data(){
                return {
                  name: 'world'
                }
              },
              methods:{
                changePropsInFather(){
                  this.name='I am from father'
                },
              },
            })
      
      
  • 使用自定義事件的表單輸入組件

    • v-model的語(yǔ)法糖(可能之前我在CNODE課程中講過(guò),但是提的不是特別的仔細(xì),這里還是給大家再說(shuō)一下)

         <div id="app">
             <input v-model="price">
         </div>
      
          new Vue({
             el: '#app',
             data: {
                  price: ''
             }
         });
      
      

      我們對(duì)v-model已經(jīng)再熟悉不過(guò)了,一般都是像上邊這樣的用法,但是v-model只是一個(gè)語(yǔ)法糖,它的真身是下邊這樣:

        <div id="app">
        <input type="text" :value="price" @input="price = $event.target.value">{{price}}
        </div>
      
          new Vue({
             el: '#app',
             data: {
                  price: ''
             }
         });
      
      
* 例子

    * html及實(shí)例部分和注冊(cè)組件部分

      ```
      <div id="app">
        <price-input :value="price" @input="isinputing"></price-input>
        {{price}}
      </div>

      new Vue({
        el: "#app",
        components:{
            'price-input':{
              template:"<input type='text' @input='update($event.target.value)' />",
            props:['value'],
            methods:{
                update(val){
                  this.$emit('input',val)
              }
            }
          }
        },
        data: {
          price:''
        },
        methods: {
            isinputing: function(val){//此處的value就是子組件傳遞過(guò)來(lái)的
              this.price = val;
          }
        }
      })
      ```

非父子組件通信

  • 非父子組件通信(1 父?jìng)髯邮怯胮rops 2 子傳父在vue中是不允許的,因?yàn)関ue只允許單向數(shù)據(jù)傳遞,這時(shí)候我們可以通過(guò)觸發(fā)事件來(lái)通知父組件改變數(shù)據(jù),從而達(dá)到改變子組件數(shù)據(jù)的目的. 3 那么非父子組件之間通信怎么搞??????)

    • 簡(jiǎn)單的場(chǎng)景---采用空實(shí)例作為中央事件總線,原理就是找一個(gè)人來(lái)當(dāng)作一個(gè)中轉(zhuǎn)站!

      
       <div id="app1" @click="toApp2">
          我是組件一,點(diǎn)擊我給二傳值
        </div>  <br>
         <div id="app2">
           {{app2msg}}
         </div>
      
      var bus = new Vue();  // 創(chuàng)建事件中心,創(chuàng)建中轉(zhuǎn)站
      new Vue({
        el: "#app1",
        data: {},
        methods: {
            toApp2: function(){
              bus.$emit('change','上山打老虎')  //使用中轉(zhuǎn)站觸發(fā)
          }
        }
      })
      
      new Vue({
        el: "#app2",
        data: {
            app2msg:''
        },
        created(){
            bus.$on('change',(val)=>{
              this.app2msg = val; //在組件二創(chuàng)建完成的時(shí)候就使用中轉(zhuǎn)站進(jìn)行監(jiān)聽(tīng)
          })
        }
      })
      
      
* 復(fù)雜的場(chǎng)景---專門的狀態(tài)管理模式vuex

使用Slot分發(fā)內(nèi)容

  • 內(nèi)容分發(fā)概念

    • 為了讓組件可以組合(如本子主題的例子),因此需要混合父組件的內(nèi)容與子組件的自己模板,這一過(guò)程就稱作內(nèi)容分發(fā)。

        <app>
          <app-header></app-header>
          <app-footer></app-footer>
        </app>
      
        之前我們的組件,如果給app指定了模板,那么里邊的app-header和foot組件的內(nèi)容就會(huì)被覆蓋,因此,為了讓他們能夠組合.需要混用,這就是內(nèi)容分發(fā)
      
      
  • 編譯作用域

    • 分發(fā)內(nèi)容是在父作用域內(nèi)編譯的
  • 單個(gè)slot(無(wú)具名slot)

    • 為什么用slot

      • 當(dāng)父組件中有內(nèi)容(即自定義的標(biāo)簽名之間有元素--見(jiàn)本子主題的例子) 子組件模板中無(wú)slot時(shí),則父組件中的內(nèi)容會(huì)被丟棄。

          <div id="app">
            <my-comp>
              <p>我是組件中的內(nèi)容</p>  //這個(gè)p會(huì)被覆蓋
            </my-comp>
          </div>
        
          new Vue({
            el: "#app",
            components:{
                'my-comp':{
                  template:'<h1>我是一個(gè)組件</h1>'
              }
            }
          })
        
        
        * 那么單個(gè)slot怎么用呢?

            ```
            <div id="app"> 
            <children> 
            <span>12345</span> 
            <!--上面這行不會(huì)顯示--> 
            </children> 
            </div> 

            var vm = new Vue({ 
            el: '#app', 
            components: { 
            children: { //這個(gè)無(wú)返回值,不會(huì)繼續(xù)派發(fā) 
                template: "<button><slot></slot>(我是button)</button>"
            } 
            } 
            }); 
            ```

* 當(dāng)父組件中有內(nèi)容時(shí)
    * 子組件中的slot會(huì)被父組件中內(nèi)容所替換。(slot標(biāo)簽也會(huì)被替換掉)
* 當(dāng)父組件中無(wú)內(nèi)容時(shí)
    * 子組件中slot內(nèi)容會(huì)被顯示出來(lái)

  • 具名slot

    • 用法:保子引父(保持子組件模板,引入父組件參數(shù))--嚴(yán)格按照子組件的模板順序來(lái)即:遇到具名slot對(duì)應(yīng)的元素就渲染相應(yīng)的元素,遇到不具名的slot,則會(huì)渲染除了具名slot對(duì)應(yīng)的元素以外的所有元素。

        <div id="app">
          <children>
            <span slot="first">12345</span>
            <span slot="second">56789</span>
            <!--上面這行不會(huì)顯示-->
          </children>
        </div>
      
        var vm = new Vue({ 
        el: '#app', 
        components: { 
          children: { //這個(gè)無(wú)返回值,不會(huì)繼續(xù)派發(fā) 
            template: "<button><slot name='first'></slot>我是button<slot name='second'></slot>所以使用button標(biāo)簽</button>"
          } 
        } 
        }); 
        總結(jié):說(shuō)白了,就是多一個(gè)name屬性.沒(méi)啥稀奇玩意
      
      
  • 作用域插槽(特殊的插槽)

    • 作用:使用可復(fù)用模板替代已渲染元素

    • 用法:同具名slot類似,都是嚴(yán)格按照子組件的模板順序渲染,只不過(guò)遇到slot元素時(shí)會(huì)將父組件中的template元素里的元素全部渲染

      • 列表組件例子

        
        <div id="app">
        <child :items="items">
        <template slot="item" scope="props">
        <!--必須存在的具有 scope屬性的 template元素(作用域插槽的模板), props臨時(shí)的變量名稱,接受子組件中傳遞的props對(duì)象-->
        <!--slot = “item”是具名 slot的用法。-->
        <li>
        {{props.tex}}
        <!--引用子組件中綁定的tex屬性值。-->
        </li>
        </template>
        </child>
        </div>
        
        
        Vue.component('child',{
                props:["items"],
                template:'<ul><slot name="item" v-for="item in items" v-bind:tex="item.text"></slot></ul>'
            });

        new Vue({
            el:'#app',
            data:{
                items:[
                    {text:'老虎'},
                    {text:'棒子'},
                    {text:'雞'}
                ]
            }
        })
        ```

動(dòng)態(tài)組件

  • 使用is屬性(注意,is前使用了v-bind?。?!通過(guò)is來(lái)決定那個(gè)組件被渲染顯示 )

    
       <div id="app">
          <component v-bind:is="show"></component>
          <button v-on:click="changeShow">change show</button> 
       </div>
    
            var app=new Vue({
                  el:'#app',
                  data:{
                      show:'tem1'
                  },
                  components:{
                      tem1:{
                          template:'<div>11111111111</div>'
                      },
                        tem2:{
                          template:'<div>22222</div>'
                      },
                        tem3:{
                          template:'<div>333333</div>'
                      }
                  },
                  methods:{
                      changeShow:function(){
                          if(this.show=='tem1'){
                                  this.show='tem2'
                          }else  if(this.show=='tem2'){
                                  this.show='tem3'
                          }else{
                               this.show='tem1'
                          }
                      }
                  }
              })
    
    
  • keep-active

    • 作用:可保留組件狀態(tài)或避免重新渲染(包裹動(dòng)態(tài)組件時(shí)會(huì)緩存不活動(dòng)的組件實(shí)例而不是銷毀它們)配合 <keep-alive>使用時(shí),可以保留組件狀態(tài)避免重新渲染(和v-show 比較的差別是v-show 是一開(kāi)始就渲染的所有組件,而keep-alive 并不是一開(kāi)始就渲染好所有組件,而已保留渲染過(guò)的組件

    • 注意事項(xiàng):使用環(huán)境應(yīng)該是較大頁(yè)面頻繁切換的情景下

    • 用法

                <div id="app">
                    <component v-bind:is="show"></component>
                    <button v-on:click="changeShow">change show</button>
                </div>
      
                         var app=new Vue({
                    el:'#app',
                    data:{
                        show:'tem1'
                    },
                    components:{
                        tem1:{
                            template:'<div>11111111111</div>'
                        },
                          tem2:{
                            template:'<div>22222</div>'
                        },
                          tem3:{
                            template:'<div>333333</div>'
                        }
                    },
                    methods:{
                        changeShow:function(){
                            if(this.show=='tem1'){
                                    this.show='tem2'
                            }else  if(this.show=='tem2'){
                                    this.show='tem3'
                            }else{
                                 this.show='tem1'
                            }
      
                        }
                    }
      
                })
      
      

總結(jié)

  • 這些就基本涵蓋了vue的基礎(chǔ)知識(shí),大家都知道,經(jīng)濟(jì)基礎(chǔ)決定上層建筑,學(xué)知識(shí)也是一樣,只有基礎(chǔ)知識(shí)掌握牢固,你才有機(jī)會(huì),有資格去學(xué)習(xí)vue中更加高級(jí)的用法,比如異步組件,嵌套組件等等,好了,感謝大家看到這里,有問(wèn)題可以群里交流
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容