04、手把手教Vue--props

PS:轉(zhuǎn)載請(qǐng)注明出處
作者: TigerChain
地址: http://www.itdecent.cn/p/87ff57037d9c
本文出自 TigerChain 簡(jiǎn)書 手把手教 Vue 系列

本節(jié)大綱

本節(jié)大綱

教程簡(jiǎn)介

  • 1、閱讀對(duì)象
    本篇教程適合新手閱讀,老手直接略過
  • 2、教程難度
    初級(jí),本人水平有限,文章內(nèi)容難免會(huì)出現(xiàn)問題,如果有問題歡迎指出,謝謝
  • 3、Demo 地址:https://github.com/tigerchain/vue-lesson 請(qǐng)看 02、vue組件 組件這一節(jié)

正文

一、v-bind

在說 props 之前,我們先說說 v-bind 這個(gè)指令

1、什么是 v-bind?

v-bind 用來動(dòng)態(tài)的綁定一個(gè)或多個(gè)屬性,或一個(gè)組件的 prop ,比如綁定圖片地址、標(biāo)簽的樣式等,v-bind 的縮寫是 :

2、v-bind 的用法

比如,我們給 img 一個(gè)圖片資源地址

<img v-bind:src="imageSrc"/>

再比如,我給一個(gè) div 設(shè)置 css 樣式,如下

<div v-bind:class="{divstyle:isShowStyle}"></div>

<style>
 .divstyle {
    background-color: red;
 }
</style>

<script>
 var vm = new Vue({
   el:"#root",
   data:{
      // 如果 isShowStyle 為 true 的話,那么 
      // v-bind:class="{divstyle:isShowStyle}" 表示此 div 的 class 就是 divstyle
      isShowStyle:true
   }
 })
</script>

等等,拿官方的舉例來說,v-bind 可以綁定屬性「以數(shù)據(jù)驅(qū)動(dòng)」,在綁定 class 或 style「內(nèi)聯(lián)樣式」 的時(shí)候支持?jǐn)?shù)據(jù)或?qū)ο螅韵率枪俜脚e例基本上把 v-bind 的使用場(chǎng)景介紹完了,html 的屬性只能使用 v-bind 來綁定「除非你使用原生寫法,不使用 v-bind」

<!-- 綁定一個(gè)屬性 -->
<img v-bind:src="imageSrc">

<!-- 縮寫 -->
<img :src="imageSrc">

<!-- 內(nèi)聯(lián)字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 綁定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 綁定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 綁定一個(gè)有屬性的對(duì)象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通過 prop 修飾符綁定 DOM 屬性 -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 綁定?!皃rop”必須在 my-component 中聲明。-->
<my-component :prop="someThing"></my-component>

<!-- 通過 $props 將父組件的 props 一起傳給子組件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

3、寫個(gè) demo 感受一下吧,這里直接在 script 引入 vue.js 來寫

  • 1、核心代碼如下:
<body>
  <div id="container">
    <!-- 第一種寫法 其中 img 是寬度為 35 的 style 樣式-->
    <img v-bind:src="imgSrc" v-bind:class="{'img':show}" >
    <!-- 第二種寫法 -->
    <img v-bind:src="'./imgs/logo.png'" v-bind:style="imgStyle" >
    <p v-bind:style="{color:'red'}">{{msg}}</p>
    <!-- 標(biāo)簽的屬性的都可以使用 v-bind 替換 -->
    <input v-bind:type="'text'"  v-bind:placeholder="'輸入內(nèi)容'" v-model="clickBtnText"><!-- :value="''"  和 v-model 同時(shí)出現(xiàn)會(huì)報(bào)錯(cuò)-->
    {{clickBtnText}} <br/>
    <!-- 這里是行內(nèi)樣式 -->
    <input type="button" value="測(cè)試" v-bind:style="{'margin-top':'10px'}">
  </div>
  <script>
    // 定義一個(gè)樣式
    var imgStyle = {
      height: '40px',
      width: '40px'
    }

    var vm = new Vue({
      el: '#container',
      data: {
        msg:"123",
        imgStyle:imgStyle,
        imgSrc:'./imgs/logo.png',
        show:true,
        clickBtnText:''
      }
    })
  </script>
</body>
  • 2、查看結(jié)果
v-bind 結(jié)果

我們看到我們使用 v-bind 設(shè)置圖片,設(shè)置樣式「行內(nèi)樣式和行外樣式」,并且代替 html 原有的屬性等,并且成功顯示,調(diào)試窗口也沒有報(bào)錯(cuò)

二、props 屬性

Vue 和 React 一樣,是使用 props「單向數(shù)據(jù)流」 來傳遞數(shù)據(jù)的「父組件的數(shù)據(jù)傳遞給后代組件」,props 在本組件中是不能修改的「和 React 也是一毛一樣」

1、一般格式

我們知道組件有四種格式,不管那種格式 props 用法都是相同的,這里以全局組件為例子

Vue.component('customcomponent',{
    // 定義接收的 props 等待父組件傳遞
    props:['message'],
    template: '<span>{{message}}</span>',
    ... 數(shù)據(jù)和方法等省略

})

2、直接寫代碼感受一下

在以下 demo 中,我們使用 props 來傳遞字符串、對(duì)象、樣式來感受一下 props

  • 1、直接在上面的代碼基礎(chǔ)上修改,添加以下代碼
<hr>
<h4>以下是 props 例子</h4>
<div id="app2">
<!-- 如果要使用 props 來傳遞對(duì)象,就要使用 v-bind  -->
<mycomponent message="你好" :mydata="{username:'tigerchain',age:28}" name-style="color:red"></mycomponent>
</div>

<script>
// 定義一個(gè)組件
var myComponent = Vue.extend({
  // 定義 props 
  props: {
    message:"",
    mydata:{},
    //樣式 ,如果這里使用駝峰標(biāo)識(shí) ,則在標(biāo)簽中使用就要使用 name-style 傳遞
    nameStyle:{}
  },
  template: '<div>{{ message }} <div> <span v-bind:style="nameStyle">{{ mydata.username}}</span></div> </div>'
})

// 全局注冊(cè)組件 組件的別名要是小寫,否則會(huì)報(bào)錯(cuò)
Vue.component('mycomponent', myComponent)

var vm2 = new Vue({
  el:'#app2',
})
</script>

為了便于觀察,我們重新定義了一個(gè) id 為 app2 的 div 和一個(gè)新的 Vue 實(shí)例「vm2」 ,我們定義一個(gè)組件并且添加如下的 props

添加 props屬性

在使用組件的時(shí)候就可以傳遞數(shù)據(jù)了

props 傳遞方法
  • 2、運(yùn)行查看結(jié)果
傳遞 props 結(jié)果

我們看到,傳遞過來的數(shù)據(jù)完美的接收到并顯示出來了,在這里注意以幾下幾點(diǎn)

  • 如果 props 中聲明的是數(shù)據(jù)是駝峰標(biāo)識(shí),那么傳值的時(shí)候就要使用 - 標(biāo)識(shí)

比如 props 中的數(shù)據(jù)是 myData 那么在組件中傳值時(shí)就要使用 my-data="" ,如果沒有使用駝峰那不牽扯

  • 在組件中使用 props 傳值的時(shí)候默認(rèn)傳的是字符串

如果想要傳值「比如對(duì)象,數(shù)據(jù)等」那么就要使用 v-bind="" 來傳值,上面的 message 和 mydata 就顯示了這兩種方式

  • props 中就定義一些默認(rèn)的值,不能直接修改 props,只能間接的通過 data 來修改「在 data 里面定義數(shù)據(jù),值就是 props ,這一點(diǎn) React 是一樣的」,其實(shí) Vue 中的 data 就和 React 中的 state 是一樣的

  • props 中的值,我們?cè)?Vue 實(shí)例中可以使用 this.props 的值來訪問「和仿問 data 是一樣的」

三、 props 驗(yàn)證

想要寫一個(gè)有“良心”的組件,指定 props 的驗(yàn)證規(guī)則非常有必要,比如我們?cè)凇rops 中定義傳遞過來的 name 必須是字符串否則就發(fā)出警告「這對(duì)使用插件的人來說是非常友好的」

1、驗(yàn)證規(guī)則

直接引用官方的驗(yàn)證規(guī)則吧

 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
      }
    }
  }

其中 type 有以下幾種類型:

  • String:字符串
  • Number:數(shù)字
  • Boolean: boolean 類型
  • Function: props 能傳遞方法,這樣的話,組件方法的回調(diào)是非常 easy 的
  • Object: 對(duì)象
  • Array: 數(shù)組
  • Symbol: 原始類型

2、寫段代碼看一下吧,我們?cè)谠写a基礎(chǔ)上添加如下代碼「紅框所示」

props 中添加規(guī)則

在這里我們就可以傳遞方法「實(shí)現(xiàn)了方法的回調(diào)」,并且規(guī)定了 age 只能傳遞數(shù)字,然后再看 vm2 實(shí)例中添加方法,如下所示

props-method

那么我們的 show 方法是如何來的呢,細(xì)心的朋友會(huì)發(fā)現(xiàn),我們?cè)诮M件中調(diào)用了 props 中聲明的方法,這個(gè) show 就是我們?cè)谑褂媒M件的時(shí)候偉遞過來的,我們看看代碼

<div id="app2">
    <!-- 如果要使用 props 來傳遞對(duì)象,就要使用 v-bind  -->
    <mycomponent
      message="你好"
      :mydata="{username:'tigerchain',age:28}"
      name-style="color:red"
      age="100"
      :clickme="show()"
      />
</div>

由于 clickme 是 props 中規(guī)定的必須是方法,所以這里傳遞一個(gè)方法過去,在 vue 實(shí)例中直接實(shí)現(xiàn)這個(gè)方法就 ok 了「這樣我們就可以在多組件開發(fā)中使用 props 來傳遞方法來達(dá)到方法回調(diào)的作用」,并且我們?yōu)榱蓑?yàn)證 age 故意傳了一個(gè)字符串,我們?cè)?chrome 調(diào)試容器能看到報(bào)錯(cuò)了,說 age 要傳一個(gè)數(shù)字「這里就不截圖了,大家可以自行實(shí)驗(yàn)」,上面的例子雖然把方法回調(diào)回來了,但是這在實(shí)際開發(fā)中還是有缺陷的,回調(diào)回來的方法沒有帶個(gè)參數(shù)「這肯定不能滿足常用的開發(fā)呀」,我們修改一下上面的代碼來實(shí)現(xiàn)回調(diào)傳參

修改一:props 傳遞方法處

props-pass-funvalue.png

修改二:調(diào)用 props 傳參方法

props-pass-vaule-call.png

修改三:回調(diào)方法實(shí)現(xiàn)

props-callback-fun.png

經(jīng)過以上三處修改,我們就使用 props 來回調(diào)子組件的方法「并且?guī)?shù)」完美實(shí)現(xiàn)了

3、顯示結(jié)果如下

props-pass-fun-callback.gif

我們可以看到,使用 props 傳遞方法,并且把子組件中的"你好"當(dāng)作方法參數(shù)回傳回來

以上我們就把 props 基本上介紹完了,細(xì)心的朋友可以發(fā)現(xiàn),我們?cè)?props 中傳遞方法的時(shí)候,未修改之前的方法是帶括號(hào)的,后面的方法沒有帶括號(hào),那么這有什么區(qū)別呢?再給大家贈(zèng)送一些 Vue 中的方法的一些知識(shí)

三、Vue 中的方法

Vue 中的方法可以定義在 methods 中「這不廢話嗎」,也可以定義在 data 中,針對(duì)于無參數(shù)方法可以帶括號(hào),也可以不帶括號(hào)來說明「有參數(shù)方法則必須帶括號(hào)」,那么這些到底有什么區(qū)別呢?我們實(shí)際寫一個(gè)例子來總結(jié)一下吧

  • 1、新建一個(gè) vue-method.html 文件「并引入 vue.js」

核心代碼如下

<h3>Vue 中的方法</h3>
  <div id="container">
    <button v-bind:class="{bg:isShowbgStyle}" @click="testDataFun">在 data 調(diào)用 testDataFun 方法</button>
    <button v-bind:class="{bg:isShowbgStyle}" @click="testDataFun()">在 data 調(diào)用 testDataFun() 方法</button>
    <button v-bind:class="{bg:isShowbgStyle}" @click="testInMethodsFun">在 methods 調(diào)用 testInMethodsFun 方法</button>
    <button v-bind:class="{bg:isShowbgStyle}" @click="testInMethodsFun()">在 data 調(diào)用 testInMethodsFun() 方法</button>
  </div>

  <script>
    var vm = new Vue({
      el:"#container",
      data:{
        isShowbgStyle:true,
        testDataFun(){
          console.log(this,arguments)
        }
      },
      methods: {
        testInMethodsFun() {
          console.log(this,arguments)
        }
      }
    })
  </script>
  • 運(yùn)行查看結(jié)果
vue-method.png

通過 Demo 我們清楚的知道以下結(jié)論

  • 1、在 data 或是 methods 中調(diào)用無參方法,那么默認(rèn)會(huì)把 Event 對(duì)象傳遞進(jìn)去,比如上面的 1、3 方法
  • 2、如果想讓 this 指向 Vue 實(shí)例化的對(duì)象,如果在 data 方法調(diào)用就必須加上括號(hào)
  • 3、在 Vue methods 中的方法不管加參數(shù)還是不加參數(shù)「帶括號(hào)或是不帶括號(hào)」,this 都指向 Vue 的實(shí)例化對(duì)象
  • 4、綜上所術(shù),我們把 Vue 中的方法都放在 methods 中是最好的選擇,如果想要想綁定事件,那么不加括號(hào)是最好的選擇。

有的朋友可能會(huì)問了,那我想在 data/methods 中聲明方法,既綁定事件又傳參數(shù)如何搞呢?可以做到嗎,肯定可以,我們添加測(cè)試代碼如下

<button v-bind:class="{bg:isShowbgStyle}" @click="testInMethodsFun('msg',$event)">在 data 調(diào)用 testInMethodsFun(參數(shù),事件) 方法</button>

我們可以使用 $event 顯示的把原生事件傳遞過去,查看一下輸出結(jié)果

Vue$3 {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue$3, …} 

Arguments(2) ["msg", MouseEvent, callee: ?, Symbol(Symbol.iterator): ?]

怎么樣,Arguments 參數(shù)中第一個(gè)是方法參數(shù),第二個(gè)就是傳遞過來的事件,在 data 方法是同理

到此為止,我們把 vue props 就說完了,請(qǐng)大家動(dòng)手寫寫感受一下

四、回顧一下

  • v-bind 是用來綁定屬性的和 props 傳遞對(duì)象或值使用的「props 默認(rèn)傳遞的是字符串,如果想要傳值、對(duì)象,那么就要使用 v-bind」

  • 如果 props 中聲明的是數(shù)據(jù)是駝峰標(biāo)識(shí),那么傳值的時(shí)候就要使用 - 標(biāo)識(shí)

    如:props 中的數(shù)據(jù)是 myData 那么在組件中傳值時(shí)就要使用 my-data="" ,如果沒有使用駝峰那不牽扯

  • props 用來定義一些默認(rèn)值,我們不能直接修改 props 的值,只能通過 data 來間接修改

  • 要寫一個(gè)"合格"的 vue 組件,那么 props 最好加上驗(yàn)證

  • props 也可以用來傳遞方法,達(dá)到父組件調(diào)用子組件方法并且回調(diào)的目標(biāo)

  • vue 中的方法建議寫在 methods 中,無參方法調(diào)用時(shí)就不要加括號(hào)

怎么樣,說了這么多就這么幾個(gè)知識(shí)點(diǎn),再次提示一定要?jiǎng)邮謱懸粚憽父惺芤幌隆?/p>

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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