文末有我看的这个视频的链接。
目录
组件注册
全局注册
全局注册的组件可以在注册后用于任意实例或者组件中
Vue.component('组件名',{/*选项对象*/})
全局注册必须设置在跟Vue实例之前
实例
<div id="root"> <input-search></input-search> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('input-search',{ template:' <input class="control" type="text" placeholder="请输入要搜索的关键字">' }) const vm = new Vue({ el:'#root', data(){ return{ } } }) vm.$mount('#root') </script>
组件基础
组件命名规则
- kebab-case:'my-component'
- PascalCase:'MyComponent'
Vue.component('my-component-a',{/**/}) Vue.component('MyComponentB',{/**/})
无论使用哪种命名方式,在DOM中都只有第一种命名方式可以使用
<div id="root"> <input-search></input-search> <just-play></just-play> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('input-search',{ template:' <input class="control" type="text" placeholder="请输入要搜索的关键字">' }) Vue.component('JustPlay',{ template:'<a href="https://mllt.cc">Just play</a>' }) const vm = new Vue({ el:'#root', data(){ return{ } } }) vm.$mount('#root') </script>
template选项
该选项用于设置组件的结构,最终被引入根实例或者其他组件中
单项数据流
父子组件间所有prop数据应当存储在data中后操作
<div id="root"> <my-component :initial-title="title"></my-component> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('my-component',{ props:['initialTitle'], template:` <div>{{title}}</div> `, data(){ return { title:this.initialTitle } } }); const vm = new Vue({ el:'#root', data(){ return{ title:"Just Play?" } } }) vm.$mount('#root') </script>
<div id="root"> <my-component :initial-title="title"></my-component> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('my-component',{ props:['initialTitle'], template:` <div>{{title}} <button @click="fn">按一下</button> </div> `, data(){ return { title:this.initialTitle } }, methods:{ fn(){ console.log(this); this.title="It's new title" } } }); const vm = new Vue({ el:'#root', data(){ return{ title:"Just Play?" } } }) vm.$mount('#root') </script>
如果prop为数组或对象时,子组件操作将会影响到父组件的状态
<div id="root"> <my-component :initial-title="title" :obj="obj"></my-component> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('my-component',{ props:['initialTitle','obj'], template:` <div>{{title}} <button @click="fn">按一下</button> </div> `, data(){ return { title:this.initialTitle } }, methods:{ fn(){ console.log(this); // this.title="It's new title" this.obj.name="萌狼蓝天"; } } }); const vm = new Vue({ el:'#root', data(){ return{ title:"Just Play?", obj:{ name:"xiaoming", age:18, } } } }) vm.$mount('#root') </script>
data选项
data选项用于存储组件的数据,与根实例不同,组件的data选项必须为函数,数据设置在返回值对象中
<div id="root"> <my-com-a></my-com-a> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('MyComA',{ template:` <div> <h3>{{title}}</h3> <p>{{content}}</p> </div> `, data(){ return{ title:'Biao ti ya', content:"nei rong ya" } } }) const vm = new Vue({ el:'#root', data(){ return{ } } }) vm.$mount('#root') </script>
这种喷那个实现方式为了确保每个组件实例可以维护一份被返回对象的独立拷贝,不会相互影响
局部注册
局部注册的组建只能用在当前实例或组件中
<div id="root"> <my-com-a></my-com-a> <my-com-b></my-com-b> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 const vm = new Vue({ el:'#root', data(){ return{ } }, components:{ 'MyComA':{ template:` <div> <h3>{{title}}</h3> <p>{{content}}</p> </div> `, data(){ return{ title:'Biao ti ya', content:"nei rong ya" } } }, 'MyComB':{ template:` <div> <h3>{{title}}</h3> <p>{{content}}</p> </div> `, data(){ return{ title:'Biao ti ya2', content:"nei rong ya2" } } }, } }) vm.$mount('#root') </script>
单独配置组件的选项对象
var MyComponentA={/*……*/} var MyComponentB={/*……*/} new Vue({ el:'#app', components:{ 'my-component-a':MyComponentA, 'my-component-b':MyComponentB, } });
ES6对象属性简写
new Vue({ el:'#app', components:{ MyComponentA, MyComponentB } });
<div id="root"> <my-com-a></my-com-a> <my-com-b></my-com-b> </div> <script> Vue.config.productionTip = false //隐藏控制台提示 var MyComA = { template: ` <div> <h3>{{title}}</h3> <p>{{content}}</p> </div> `, data() { return { title: 'Biao ti ya', content: "nei rong ya" } } }; var MyComB = { template: ` <div> <h3>{{title}}</h3> <p>{{content}}</p> </div> `, data() { return { title: 'Biao ti ya2', content: "nei rong ya2", } } }; const vm = new Vue({ el: '#root', data() { return {} }, components: { 'MyComA': MyComA,//写法1 MyComB,//写法2 } }) vm.$mount('#root') </script>
<div id="root"> <!-- 静态属性设置 --> <my-component-a title="静态标题" content="静态内容" ></my-component-a> <!-- 动态属性绑定 --> <my-component-a v-bind:title="'zhe shi jing tai biao ti'" :content="'zhe sh jing tai nei rong'" ></my-component-a> <!-- 动态属性绑定常用操作 --> <my-component-a :title="item.title" :conent="item.content" ></my-component-a> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 //创建子组件 Vue.component('my-component-a',{ props:['title','content'], template:` <div> <h3>{{title}}</h3> <p>{{content}}</p> </div> ` }) const vm = new Vue({ el:'#root', data(){ return{ item:{ title:'Biaoti', content:'neirong', } } } }) vm.$mount('#root') </script>
组件通信
在组件间传递数据的操作,称为组件通信
父组件向子组件传值
组件传值
通过子组件的props选项接收父组件的传值
Vue.component('my-component',{ props:['title'], template:'<h2>{{title}}</h2>' })
注意:props不要与data存在同名属性
父组件设置如下
<div id="app"> <my-component title="例1"></my-component> <my-component :title="例2"></my-component> <my-component :title="item.title"></my-component> </div>
new Vue({ el:'#app', data:{ item:{ title:'父组件中的数据' } } })
Props命名规则
建议prop命名使用cameCase,父组件绑定时使用kebab-case
<div id="root"> <my-component :item-title='item.title' :item-content="item.content" ></my-component> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('my-component',{ props:['itemTitle','itemContent'], template:` <div> <h3>{{itemTitle}}</h3> <p>{{itemContent}}</p> </div> ` }) const vm = new Vue({ el:'#root', data(){ return{ item:{ title:'Biao Ti is', content:'Nei Rong is' } } } }) vm.$mount('#root') </script>
练习:通过v-for创建组件
<div id="root"> <!-- 通过v-for遍历数据items,创建组件并生成内容 --> <demo-item v-for="item in items" :item-title="item.title" :item-content="item.content" :key = "item.title" :item="item" ></demo-item> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('demoItem',{ props:['itemTitle','itemContent','item'], template:` <div> <h3>{{itemTitle}}</h3> <p>{{itemContent}}</p> </div> ` }) const vm = new Vue({ el:'#root', data(){ return{ items:[ { title:'Biao Ti is', content:'Nei Rong is' }, { title:'Biao Ti is2', content:'Nei Rong is2' }, { title:'Biao Ti is3', content:'Nei Rong is3' } ] } } }) vm.$mount('#root') </script>
子组件向父组件传值
组件传值
子向父传值需要通过自定义事件实现
例如:商品为子组件,购物车为父组件,父组件需要统计商品个数,就需要在子组件个数变化时传值给父组件。
<div id="root"> <product-item v-for="product in products" :key = "product.id" :title="product.title" ></product-item> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('ProductItem',{ props:['title'], template:` <div> <span>商品名称:{{title}},商品个数:{{count}}</span> <button @click="countIns">+1</button> <button @click="countInsf">-1</button> </div> `, data(){ return{ count:0 } }, methods:{ countIns(){ this.count++; }, countInsf(){ if(this.count<=0) alert("已经清空啦") else this.count--; }, } }) const vm = new Vue({ el:'#root', data(){ return{ products:[ { id:1, title:'苹果11斤' }, { id:2, title:'香蕉12斤' }, { id:3, title:'橙子13斤' }, ], totalCount:0 } } }) vm.$mount('#root') </script>
子组件数据变化时,通过$emit()
触发自定义事件
Vue.component('product-item',{ …… methods:{ countIns(){ this.$emit('count-change'); this.count++; } } });
自定义事件名称建议使用kebab-case
父组件监听子组件的自定义事件,并设置处理程序
<div id="app"> …… <product-item …… @count-change = "totalCount++" ></product-item> …… </div>
<div id="root"> <product-item v-for="product in products" :key = "product.id" :title="product.title" @count-change-add="totalCount++" @count-change-jianshao="totalCount--" ></product-item> <p>商品总数为:{{totalCount}}</p> </div> <script> Vue.config.productionTip=false//隐藏控制台提示 Vue.component('ProductItem',{ props:['title'], template:` <div> <span>商品名称:{{title}},商品个数:{{count}}</span> <button @click="countIns">+1</button> <button @click="countInsf">-1</button> </div> `, data(){ return{ count:0 } }, methods:{ countIns(){ this.$emit('count-change-add'); this.count++; }, countInsf(){ if(this.count<=0) alert("已经清空啦") else{ this.$emit('count-change-jianshao'); this.count--; } }, } }) const vm = new Vue({ el:'#root', data(){ return{ products:[ { id:1, title:'苹果11斤' }, { id:2, title:'香蕉12斤' }, { id:3, title:'橙子13斤' }, ], totalCount:0 } } }) vm.$mount('#root') </script>
自定义事件传值
子组件触发事件时可以向父组件传值
非父子组件传值
非父子组件:兄弟组件或完全无关的两个组件
其他通信方式
组件插槽
内置组件
观看的教程链接