组件化开发
组件模块的分离
<div id="app"> <cpn></cpn> </div> <!-- 第1个方法.script标签类型必须是type="text/x-template" --> <!-- <script type="text/x-template" id="cpn"> --> <!-- 组件写这里更方便 --> <!-- <div> <h2>标题</h2> <p>内容</p> </div> </script> --> <!-- 第2个方法.template标签 --> <template id="cpn"> <div> <h2>标题</h2> <p>内容</p> </div> </template> <script> // 注册一个component全局组件的语法糖更方便,不用创建组件构造器 Vue.component('cpn', { template: '#cpn' }) const app = new Vue({ el: '#app', data: {}, methods: {} }); </script 组件中的data为什么是函数
<script> // 1.注册组件Vue.component('cpn',{ template:'#cpn', // data()必须是个函数,不是函数也会报错, //data:{}这样多个调用都指向一个内存地址一个变一起变, // data()这样每次调用就会有一个新的内存地址,自己改自己的内存东西 // 每一个组件实例都有自己的状态,他都需要一个对象来保存属于自己的状态 data(){ return { counter:0 } }, methods:{ increment(){ this.counter++ }, decrement(){ this.counter-- } }}) </script 组件通信父传子props
<div id="app"> <!-- <cpn v-bind:cmovies="movies" :cmessage="message"></cpn> --> <!-- 这里只负责赋值了,没有输出 --> <cpn v-bind:cmovies="movies" :cmessage="message"></cpn> </div> <!-- 组件模板 --> <template id="cpn"> <!-- 内部代码多必须有个根标签包裹,比如这个div --> <div> <ul> <li v-for="item in cmovies">{{item}}</li> </ul> <h2>{{cmessage}}</h2> </div> </template> <script> //父传子props const cpn = { template: '#cpn', // 一。数组方式 // props:['cmovies','cmessage'], // 二。对象方式 props: { // 1.类型限制 // cmovies:Array, // cmessage:String, // 2.给字符串提供一些默认值 cmessage: { // 类型 type: String, // default当别人没传值的默认值 default: 'aaaaa', // required必须传值 required:true }, // 给数组设置 // 类型是对象或数组时,默认值default必须是一个函数 cmovies:{ type:Array, default(){ return [] } } }, data() { return {} }, methods: { } } // 父组件,实例 const app = new Vue({ el: '#app', data: { message: '你好吖', movies: ['海王', '海贼王', '海尔兄弟'] }, // components注册组件 components: { // 相当于cpn:cpn ,是es6的增强写法 cpn } }); </script 组件通信子传父$emit(发射事件)
<!-- 父组件模板 --> <div id="app"> <cpn @item-click="cpnClick"></cpn> </div> <!-- 子组件模板 --> <template id="cpn"> <div> <button v-for="item in categories" @click="btnClick(item)"> {{item.name}} </button> </div> </template> <script> // 1.子组件 const cpn = { template:'#cpn', data(){ return { categories:[ {id:'aaa',name:'热门推荐'}, {id:'bbb',name:'手机数码'}, {id:'ccc',name:'家用家电'}, {id:'ddd',name:'电脑办公'} ] } }, methods:{ btnClick(item){ //$emit 发射事件:自定义事件 // 子传父就是通过自定义事件传递的 // item-click自定义事件的名字,item自定义事件的参数 this.$emit('item-click',item) } } } // 2.父组件 const app = new Vue({ el: '#app', data: {}, methods: { cpnClick(item){ // 获取到了子组件cpn里的对象属性 console.log(item); } }, components:{ cpn } }); </script 组件访问父访问子
<div id="app"> <cpn></cpn> <cpn ref="aaa"></cpn> <button @click="btnClick">按钮</button> </div> <template id="cpn"> <div> 我是子组件 </div> </template> <script> const app = new Vue({ el: '#app', data: {}, // methods装函数 methods: { btnClick(){ // 2.$refs是对象类型,默认是一个空的对象,必须在组件上加 ref='bbb' ,一般用这个 直接锁定元素 console.log(this.$refs.aaa.name); } }, // components注册组件 components:{ cpn:{ template:'#cpn', data(){ return { name:'我是子组件的name' } }, methods:{ showMessage(){ console.log('showMessage'); } } } } }) 组件访问子访问父
<div id="app"> <cpn></cpn> </div> <template id="cpn"> <div> <h2>我是cpn组件</h2> <ccpn></ccpn> </div> </template> <template id="ccpn"> <div> <h2>我是子组件</h2> <button @click="btnClick">按钮</button> </div> </template> <script> const app = new Vue({ el: '#app', data: {}, // methods装函数 methods: { }, // components注册组件 // 父 components: { cpn: { template: '#cpn', data() { return { name: '我是cpn组件的name' } }, // 子 components: { ccpn: { template: '#ccpn', methods: { btnClick() { // 1.访问父组件$parent ,用的非常少 // console.log(this.$parent); // console.log(this.$parent.name) // 2.访问根组件$root console.log(this.$root); } } } }, } } }); </script 组件化高级
slot插槽的基本使用
<!-- 1.插槽的基本使用 写个空的啥也不加<slot></slot> 2.可以加默认值,<slot>内容</slot> 3.多个值可以同时放到组件一起替换 --> <div id="app"> <cpn></cpn> <cpn><span>我是span</span></cpn> <cpn> <i>我i是</i> <p>我是p</p> </cpn> </div> <template id="cpn"> <div> <h2>我是组件</h2> <p>我是组件的p</p> <slot><button>按钮</button></slot> </div> </template> <script> const app = new Vue({ el: '#app', data: {}, methods: {}, components:{ cpn:{ template:'#cpn' } } }); </script 具名插槽的作用
<div id="app"> <cpn><span slot="center">换的中间</span></cpn> <cpn><button slot="left">换的左边</button></cpn> </div> <template id="cpn"> <div> <!-- 加上name可以指定换那个 --> <slot name="left"><span>左边</span></slot> <slot name="center"><span>中间</span></slot> <slot name="right"><span>右边</span></slot> </div> </template> <script> const app = new Vue({ el: '#app', data: {}, methods: {}, components:{ cpn:{ template:'#cpn', } } }); </script 博主公_号:前端老实人,希望可以认识大家,一起学习哦❤
|