免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Vue.js 創(chuàng)建一個(gè) CNODE 社區(qū)(4)

表單與 v-model / Component

內(nèi)容包含:v-model / component(全局注冊(cè)/局部注冊(cè)/父子組件之間傳遞數(shù)據(jù)/slot/動(dòng)態(tài)組件等..)

哈哈,又是 demo 和基礎(chǔ)概念理解。

邊寫 demo 邊理解總結(jié),花費(fèi)兩天終于完成,我要緩一天去學(xué)學(xué) webpack ,接著回來再戰(zhàn) Vue。

這邊博文會(huì)略長,因?yàn)橛嘘P(guān)于組件的各個(gè)例子的 demo~全部敲一遍才能理解得更快嘛。


v-model

你可以用 v-model 指令在表單<input>、<textarea> 及 <select> 元素上創(chuàng)建雙向數(shù)據(jù)綁定。它會(huì)根據(jù)控件類型自動(dòng)選取正確的方法來更新元素。

Vue 的官方文檔:v-model

v-model 的 demo :JSbin


Component

Vue 關(guān)于 組件的官方文檔:Component

定義:組件是可復(fù)用的 Vue 實(shí)例

作用:提高代碼的復(fù)用性

關(guān)于 component 的 demo:JSbin

全局注冊(cè)

<div id="app">    <!-- 2.引入組件 -->    <div-component></div-component></div>
// 1.注冊(cè)組件Vue.component('div-component',{    template:'<div>I\'m component</div>'})var app = new Vue({    el:'#app',    data:{}})

優(yōu)點(diǎn):所有的 Vue實(shí)例都可以使用

缺點(diǎn):權(quán)限太大,容錯(cuò)率低

局部注冊(cè)

<div id="app">    <!-- 引入局部組件 -->    <app-component></app-component></div>
var app = new Vue({    el:'#app',    data:{},    // 注冊(cè)局部組件    components:{        'app-component':{            template:'<div>I\'m  局部 component</div>'        }    }})

在 app實(shí)例 中創(chuàng)建的組件 只有在 app 掛載的 HTML 中才可以使用。

注意 HTML 中的某些標(biāo)簽受限:

比如 table 標(biāo)簽中嵌入組件的話將不會(huì)生效,因?yàn)樗锩嬷挥?tr/td/tbody 等屬性,除非使用 is 將組件傳遞進(jìn)去:

<div id="app">    <!-- 引入局部組件 -->    <table>        <tbody :is='app-component'></tbody>    </table></div>

使用技巧

1.命名規(guī)則:推薦使用小寫加 - 的形式命名

2.template 中的內(nèi)容必須要用一個(gè) DOM 元素包裹,也可以嵌套

3.在組件的定義中,還可以使用除了 template 之外其他的屬性,如 data / computed / methods 等

4.一個(gè)組件中的 data 必須是一個(gè)函數(shù),返回一個(gè)對(duì)象(每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝)

如:

<div id="app">    <!-- 引入局部組件 -->    <app-component></app-component>    <app-component></app-component></div>
var app = new Vue({    el:'#app',    data:{},    // 注冊(cè)局部組件    components:{        'app-component':{            template:`<div><div>I\'m  局部 component</div><button @click='countNum'>已點(diǎn)擊{{ count }}次</button></div>`,            data:function(){                return {                    msg:'component 中的 屬性',                    count:0                }            },            methods:{                countNum:function(){                this.count  = 1                }            }        }    }})

兩個(gè)按鈕每次點(diǎn)擊,都會(huì)維護(hù)各自的 count,而不會(huì)影響到其他所有實(shí)例。


父組件傳遞數(shù)據(jù)給子組件(使用 props )

demo1:

<div id="app">    <!-- 引入局部組件 -->    <!-- 父組件傳遞數(shù)據(jù) -->    <app-component msg='這是父組件給子組件傳遞的信息'></app-component>    <app-component msg='msg'></app-component></div>
var app = new Vue({    el:'#app',    data:{},    // 注冊(cè)局部組件    components:{        'app-component':{            // 在子組件頁面中渲染數(shù)據(jù)            template:`<div><div>I\'m  局部 component</div>{{ msg }}</div>`,            // 子組件通過 props 接收參數(shù)            props:[                'msg'            ]            data:function(){                return {                    msg:'component 中的 屬性',                    count:0                }            },        }    }})

1.在組件中使用props來從父組件接收參數(shù),注意,在props中定義的屬性,都可以在組件中直接使用

2.propps來自父級(jí),而組件中data return的數(shù)據(jù)就是組件自己的數(shù)據(jù),兩種情況作用域就是組件本身,可以在template,computed,methods中直接使用

3.props的值有兩種,一種是字符串?dāng)?shù)組,一種是對(duì)象

4.可以使用v--bind動(dòng)態(tài)綁定父組件來的內(nèi)容:

// 1.創(chuàng)建 Vue 實(shí)例var app = new Vue({    el:'#app',    data:{        posts: [            { id: 1, title: 'My journey with Vue' },            { id: 2, title: 'Blogging with Vue' },            { id: 3, title: 'Why Vue is so fun' }        ]    },    // 2.注冊(cè)子組件    components:{        'app-component':{            // 3.子組件通過 props 接收參數(shù)            props:[                'id',                'titel'            ],            // 4.創(chuàng)建模板,渲染組件            template:`<div>{{ id }} - {{ title }}</div>`        }    }})
<div id='app'>    <!-- 5.在父組件中引入子組件 -->    <!-- 6.動(dòng)態(tài)綁定屬性,傳遞到子組件 -->    <app-component    v-for='item in posts'    v-bind:id='item.id'    v-bind:title='item.title'></app-component></div>

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

解釋 : 通過 props 傳遞數(shù)據(jù) 是單向的了, 也就是父組件數(shù)據(jù)變化時(shí)會(huì)傳遞給子組件,但是反過來不行。

目的 :是盡可能將父子組件解耦,避免子組件無意中修改了父組件的狀態(tài)。

應(yīng)用場(chǎng)景: 業(yè)務(wù)中會(huì)經(jīng)常遇到兩種需要改變 prop 的情況

  • 1

父組件傳遞初始值進(jìn)來,子組件將它作為初始值保存起來,在自己的作用域下可以隨意使用和修改。這種情況可以在組件 data 內(nèi)再聲明一個(gè)數(shù)據(jù),引用父組件的 prop

步驟一:注冊(cè)組件

步驟二:將父組件的數(shù)據(jù)傳遞進(jìn)來,并在子組件中用props接收

步驟三:將傳遞進(jìn)來的數(shù)據(jù)通過 初始值 保存起來:

components:{    'app-component':{        props:['msg'],        data:function(){            return {                Message:this.msg            }        },        template:`<div>{{ Message }}</div>`    }}
  • 2

prop 作為需要被轉(zhuǎn)變的原始值傳入。這種情況用計(jì)算屬性就可以了

步驟一:注冊(cè)組件

步驟二:將父組件的數(shù)據(jù)傳遞進(jìn)來,并在子組件中用props接收

步驟三:將傳遞進(jìn)來的數(shù)據(jù)通過 計(jì)算屬性 進(jìn)行重新計(jì)算

<div id='app'>    <input text='text' v-model='width'>    <app-component :width='width'></app-component></div>
var app = new Vue({    el:'#app',    data:{        width:0    },    components:{        'app-component':{            props:['width'],            template:`<div :style='style'></div>`,            computed:{                style:function(){                    return {                        width:this.width  'px',                        background:'yellow',                        height:'20px'                    }                }            }        }    }})

因?yàn)楦附M件中的 input 用 v-model 綁定了父組件 data 中的 width,所以當(dāng)在 input 中輸入數(shù)字時(shí),width 也會(huì)跟著變化;而子組件中使用 :width 傳遞著父組件的 width,template 中使用了動(dòng)態(tài)綁定 :style 更新 div 的樣式,所以當(dāng) width 變化時(shí),計(jì)算屬性 style 開始計(jì)算,返回一個(gè)對(duì)象,重新渲染 div 的寬度 width。


命名規(guī)則

vue組件中camelCased (駝峰式) 命名與 kebab-case(短橫線命名)

在html中, myMessage 和 mymessage 是一致的,因此在組件中的html中使用必須使用kebab-case(短橫線)命名方式。在html中不允許使用駝峰?。?/p>

<div id='app'>    <app-component my-msg='xxx'></app-component></div>

在組件中, 父組件給子組件傳遞數(shù)據(jù)必須用短橫線。在template中,必須使用駝峰命名方式,若為短橫線的命名方式。則會(huì)直接保錯(cuò)。

components:{    props:['myMsg'],    template:`<div>{{ myMsg }}</div>`}

在組件的data中,用this.XXX引用時(shí),只能是駝峰命名方式。若為短橫線的命名方式,則會(huì)報(bào)錯(cuò)。

components:{    props:['myMsg'],    data:function(){        return {            name = this.myMsg        }    },    template:`<div>{{ myMsg }}</div>`}

數(shù)據(jù)驗(yàn)證

驗(yàn)證父組件傳遞給子組件的數(shù)據(jù)的類型:

String / Number / Boolean / Object / Array / Function

<div id='app'>    <app-component :a='a' :b='b' :c='c' :d='d' :e='e' :f='f'></app-component></div>
var app = new Vue({    el:'#app',    data:{        a:'1',        b:1,        c:true,        d:{'name':'sgt'},        e:[],        f:console.log(),        g:67,    },    components:{        'app-component':{            // required 必傳 / default 默認(rèn) / type 類型            // 如果父組件沒有向子組件 傳遞數(shù)據(jù),則使用 default 值            props:{                // 傳入的 a 的值需要是 String/Number 類型,如果不是,則報(bào)錯(cuò)                a:[String,Number]                // 必須傳入 b 且 b 的值是 Number類型,如果不傳入(即沒有 :b='b'),則報(bào)錯(cuò);如果傳入是其他類型,則報(bào)錯(cuò)                b:{type:Number,required:true},                // 傳入的值需為 Boolean 類型,如果不傳入(即沒有 :c='c'),則使用 default 值,true;如果傳入值不為 Boolean,則報(bào)錯(cuò)                c:{type:Boolean,default:true},                // 傳入的值需為 Object 類型,如果不傳入(即沒有 :d='d'),則使用 default 值;如果傳入值不為 Object,則報(bào)錯(cuò)                d:{type:Object,defult:function(){return {'name':'xxx'}}},                // 傳入的值需為 Array 類型,如果不傳入(即沒有 :e='e'),則使用 default 值;如果傳入值不為 Array,則報(bào)錯(cuò)                e:{type:Array,defult:function(){return [666]}},                // 傳入的值需為 Function 類型                f:{type:Function}                // 自定義驗(yàn)證函數(shù)                g:{validator:function(value){return value>10}},            },            template:`<div>{{a}}-{}-{{c}}-{fu8ihs5fyo3}-{{e}}-{{f}}-{{g}}</div>`        }    }})

子組件傳遞給父組件

利用自定義事件,子組件傳遞數(shù)據(jù)給父組件

子組件用$emit()來觸發(fā)事件 ,父組件用$on()來監(jiān)昕子組件的事件

<div id="app">    <!-- 引入局部組件 -->    <!-- 自定義事件 -->    <app-component @change='handleTotal'></app-component></div>
var app = new Vue({    el:'#app',    data:{        // 父組件中的數(shù)據(jù)        total:1000    },    methods:{        handleTotal:function(value){            this.total = value        }    },    components:{        'app-component':{            template:`<div>            <button @click='handleCrease'>點(diǎn)擊  1000</button>            <button @click='handleReduce'>點(diǎn)擊 -1000</button>            </div>`,            data:function(){                return {                    count:1000                }            },            methods:{                handleCrease:function(){                    this.count  = 1000                    this.$emit('change',this.count)                },                handleReduce:function(){                    this.count -= 1000                    this.$emit('change',this.count)                }            }        }    }})

過程解析:在子組件中定義了一個(gè)數(shù)據(jù) count 和兩個(gè)監(jiān)聽事件 handleCrease / handleReduce,每當(dāng)點(diǎn)擊按鈕,觸發(fā)監(jiān)聽事件,則改變 count 的值,并且把改變后的 count 作為參數(shù)通過 $emit 傳給自定義事件 change,change 綁定的是父組件中的方法 handleTotal,所以他執(zhí)行了父組件中的方法 handleTotal,把父組件中的 total 值修改成通過自定義事件傳遞進(jìn)來的參數(shù) count,實(shí)現(xiàn)子組件向父組件傳遞信息。


在組件中使用 v-model

其實(shí)使用 v-model 可以用更少的代碼實(shí)現(xiàn)上面的功能,而且不需要自定義事件:

<div id="app">    <!-- 引入局部組件 -->    <!-- 自定義事件 -->    <app-component v-model='total'></app-component></div>
var app = new Vue({    el:'#app',    data:{        // 父組件中的數(shù)據(jù)        total:1000    },    components:{        'app-component':{            template:`<div>            <button @click='handleCrease'>點(diǎn)擊  1000</button>            <button @click='handleReduce'>點(diǎn)擊 -1000</button>            </div>`,            data:function(){                return {                    count:1000                }            },            methods:{                handleCrease:function(){                    this.count  = 1000                    this.$emit('input',this.count)                },                handleReduce:function(){                    this.count -= 1000                    this.$emit('input',this.count)                }            }        }    }})

$emit的代碼,實(shí)際上會(huì)觸發(fā)一個(gè)input事件, ‘input’后的參數(shù)就是傳遞給v--model綁定的屬性的值

v--model 其實(shí)是一個(gè)語法糖,這背后其實(shí)做了兩個(gè)操作:

1.v--bind 綁定一個(gè) value 屬性

2.v--on 指令給當(dāng)前元素綁定 input 事件

<input v-model="searchText"><!-- 等價(jià)于 --><input  v-bind:value="searchText"  v-on:input="searchText = $event.target.value">

要使用v--model,要做到:

接收一個(gè) value 屬性。

在有新的 value 時(shí)觸發(fā) input 事件


非父組件之間的通信

有時(shí)候兩個(gè)組件也需要通信(非父子關(guān)系),在簡(jiǎn)單的場(chǎng)景下,可以使用一個(gè)空的Vue實(shí)例作為中央事件總線

<div id="app">    <app-component></app-component>    <bpp-component></bpp-component></div>
var app = new Vue({    el:'#app',    data:{        // 1.創(chuàng)建空的 Vue 實(shí)例,this.$root 代表著當(dāng)前組件樹的根 Vue 實(shí)例。如果當(dāng)前實(shí)例沒有父實(shí)例,此實(shí)例將會(huì)是其自己。        bus:new Vue()    }    components:{        'app-component':{            data:function(){                return {                    a:'通訊信息 SOS'                }            },            template:`<div><button @click='handleA2B'>點(diǎn)擊我從 A 組件發(fā)送到 B 組件</button></div>`,            methods:{                // 2.點(diǎn)擊執(zhí)行函數(shù),觸發(fā) $emit ,把 this.a 當(dāng)成參數(shù)傳遞給 aEvent事件                handleA2B:function(){                    this.$root.bus.$emit('aEvent',this.a)                }            }        },        'bpp-component':{            template:`<div>我是 B 組件</div>`            // 3.B 組件在實(shí)例創(chuàng)建的時(shí)候就監(jiān)聽 aEvent 事件,一旦監(jiān)聽到變化,即值傳入函數(shù)進(jìn)行處理            created:function(){                this.$root.bus.$on('aEvent',function(value){                    alert('我是 B 組件,已接收到 A 組件發(fā)出的信息:'   value)                })            }        }    }})

父鏈

父實(shí)例,如果當(dāng)前實(shí)例有的話。子組件可以拿到父組件中的內(nèi)容

<div id="app">    {{ msg }}    <app-component></app-component></div>
var app = new Vue({    el:'#app',    data:{        msg:'我是父組件中的 msg'    },    components:{        'app-component':{            template:`<div><button @click='changeFather'>點(diǎn)擊設(shè)置父組件中的 msg </button></div>`,            methods:{                changeFather:function(){                    this.$parent.msg = '哈哈,我已經(jīng)改變了這個(gè) msg'                }            }        }    }})

子鏈

提供了為子組件提供索引的方法,用特殊的屬性ref為其增加一個(gè)索引,拿到子組件中的內(nèi)容

<div id="app">    {{ msg }}    <button @click='changeChild'>點(diǎn)擊拿到子組件中的 msg</button>    <app-component ref='a'></app-component>    <bpp-component ref='b'></bpp-component></div>
var app = new Vue({    el:'#app',    data:{        msg:'這是父組件原始的 msg'    }    methods:{        changeChild:function(){            // 這里是 refs,而不是 ref            this.msg = this.$refs.a.msg        }    },    components:{        'app-component':{            data:function(){                return {                    msg:'這是子組件中的 msg'                }            },        }    }})

slot(插槽)

為了讓組件可以組合,我們需要一種方式來混合父組件的內(nèi)容與子組件自己的模板。這個(gè)過程被稱為 內(nèi)容分發(fā)。Vue.js 實(shí)現(xiàn)了一個(gè)內(nèi)容分發(fā) API,用特殊的 ‘slot’ 元素作為原始內(nèi)容的插槽。

父組件的內(nèi)容與子組件相混合,從而彌補(bǔ)了視圖的不足。

插槽嘛,顧名思義,就是在子組件中的 template 中開一個(gè)槽,槽里面可以不放數(shù)據(jù),也可以用放默認(rèn)的數(shù)據(jù);當(dāng)父組件往子組件里面插數(shù)據(jù)的時(shí)候,這個(gè)數(shù)據(jù)就會(huì)安放在槽里;如果父組件沒有網(wǎng)子組件里面插數(shù)據(jù),則顯示槽里面的默認(rèn)內(nèi)容。

  • 單個(gè)插槽
<div id="app">    <app-component>        <span>這是父組件安插在子組件中的內(nèi)容</span>    </app-component></div>
var app = new Vue({    el:'#app',    components:{        'app-component':{            template:`<div>我是組件 A <slot>如果父組件沒有插入內(nèi)容,則顯示此條消息</slot></div>`        }    }})
  • 具名插槽
<div id="app">    <app-component>        <h2 slot='header'>具名插槽</h2>        <span>這是父組件安插在子組件中的內(nèi)容</span>        <div slot='footer'>插槽尾部</div>    </app-component></div>
var app = new Vue({    el:'#app',    components:{        'app-component':{            template:`            <div>我是組件 A                <div class='header'>                    <slot name='header'></slot>                </div>                <div class='container'>                    <slot>如果父組件沒有插入內(nèi)容,則顯示此條消息</slot>                </div>                <div class='footer'>                    <slot name='footer'></slot>                </div>            </div>`        }    }})

作用域插槽

作用域插槽是一種特殊的slot,使用一個(gè)可以復(fù)用的模板來替換已經(jīng)渲染的元素 - 從子組件獲取數(shù)據(jù)

template模板是不會(huì)被渲染的,在 Vue 2.5 之后可以直接用 標(biāo)簽 slot-scope 獲取 slot 中的數(shù)組,而不是指定的 template 模板了

<div id="app">    <app-component>        <p slot='abc' slot-scope='temp'>            這是 slot 中的內(nèi)容            {{ temp.text }}            {{ temp.prop }}        </p>    </app-component></div>
var app = new Vue({    el:'#app',    components:{        'app-component':{            template:`            <div>                <slot name='abc' text='這是 slot 中的 text' prop='這是 slot 中的 prop'></slot>            </div>`        }    }})

訪問 slot

通過this.$slots.(插槽名稱)可以訪問 slot

<div id="app">    <app-component>        <p slot='abc'>            slot is ready.        </p>    </app-component></div>
var app = new Vue({    el:'#app',    components:{        'app-component':{            template:`            <div>                <slot name='abc'></slot>            </div>`,            // 在 Vue 實(shí)例掛載后            mounted:function(){                let abc = this.$slots.abc   // 獲取了一個(gè) Vue 所特有的 VNODE 節(jié)點(diǎn)                let text = abc[0].ele.innerHTML     // 根據(jù)節(jié)點(diǎn) API 獲取內(nèi)容                console.log(text)   // slot is ready.            }        }    }})

組件高級(jí)用法–動(dòng)態(tài)組件

Vue 給我們提供 了一個(gè)元素叫 component

作用是: 用來動(dòng)態(tài)的掛載不同的組件

實(shí)現(xiàn):使用is特性來進(jìn)行實(shí)現(xiàn)的

<div id="app">    <!-- :is 綁定的是組件名 -->    <component :is='thisView'></component>    <button @click='changeTo("A")'>點(diǎn)擊跳到組件A</button>    <button @click='changeTo("B")'>點(diǎn)擊跳到組件B</button></div>
var app = new Vue({    el:'#app',    data:{        // 默認(rèn)顯示的組件        thisView:'componentA'    },    methods:{        // 點(diǎn)擊后顯示改變后的組件        changeTo:function(value){            this.thisView = 'component'   value        }    },    components:{        'componentA':{            template:`            <div>                <slot name='abc'>這是組件A</slot>            </div>`,        },        'componentB':{            template:`            <div>                <slot name='cba'>這是組件B</slot>            </div>`,        }    }})

關(guān)于 v-model 和 component 的內(nèi)容就到這里啦~有更深入的理解的話會(huì)回來更新的~

來源:http://www.icode9.com/content-1-37301.html
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Vue.js
詳解vue組件三大核心概念
Vue 2.0學(xué)習(xí)筆記:Vue的render函數(shù)
Vue 父子組件之間的通信
vue.js進(jìn)階之組件
聊聊 VueJs 組件化編程
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服