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

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

- 2、運(yùn)行查看結(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ǔ)上添加如下代碼「紅框所示」

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

那么我們的 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 傳遞方法處

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

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

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

我們可以看到,使用 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é)果

通過 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>