Vue.js,學(xué)習(xí)心得(十二)組件二

學(xué)習(xí)心得,
組件(二),

直接上代碼了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Prop</title>
    <script src="../js/vue.js"></script>
</head>
<body>
<div id="app-1">
    <div is="child1" message="HI~~Vue.js"></div>
</div>
<hr>

<div id="app-2">
    <!-- 在 HTML 中使用 kebab-case -->
    <div is="child2" my-message="Hello~~2"></div>
</div>
<hr>

<div id="app-3">
    <input v-model="parentMsg">
    <br>
    <div is="child3" v-bind:my-message="parentMsg" v-bind="todo"></div>

</div>
<hr>

<!--字面量語法 vs 動態(tài)語法-->

<!--初學(xué)者常犯的一個(gè)錯(cuò)誤是使用字面量語法傳遞數(shù)值:-->
<!--&lt;!&ndash; 傳遞了一個(gè)字符串 "1" &ndash;&gt;-->
<!--<comp some-prop="1"></comp>-->
<!--因?yàn)樗且粋€(gè)字面量 prop伍纫,它的值是字符串 "1" 而不是一個(gè)數(shù)值贯涎。如果想傳遞一個(gè)真正的 JavaScript 數(shù)值,則需要使用 v-bind索绪,從而讓它的值被當(dāng)作 JavaScript 表達(dá)式計(jì)算:-->
<!--&lt;!&ndash; 傳遞真正的數(shù)值 &ndash;&gt;-->
<!--<comp v-bind:some-prop="1"></comp>-->



<!--非 Prop 特性-->

<!--所謂非 prop 特性,就是指它可以直接傳入組件裆针,而不需要定義相應(yīng)的 prop帐萎。-->
<!--盡管為組件定義明確的 prop 是推薦的傳參方式,組件的作者卻并不總能預(yù)見到組件被使用的場景弥锄。-->
<!--所以,組件可以接收任意傳入的特性蟆沫,這些特性都會被添加到組件的根元素上籽暇。-->
<!--例如,假設(shè)我們使用了第三方組件 bs-date-input饭庞,它包含一個(gè) Bootstrap 插件戒悠,該插件需要在 input 上添加 data-3d-date-picker 這個(gè)特性。-->
<!--這時(shí)可以把特性直接添加到組件上 (不需要事先定義 prop):-->
<!--<bs-date-input data-3d-date-picker="true"></bs-date-input>-->
<!--添加屬性 data-3d-date-picker="true" 之后舟山,它會被自動添加到 bs-date-input 的根元素上救崔。-->

<div id="app-4">
    <span is="bs-date-input" data-3d-date-picker="true" class="date-picker-theme-dark"></span>
</div>
<hr>

<div id="app-5">
    <p>{{totals}}</p>
    <button-counter v-on:increments="incrementTotals"></button-counter>
    <button-counter v-on:increments="incrementTotals"></button-counter>
</div>
<hr>


    <!--.sync 修飾符-->
    <!--<comp :foo.sync="bar"></comp>-->





<!--使用自定義事件的表單輸入組件-->

<!--自定義事件可以用來創(chuàng)建自定義的表單輸入組件,使用 v-model 來進(jìn)行數(shù)據(jù)雙向綁定捏顺。要牢記:-->

<!--<input v-model="something">-->

<!--這不過是以下示例的語法糖:-->
<!--<input-->
        <!--v-bind:value="something"-->
        <!--v-on:input="something = $event.target.value">-->
<!--所以在組件中使用時(shí),它相當(dāng)于下面的簡寫:-->
<!--<custom-input-->
        <!--v-bind:value="something"-->
        <!--v-on:input="something = arguments[0]">-->
<!--</custom-input>-->



<div id="app-6">
    <currency-input v-model="price"></currency-input>
</div>
<hr>





<div id="app-7">
    <my-checkbox v-model="foo" value="some value"></my-checkbox>
</div>
<hr>




<script>
    //使用Prop傳遞數(shù)據(jù)
    //組件實(shí)例的作用域是孤立的纬黎。
    //這意味著不能 (也不應(yīng)該) 在子組件的模板內(nèi)直接引用父組件的數(shù)據(jù)幅骄。
    //父組件的數(shù)據(jù)需要通過 prop 才能下發(fā)到子組件中。
    //子組件要顯式的用props選項(xiàng)聲明它預(yù)期的數(shù)據(jù):
    Vue.component('child1',{
        //聲明 props
        props:['message'],
        //就像data一樣,prop也可以用在模板中使用
        //同樣也可以在 vm 實(shí)例中通過 this.message 來使用
        template:'<span>{{message}}</span>'
    });
    var app1 = new Vue({
        el:"#app-1"
    });

    //    camelCase vs. kebab-case
    //
    //    HTML 特性是不區(qū)分大小寫的本今。
    //    所以拆座,當(dāng)使用的不是字符串模板時(shí),camelCase (駝峰式命名) 的 prop 需要轉(zhuǎn)換為相對應(yīng)的 kebab-case (短橫線分隔式命名):
    Vue.component('child2',{
        // 在 JavaScript 中使用 camelCase
        props:['myMessage'],
        template:'<span>{{myMessage}}</span>'
    });
    var app2 = new Vue({
        el:"#app-2"
    });

    //動態(tài)Prop
    //與綁定到任何普通的 HTML 特性相類似冠息,
    // 我們可以用 v-bind 來動態(tài)地將 prop 綁定到父組件的數(shù)據(jù)挪凑。
    // 每當(dāng)父組件的數(shù)據(jù)變化時(shí),該變化也會傳導(dǎo)給子組件:

    //    如果你想把一個(gè)對象的所有屬性作為 prop 進(jìn)行傳遞逛艰,
    //    可以使用不帶任何參數(shù)的 v-bind (即用 v-bind 而不是 v-bind:prop-name)躏碳。
    //    例如,已知一個(gè) todo 對象:

    var app3 = new Vue({
        el:"#app-3",
        data:{
            parentMsg:'',
            todo:{
                text:'Learn Vue',
                isComplete:false
            }
        },
        components:{
            child3:{
                props:['myMessage','text'],
                template:'<span>{{myMessage}},{{text}}</span>'
            }
        }
    });

    //單項(xiàng)數(shù)據(jù)流
    //    Prop 是單向綁定的:當(dāng)父組件的屬性變化時(shí)散怖,將傳導(dǎo)給子組件菇绵,但是反過來不會。
    //    這是為了防止子組件無意間修改了父組件的狀態(tài)镇眷,來避免應(yīng)用的數(shù)據(jù)流變得難以理解咬最。
    //另外,每次父組件更新時(shí)欠动,子組件的所有 prop 都會更新為最新值永乌。
    //    這意味著你不應(yīng)該在子組件內(nèi)部改變 prop。如果你這么做了,Vue 會在控制臺給出警告翅雏。
    //在兩種情況下圈驼,我們很容易忍不住想去修改 prop 中數(shù)據(jù):
    //Prop 作為初始值傳入后,子組件想把它當(dāng)作局部數(shù)據(jù)來用枚荣;
    //Prop 作為原始數(shù)據(jù)傳入碗脊,由子組件處理成其它數(shù)據(jù)輸出啦逆。
    //對這兩種情況顾画,正確的應(yīng)對方式是:
    //1.定義一個(gè)局部變量,并用 prop 的值初始化它:
    //    props: ['initialCounter'],
    //        data: function () {
    //        return { counter: this.initialCounter }
    //    }

    //    2.定義一個(gè)計(jì)算屬性叨咖,處理 prop 的值并返回:
    //props: ['size'],
    //    computed: {
    //        normalizedSize: function () {
    //            return this.size.trim().toLowerCase()
    //        }
    //    }
    //    注意在 JavaScript 中對象和數(shù)組是引用類型害碾,指向同一個(gè)內(nèi)存空間矢劲,
    // 如果 prop 是一個(gè)對象或數(shù)組,在子組件內(nèi)部改變它會影響父組件的狀態(tài)慌随。

    //Prop驗(yàn)證
    //我們可以為組件的 prop 指定驗(yàn)證規(guī)則芬沉。
    //如果傳入的數(shù)據(jù)不符合要求,Vue 會發(fā)出警告阁猜。
    //這對于開發(fā)給他人使用的組件非常有用丸逸。
    //要指定驗(yàn)證規(guī)則,需要用對象的形式來定義 prop剃袍,而不能用字符串?dāng)?shù)組:


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

        }
    });
    //    type 可以是下面原生構(gòu)造器:
    //    String
    //    Number
    //    Boolean
    //    Function
    //    Object
    //    Array
    //    Symbol
    //    type 也可以是一個(gè)自定義構(gòu)造器函數(shù)黄刚,使用 instanceof 檢測。
    //    當(dāng) prop 驗(yàn)證失敗民效,Vue 會拋出警告 (如果使用的是開發(fā)版本)憔维。
    //    注意 prop 會在組件實(shí)例創(chuàng)建之前進(jìn)行校驗(yàn),
    //    所以在 default 或 validator 函數(shù)里畏邢,諸如 data业扒、computed 或 methods 等實(shí)例屬性還無法使用。

    //非Prop特性

    //替換/合并現(xiàn)有的特性
    Vue.component('bs-date-input',{
        template:'<input type="date" class="form-control">'
    });
    var app4 = new Vue({
        el:"#app-4"
    });

    //自定義事件
    //    我們知道舒萎,父組件使用 prop 傳遞數(shù)據(jù)給子組件程储。但子組件怎么跟父組件通信呢?這個(gè)時(shí)候 Vue 的自定義事件系統(tǒng)就派得上用場了臂寝。
    //    使用 v-on 綁定自定義事件
    //
    //    每個(gè) Vue 實(shí)例都實(shí)現(xiàn)了事件接口虱肄,即:
    //    使用 $on(eventName) 監(jiān)聽事件
    //    使用 $emit(eventName) 觸發(fā)事件
    //    Vue 的事件系統(tǒng)與瀏覽器的 EventTarget API 有所不同。
    //    盡管它們的運(yùn)行起來類似交煞,但是 $on 和 $emit 并不是addEventListener 和 dispatchEvent 的別名咏窿。
    //
    //    另外,父組件可以在使用子組件的地方直接用 v-on 來監(jiān)聽子組件觸發(fā)的事件素征。
    //    不能用 $on 偵聽子組件釋放的事件集嵌,而必須在模板里直接用 v-on 綁定萝挤,參見下面的例子。

    //聲明是子組件,調(diào)用是父組件

    Vue.component('button-counter',{
        template:'<button v-on:click="incrementTotals">{{counter}}</button>',
        data:function(){
            return {
                counter:0
            }
        },
        methods:{
            incrementTotals:function () {
                this.counter += 1;
                this.$emit("increments");
            }
        }
    });

    var app5 = new Vue({
        el:"#app-5",
        data:{
            totals:0
        },
        methods:{
            incrementTotals:function () {
                this.totals +=1 ;
            }
        }
    });
    //    給組件綁定原生事件
    //
    //    有時(shí)候根欧,你可能想在某個(gè)組件的根元素上監(jiān)聽一個(gè)原生事件怜珍。
    // 可以使用 v-on 的修飾符 .native。例如:



    //所以要讓組件的 v-model 生效凤粗,它應(yīng)該 (從 2.2.0 起是可配置的):
    //接受一個(gè) value prop
    //    在有新的值時(shí)觸發(fā) input 事件并將新值作為參數(shù)
    //    我們來看一個(gè)非常簡單的貨幣輸入的自定義控件:

    Vue.component('currency-input',{
        template:'<span>$' +
        '<input ref="inputr" v-bind:value="value" v-on:input="updateValue($event.target.value)">' +
        '</span>',
        props:['value'],
        methods:{
            //不是直接更新,而是使用此方法來對輸入值進(jìn)行改格式化和位數(shù)限制
            updateValue:function(value){
                var formattedValue = value
                //刪除兩側(cè)的空格符
                    .trim()
                //保留2位小數(shù)
                    .slice(
                        0,
                        value.indexOf('.') === -1
                        ? value.length
                            :value.indexOf('.') + 3
                    )
                //如果值上不合規(guī),則手動覆蓋為合規(guī)的值
                if(formattedValue !== value){
                    this.$refs.inputr.value = formattedValue;
                }
                //通過input 事件帶出數(shù)值
                this.$emit('input', Number(formattedValue));

            }
        }
    });

    var app6 = new Vue({
        el:'#app-6',
        data:{
            price:''
        }
        //為什么price寫在這里,哪里用到了v-model="price" ??
    });



//    自定義組件的 v-model
//    默認(rèn)情況下酥泛,一個(gè)組件的 v-model 會使用 value prop 和 input 事件。
//    但是諸如單選框嫌拣、復(fù)選框之類的輸入類型可能把 value 用作了別的目的柔袁。
//    model 選項(xiàng)可以避免這樣的沖突:


    Vue.component('my-checkbox',{
        template:'<input type="checkbox">',
        model:{
            prop:'checked',
            event:'checked'
        },
        props:{
            checked:Boolean,
            value:String
        }
    });


    var app7 = new Vue({
        el:'#app-7',
        data:{
            foo:''
        }
        //    沒調(diào)通,看不明白
    });


//    非父子組件的通信
//
//    有時(shí)候,非父子關(guān)系的兩個(gè)組件之間也需要通信异逐。
    // 在簡單的場景下捶索,可以使用一個(gè)空的 Vue 實(shí)例作為事件總線:

    var bus = new Vue();

    //觸發(fā)組件A中的事件
    bus.$emit('id-selected',1);

    //在組件B創(chuàng)建的鉤子中監(jiān)聽事件
    bus.$on('id-selected',function(id){
        //...
    })


//    使用插槽分發(fā)內(nèi)容




</script>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灰瞻,隨后出現(xiàn)的幾起案子腥例,更是在濱河造成了極大的恐慌,老刑警劉巖酝润,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燎竖,死亡現(xiàn)場離奇詭異,居然都是意外死亡要销,警方通過查閱死者的電腦和手機(jī)底瓣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕉陋,“玉大人,你說我怎么就攤上這事拨扶〉树蓿” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵患民,是天一觀的道長缩举。 經(jīng)常有香客問我,道長匹颤,這世上最難降的妖魔是什么仅孩? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮印蓖,結(jié)果婚禮上辽慕,老公的妹妹穿的比我還像新娘。我一直安慰自己赦肃,他們只是感情好溅蛉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布公浪。 她就那樣靜靜地躺著,像睡著了一般船侧。 火紅的嫁衣襯著肌膚如雪欠气。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天镜撩,我揣著相機(jī)與錄音预柒,去河邊找鬼。 笑死袁梗,一個(gè)胖子當(dāng)著我的面吹牛宜鸯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播围段,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼顾翼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了奈泪?” 一聲冷哼從身側(cè)響起适贸,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涝桅,沒想到半個(gè)月后拜姿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冯遂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年蕊肥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛤肌。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡壁却,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出裸准,到底是詐尸還是另有隱情展东,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布炒俱,位于F島的核電站盐肃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏权悟。R本人自食惡果不足惜砸王,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望峦阁。 院中可真熱鬧谦铃,春花似錦、人聲如沸榔昔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疮方,卻和暖如春控嗜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背骡显。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工疆栏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惫谤。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓壁顶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親溜歪。 傳聞我的和親對象是個(gè)殘疾皇子若专,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容