Vue学习笔记——基础语法之组件化开发

    技术2026-10-08  4

    Vue学习笔记——基础语法之组件(Component)

    目标:

    能够知道组件化开发思想能够知道组件的注册方式能够说出组件间的数据交互方式 ▲能够说出组件插槽的用法能够说出Vue调试工具的用法能够基于组件的方式实现业务功能

    1. 组件化开发思想——自定义标签

    Web Components 通过创建 封装好功能的定制元素(自定义标签)解决问题组件可以扩展 HTML 元素,封装可重用的代码

    2. 组件注册

    2.1 全局注册

    语法:

    Vue.component( ‘组件名称’,{ data:组件数据,——是一个函数 function(){ return { } } template:组件模板内容——是字符串,字符串当中可以写vue所支持的模板语法 })

    例子:

    <body> <div id="app"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> //注册组件 Vue.component('button-counter',{ data: function(){ return { count:0 } }, //template:'<button @click="count++">点击了{{count}}次</button>', 这种也可以 template:'<button @click="handle">点击了{{count}}次</button>', //这里也是可以有methods的 methods:{ handle:function(){ this.count+=2; } } }) var vm = new Vue({ el:'#app', data:{ }, }) </script>

    2.2 组件注册注意事项

    data必须是一个函数, 同时这个函数要求返回一个对象组件模板内容必须是单个根元素(很多内容的时候你一开始先用个div包一下就好了其实)

    template:’<button @click=“handle”>点击了{{count}}次< /button>< button>测试< /button> ’ 这样会报错,它们两个是兄弟关系,得在外层加个div才不会报错

    组件模板内容可以是模板字符串的形式(可读性)命名格式 如果使用驼峰式命名组件,那么使用组件的时候,只能在字符串模板中用驼峰的方式使用组件,在普通的标签模板中,必须使用短横线的方式使用组件(所有单词都小写,每个单词之间用短横线连接)

    2.3 局部组件注册

    只能在当前注册它的vue实例中使用组件的内容可以抽取到一个对象当中

    例子:

    <body> <div id="app"> <component-tom></component-tom> <component-a></component-a> <component-lili></component-lili> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> //组件的内容可以抽取到一个对象当中 var componentA = { data:function(){ return { msg:'HelloWorld' } }, template:'<div>{{msg}}</div>', } var componenttom = { data:function(){ return { msg:'i am tom' } }, template:'<div>{{msg}}</div>', } var vm = new Vue({ el:'#app', data:{ }, components:{ 'component-a':componentA, //组件的内容可以抽取到一个对象当中 'component-tom':componenttom, } }) </script>

    组件名还是有加 ’ ’ 的

    3. 组件间数据交互

    3.1 父组件向子组件传值

    在父组件中,直接通过属性的静态方式或动态绑定的属性值的方式传递给子组件,然后子组件通过props接收属性名来接收

    父组件通过属性将值传递给子组件

    < component-test title=‘来自父组件的值’>< /component-test> < component-test :title=‘trans’ multi=‘nihao’>< /component-test>

    子组件内部通过props接收传递过来的值

    Vue.component(‘component-test’,{ props:[‘title’,‘multi’], data:function(){ return { zmsg:‘子组件本身的数据’ } }, template:’< div>{{zmsg + “----------”+ title + “--------”+multi}}< /div>’ })

    props属性命名规则:

    在props中使用驼峰形式,普通模板中需要使用短横线的形式,而在字符串形式的模板中没有这个限制

    3.2 子组件向父组件传值 ▲只能多悟几遍

    子组件触发一个自定义事件,父组件去监听这个自定义事件

    子组件通过自定义事件向父组件传递信息 $emit(‘自定义事件的名称’,需要传递的数据)触发事件父组件用v-on 监听子组件的事件,接收子组件传递过来的内容($event) <cart-list :list='list' @cart-del='delCart($event)'></cart-list>

    看回放叭

    3.3 兄弟之间的传递

    需要借助事件中心管理组件间的通信

    var hub = new Vue( );

    监听事件与销毁事件

    hub.$on(‘监听的事件名称’,()=>{});

    hub.$off(‘监听的事件名称’);

    触发事件

    hub.$emit( '方法名‘,传递的数据)

    组件内部什么时候去监听事件呢? mounted钩子函数什么时候触发? 点击按钮的时候触发对应的事件 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <div>{{fmsg}}</div> <test-tom></test-tom> <test-jerry></test-jerry> <button @click='handle'>销毁事件</button> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> //事件中心 var hub = new Vue(); Vue.component('test-tom',{ data:function(){ return { num:0 } }, template:` <div> <div>TOM:{{num}}</div> <div> <button @click='handle'>点击</button> </div> </div> `, methods:{ handle:function(){ // 触发兄弟组件的事件 hub.$emit('jerry-event',2); } }, mounted:function(){ hub.$on('tom-event',(val)=>{ this.num+=val; }) } }); Vue.component('test-jerry',{ data:function(){ return { num:0 } }, template:` <div> <div>JERRY:{{num}}</div> <div> <button @click='handle'>点击</button> </div> </div> `, methods:{ handle:function(){ // 触发兄弟组件的事件 hub.$emit('tom-event',1) } }, mounted:function(){ hub.$on('jerry-event',(val)=>{ this.num += val; }) } }); var vm = new Vue({ el:'#app', data:{ fmsg:'父组件', }, methods:{ handle:function(){ hub.$off('tom-event'); hub.$off('jerry-event'); } } }) </script> </body> </html>

    4. 组件插槽

    组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力插槽内可以包含任何模板代码,包括HTML组件标签中的内容会传递给slot (如果没有slot,在组件标签中写了内容也不会显示)

    4.1 匿名插槽

    <div id="app"> <alert-box>你好哇</alert-box> <alert-box></alert-box> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> Vue.component('alert-box',{ // ① 当组件渲染的时候,这个slot元素将会被替换为组件标签中嵌套的内容 // ② 插槽内可以包含任何模板代码,包括 HTML template:` <div> <strong>ERROR:</strong> <slot>默认内容</slot> </div> `, }) var vm = new Vue({ el:'#app', data:{ } }) </script>

    4.2 具名插槽

    具名插槽的渲染顺序,完全取决于模板,而不是取决于父组件中元素的顺序。 (下面代码就不是按顺序写的,但是渲染的时候是按模板顺序渲染) <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="app"> <alert-box> <div>主要内容1</div> <div>主要内容2</div> <h1 slot="header">标题内容</h1> <p slot="footer">底部内容</p> </alert-box> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> Vue.component('alert-box',{ template:` <div> <header> <slot name='header'></slot> </header> <main> <slot> </main> <footer> <slot name='footer'></slot> </footer> </div> `, }) var vm = new Vue({ el:'#app', data:{ } }) </script> </body> </html>

    4.3 作用域插槽

    父组件对子组件加工处理 (从父组件中获取到一些子组件的数据,获取数据的方式就是通过slot-scope=‘slotProps’来得到,它当中得到的值就是在子组件slot属性中所绑定的,它对应的值会被父组件获取到)

    例子: 父组件动态控制哪一种水果高亮 (因为子组件一旦封装好后,后期就很少在动了,所以最好有一种办法,从父组件可以直接去决定,这就是作用域插槽所解决的问题) 这个列表数据是通过动态遍历的方式生成的 所以我们需要提供对应数据。 对于数据来说,我们一般是通过父组件传递过来的,所以 ①在父组件中要提供一份水果列表的数据。②父组件通过属性绑定的方式传递给子组件 ③子组件通过props接收,然后遍历

    <div id="app"> <fruit-list :list='list'> <!-- 通过插槽传递过来的属性 子组件通过属性名传递过来数据--> <template slot-scope='slotProps'> <strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong> <span v-else>{{slotProps.info.name}}</span> </template> </fruit-list> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> 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> `, }) var vm = new Vue({ el:'#app', data:{ list:[{ id:1, name:'pear', },{ id:2, name:'orange', },{ id:3, name:'strawberry' }] } }) </script>

    首先,在子组件的模板当中要提供一个插槽,slot中间填充我们要显示的数据,并且slot标签当中要绑定一个属性,(属性名字自定义,用来提供给父组件。属性值是你要操作的数据) 然后,从父组件的角度:要填充slot。 填充规则:在组件标签的中间提供内容,这个内容用< template>标签进行包裹,并且通过template的一个属性:slot-scope来得到子组件中传递过来的数据,数据得到后就可以进行一些控制了

    Processed: 0.012, SQL: 9