前端 ---- Vue组件

1.组件的注册 
    也分为全局和局部注册,
    .app也是组件,组件也有父子关系
    模板内容 可以用模板字符串``
    
    1.简单使用:
        <div id="example">
          <!-- 2、 组件使用 组件名称 是以HTML标签的形式使用  -->  
          <my-component></my-component>
        </div>
        <script>
            //   注册组件 
            // 1、 my-component 就是组件中自定义的标签名
            Vue.component('my-component', {
              template: '<div>A custom component!</div>'
            })

            // 创建根实例
            new Vue({
              el: '#example'
            })

        </script>

    
    ···········注意事项·······
        1.组件参数的data值必须是函数同时这个函数要求返回一个对象  
            data一定是函数,这样就可以形成一个闭包的数据
        2.组件模板必须是单个根元素 
        模板必须是单个根元素如:template :'<button @click="handle">点击了{{count}}次</button>',
        3.组件模板的内容可以是模板字符串
        但是如果想要两个button标签的话可以加个div,如这样template :'<div><button @click="handle">点击了{{count}}次</button><button>测试</button></div>',
        4.命名方式:
        Vue.component('my-component'   OR  'MyComponent', { /* ... */ })
        '-'短横线 'hello-world'和驼峰式(大写)'HelloWorld'但是驼峰式只能在字符串模板中`<HelloWorld></HelloWorld>`使用,在普通的标签模板中是错的(即不能在外面直接<HelloWorld></HelloWorld>)
        但是驼峰式的标签HelloWorld,可以直接使用短横线式的来调用<hello-world></hello-world>,反之不行
        -------------所以最好还是短横线吧----------------------

    2.局部组件的注册
          <div id="app">
              <my-component></my-component>
          </div>


        <script>
            // 定义组件的模板
            var Child = {
              template: '<div>A custom component!</div>'
            }
            new Vue({
              //局部注册组件  
              components: {
                // <my-component> 将只在父模板可用  一定要在实例上注册了才能在html文件中使用
                'my-component': Child
              }
            })
         </script>

2.工具调试
3.组件间数据交互

    1.属性名规则
        在props中使用驼峰形式,模板中需要使用短横线的形式
        字符串形式的模板中没有这个限制
        Vue.component(‘menu-item', {
        // 在 JavaScript 中是驼峰式的
        props: [‘menuTitle'],
        template: '<div>{{ menuTitle }}</div>'
        })
        <!– 在html中是短横线方式的 -->
        <menu-item menu-title=“nihao"></menu-item>



    2.属性类型
        1.字符串
        2.数字  传入的时候参数名前要加: 不然传入类型就是string
        3.布尔值 同上
        4.数组 同上
        5.对象 同上
        
	3.父子   props
        - 父组件发送的形式是以属性的形式绑定值到子组件身上。
        - 然后子组件用属性props接收
        - 在props中使用驼峰形式,模板中需要使用短横线的形式字符串形式的模板中没有这个限制
		静态:<menu-item title="来自父组件的数据"></menu-item>
		动态:<menu-item :title="title"></menu-item>
        区别在这个':'  经常忘了,气死了!!!!

        
        props传递数据原则:单向数据流 只能父--->子  但是子组件能修改和操作父组件传递过来的参数
        但是子组件也能向父组件传递信息(父组件中的模板):----->$emit,
        触发事件:
            子: <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button>
            父: <menu-item :parr='parr' @enlarge-text='fontSize += 5'></menu-item>
            父: <menu-item :parr='parr' @enlarge-text='handle'></menu-item>   也可以是方法
        传值: $event
            子:<button @click='$emit("enlarge-text",0.1)'>扩大父组件中字体大小</button>
            父: <menu-item :parr='parr' @enlarge-text='fontSize += $event'></menu-item>
            父: <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item>   也可以是方法

        
        
	4.兄弟
        组件A (监听)<=====>(触发) 事件中心 (触发)<=====>(监听)组件B
        1.单独的事件中心管理组件的通信
        var eventHub = new Vue()
        2. 监听事件与销毁事件
        eventHub.$on('add-todo', addTodo)
        eventHub.$off('add-todo')
        3. 触发事件
        eventHub.$emit(‘add-todo', id)
    
    5.组件插槽的作用
        1. 插槽位置
            Vue.component('alert-box', {
            template: `
            <div class="demo-alert-box">
              <strong>Error!</strong>
              <slot></slot>
            </div>
            `
            })
        2. 插槽内容
            <alert-box>Something bad happened.</alert-box>
        
    6.具名插槽用法
        1. 插槽定义
            <div class="container">
                <header>
                  <slot name="header"></slot>
                  <slot name="header"></slot>
                </header>
                <main>
                  <slot></slot>
                  </main>
                <footer>
                    <slot name="footer"></slot>
                </footer>
            </div>
        2. 插槽内容
            <base-layout>
                <h1 slot="header">标题内容</h1>
                <p>主要内容1</p>
                <p>主要内容2</p>
                <p slot="footer">底部内容</p>
            </base-layout>
    
    7.作用域插槽
        应用场景:父组件对子组件的内容进行加工处理
        1. 插槽定义
        <ul>
            <li v-for= "item in list" v-bind:key= "item.id" >
                <slot v-bind:item="item">
                    {{item.name}}
                </slot>
            </li>
        </ul>
        2. 插槽内容
        <fruit-list v-bind:list= "list">
            <template slot-scope="slotProps">
                <strong v-if="slotProps.item.current">
                    {{ slotProps.item.text }}
                </strong>
            </template>
        </fruit-list>










        
        


		








9.组件插槽
    1.普通插槽
        在模板中设定 Vue.component('alert-box',)template=`<slot></slot>` 然后在父组件中使用<alert-box>插入内容</alert-box>  内容就会传到slot中,如果内容带标签也会把对应标签展示出来
        <slot>默认内容</slot>中可以有默认内容,如果父组件使用<alert-box>却没插入内容,就会在父组件中显示默认内容

    2.具名插槽
        插槽定义:
            Vue.component('base-layout', {
              template: `
                <div>
                  <header>
                    <slot name='header'></slot>
                  </header>
                  <main>
                    <slot></slot>
                  </main>
                  <footer>
                    <slot name='footer'></slot>
                  </footer>
                </div>
              `
            });
        内容:1.
            <base-layout>
              <p slot='header'>标题信息</p>
              <p>主要内容1</p>
              <p>主要内容2</p>
              <p slot='footer'>底部信息信息</p>
            </base-layout>
             2.如果想往同一个name中插入比较多的数据,可以用template
             <base-layout>
              <template slot='header'>
                <p>标题信息1</p>
                <p>标题信息2</p>
              </template>
              <p>主要内容1</p>
              <p>主要内容2</p>
              <template slot='footer'>
                <p>底部信息信息1</p>
                <p>底部信息信息2</p>
              </template>
            </base-layout>
        结果就是:标签和内容都会过去
            <div>
              <header>
                <p>标题信息</p>
              </header>
              <main>
                  <p>主要内容1</p>
                  <p>主要内容2</p>
              </main>
              <footer>
                <p>底部信息信息</p>
              </footer>
        </div>
        
        
        
        
        


































    3. 插槽作用域
        父组件堆子组件的内容进行加工处理,样式也可以
        插槽模板:子
            Vue.component('fruit-list', {
              props: ['list'],
              template: `
                <div>
                  <li :key='item.id' v-for='item in list'>
                    <slot :info='item'> {{item.name}} </slot> 
                  </li>
                </div>
              `
            });
        插槽内容:父
            <fruit-list :list='list'>
                <template slot-scope='slotProps'>
                  <strong v-if='slotProps.info.id==2'>{{slotProps.info.name}}</strong>
                  <span v-else>{{slotProps.info.name}}</span>
                </template>
            </fruit-list>



案列:购物车
1.event
    <input type="text"  :value='item.num' @blur='change(item.id, $event)'/>
    函数可以通过可以通过event来获得Input栏的值
    changeNum: function(id, event){
            num=event.target.value
        },

内容:传参、
触发方法:传参
样式:插槽作用域

posted @ 2020-09-21 10:33  otome  阅读(177)  评论(0编辑  收藏  举报