vue的组件深入了解

# .natvie

>能够在使用组件的时候,将事件传递到组件的根元素上面。(默认在调用组件的时候,写的一些事件,是不会被触发比如:click。)

# $listeners实例属性是干什么的。

>在我们调用组件的时候,可以给组件上面写上一些个事件。但是默认这个事件是不会被执行的。如果我想让他执行。需要给事件加上.native的属性。这个时候,我这个事件是绑定在组件的根元素的。。如果我需要将这个事件不绑定在根元素上。这时就需要$listeners。他里面的内容。就是你在组件调用的时候,定义的那个事件。。

#组件需要可复用性高。灵活性高。(代码不要写死)

#有时需要对组件的prop进行双向绑定

# slot

base-layout

#组件的作用域

PS:

1.组件有自己的作用域,里面的数据只能在里面自己找。找不到就报错了。

2.父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

#作用域插槽

#对象解构

```js

varprop= {h:'msg',s:'哈哈哈哈'};

var{h} =prop; =>varh=prop.h;

var{h,s} =prop;=>varh=prop.h;vars=prop.s;

```

# keep-alive vue默认提供的一个内置组件。用于缓存当前不活动|失活|看不见的的组件或路由或。。。。

#组件动态切换会使组件被销毁。。再次出现会重建。

#如果想实现缓存组件的话,就只需要将keep-alive内置组件做为容器将他们给包裹起来。


1.原生事件

<!DOCTYPEhtml>

<htmllang="en">

<head>

   <metacharset="UTF-8">

   <metaname="viewport"content="width=device-width, initial-scale=1.0">

   <metahttp-equiv="X-UA-Compatible"content="ie=edge">

   <title>Document</title>

</head>

<body>

   <divid="app">

       <!--

           子组件调用根元素自己的方法

           默认情况下我们在组件的标签上绑定的事件是不会执行的

           我们组件调用最终渲染是渲染template

           如果我们需要让事件执行的话就在后面加上一个

            .active就能让这个时间绑定到这个组件的根元素上

        -->

       <l-p@click.native="fn1"v-if="isShow"></l-p>

       <l-c@click="fn2"@keyup="fn2"></l-c>


   </div>

</body>

</html>

<scriptsrc="../js/vue.js"></script>

<script>

   //如何让根组件的方法绑定在子组件的元素上

   // 在元素上添加v-on="$listeners"

   // 在组件的外侧调用事件

   // 作用是在我们调用组件的时候可以给我们的的组件协商一些事件

   // 但是默认这个组件是不会执行的,如果我们想要他执行,就要给

   // 这个事件加上.native的属性,这个事件是我们绑定在根元素上的事件

   // 如果我们需要将这个事件绑定在元素上的时候,.active就不能绑定

   // 就需要使用v-on="$listeners",他里面的内容就是你在组件调用的时候

   // 定义的事件

   Vue.component('l-c', {

       template:`

            <div style="width:100px;height:100px;border:1px solid #000;">

                <input type="text" v-on="inputEvent" />

                <button @click="$listeners.click">我要调用fn2</button>

            </div>

        `,

       computed: {

           //第一个参数空对象,根元素的事件对象,自己组件的事件

           inputEvent() {

               returnObject.assign({},this.$listeners, {

                   'keydown': ()=>{

                       this.fn1();

                    }

                })

            }

        },

     methods:{

         fn1(){

             console.log("我是自己定义的fn1")

          }

      },

       mounted() {

           console.log(this.$listeners)

        }

    });

   Vue.component('l-p', {

       template:`

        <div>

            <h1 @click.stop="fn1">我是l-p的组件</h1>   

        </div>

       `,

       methods: {

           fn1() {

               alert("我是l-p自己的方法,我用了阻止")

            }

        }

    });

   varvm=newVue({

       el:'#app',

       data: {

           isShow:true

        },

       methods: {

           fn1() {

               this.isShow=false;

            },

           fn2() {

               console.log("点击到了l-c的根元素上")

            }

        }

    })

</script>

2.sync修饰符

<body>

   <divid="app">

       <!--这种操作有些复杂,需要同过$emit自定义事件去触发-->

       <!-- <l-p :msg="msg"  @update="msg=$event"></l-p> -->

       <!--

           提供了一个灵活的sync的修饰符,也是相当于一个语法糖

           完成了双向的一个数据传递

         -->

        <l-p:msg.sync="msg"></l-p>

        <!--单项传递数据-->

        <!-- <input type="text" v-model="msg"> -->

        <!--双向数据绑定-->

        <!--

            页面刷新不存在了,如果要保存数据需要本地数据或者是保存到数据库

          -->

        <inputtype="text"placeholder="用户名"v-model="username">

        <inputtype="password"placeholder="密码"v-model="password">

        <button@click="fn1">提交</button>

   </div>

</body>

</html>

<scriptsrc="../js/vue.js"></script>

<script>

Vue.component('l-p', {

   props: ['msg'],  

   template:`

        <h1 @click="fn1">{{ msg }}</h1>  

       `,

   methods: {

        fn1(){

          this.$emit('update:msg','王五')

        }

    }

   })


   varvm =newVue({

       el:'#app',

       data:{

           msg:"我的天",

           username:localStorage.getItem('username')||"",

           password:"",

        },

       methods:{

            fn1(){

               localStorage.setItem('username',this.username);

            }

        }

    })

</script>

3.slot插槽,以及插槽作用域

<body>

   <divid="app">

       <!--

            template在标签里面使用就是一个默认

           提供的内置组件

           在组件里使用就是一个模板

         -->

        <!--

            编译作用域

             1.组件没有作用域链,组件只能调用自己的数据没有就会报错

             2.父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

          -->

       <base-layout>

           <template>

               <divslot="header">我是头部</div>

               <div>我是二级头部</div>

           </template>

           <div>我是内容</div>

           <!-- <div slot="footer">我是底部</div> -->

       </base-layout>

   </div>

</body>

</html>

<scriptsrc="../js/vue.js"></script>

<script>

Vue.component('base-layout', {

       template:`

        <div>

          <header>

                <slot name="header"></slot>

            </header>

            <section>

                <slot></slot>

            </section>

            <footer>

                <!--默认内容可以直接在插槽中写就好了-->

                <slot name="footer">

                   我是底部的默认内容   

                </slot>

            </footer> 

        </div>

       `

    })

   varvm =newVue({

       el:'#app',

       data:{

           msg:'编译作用域'

        }

    })

</script>

4.slot插槽,结构赋值

<body>

   <divid="app">

       <l-p>

           <!--

                 slot-scope="prop"

                得到的是一个对象

                只想输出一个的时候可以{{ prop.s }}

                按照对象使用即可

                这就是作用域插槽

                可以把组件的数据放出来个大家使用

             -->

            <h1slot-scope="prop">我是一个l-p组件的插槽内容{{ prop.s }}</h1>

            <!--

                结构赋值

                用法

              -->

             <h1slot-scope="{ h }">我是一个l-p组件的插槽内容{{ h }}</h1>

       </l-p>

   </div>

</body>

</html>

<scriptsrc="../js/vue.js"></script>

<script>


Vue.component('l-p', {

        data () {

           return{

           title:'我的天'       

          }

        },

       template:`

            <div>

                <!--

                   我们直接绑定插槽是拿不到这个title中的值

                   我们需要在页面标签上插入slot-scope="prop"

                   在需要渲染的地方输出{{ prop }}  

                -->

                <slot h="title" s="hahahaha"></slot>

            </div>


        `

    })

   varvm =newVue({

       el:'#app'

    })

</script>

5.动态组件keep-alive

<body>

   <divid="app">

       <button@click="curPage='l-home'">首页</button>

       <button@click="curPage='l-list'">列表</button>

       <button@click="curPage='l-about'">关于</button>

       <!--

           动态组件

           组件动态切换会使组件被销毁,再次会出现重建

           如果想实现缓存组件的话,就只需要keep-alive内置组件

           作为容器将他们给包括起来。

           还可以配置三个组件

            include -字符串或正则表达式。只有名称匹配的组件会被缓存。

            exclude -字符串或正则表达式。任何名称匹配的组件都不会被缓存。

            max -数字。最多可以缓存多少组件实例。(:max="2")

         -->

       <keep-alive>

               <component:is="curPage"></omponent>         

       </keep-alive>

   </div>

</body>

</html>

<scriptsrc="../js/vue.js"></script>

<script>

Vue.component('l-home', {

        data () {

           return{

               name:'张胜男'     

            }

        },

       template:`

            <div style="border:1px solid #000;width:400px;height:400px;overflow:auto">

               我是首页   

                <div style="height:4000px;">

                    {{ name }}


                    <button @click='name="张三"'>修改名字</button>

                </div>

            </div>

        `,

        created () {

            console.log("我回来啦")

        }

        ,

        beforeDestroy () {

            console.log('啊!!~~啊~~~aaa~~~我被销毁了')

        },


       //如果做了缓存之后会多两个生命周期函数

        activated () {

           //激活缓存,并显示

            console.log("activated")

        },

         deactivated () {

           //被缓存,并且隐藏

             console.log('deactivated');

         }

    })

Vue.component('l-list', {

       template:`

            <div>

               我是列表页 

            </div>

        `

    })

Vue.component('l-about', {

       template:`

            <div>

               我是关于页

            </div>

        `

    })

   varvm =newVue({

       el:'#app',

       data:{

           curPage:"l-home"

        }

    })

</script>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345