87 全局和局部组件, 子父和父子之间的通信 混入 插槽 路飞导航栏
主要内容:
1 全局组件:
a : 定义一个全局组件
Vue.component(
'global-component', {
template: `<div> 注意: template一定要包一层div
<h3>{{wanrong}}</h3>
<h2>{{wanrong}}</h2>
</div>`,
data() {
return {
wanrong: 'hello',
}
}
}
);
2 全局组件的使用的两种方式:
a: 写在实例中:
new Vue({ el: '#app', //如果写在下面, 则找到tmplate标签, 把它当做跟标签.渲染, template:`<global-component></global-component>` })
b : 写在标签里:
<div id="app"> <!--如果写在上面, 则以id为app的div为根标签--> <global-component></global-component> </div>
两种方式的区别: 如果写在实例中, 直接显示组件中的template, 如果写在div中, 多了一个以id为app的div标签
2 局部组件的应用:
a: 先创建一个对象:
let Header = { template:`<h1>{{greeting}}</h1>`, data(){ return{ greeting: 'hello' } } };
b : 为了更加的符合规范, 创建了一个app对象, 作为程序入口
let App = { //3使用子组件 template: ` <div> <app-header"></app-header> </div> ` , //2在父组件中注册子组件 components:{ 'app-header': Header } };
c: 实例
new Vue({ el:'#app', template: `<App></App>`, components:{ App } })
流程:先创建两个对象, Header, App, 然后创建一个Vue实例, 注册组件App作为程序的入口, 为了使程序更加的规范 ,
然后,在实例中使用组件, 接着走到app组件, 在父组件中注册子组件, 使用子组件, 然后找到Header的template渲染.
3 父子组件之间的通信,
a : 父亲传递一个数据给孩子, 孩子接受数据使用props
b : 实例:
<div id="app"></div> <script> //1创建一个obj let Header = { template:`<div> <h1>{{greeting}}</h1> <h2>{{fData}}</h2> </div>`, //在子组件中用props接收父组件传过来的参数 props:['fData'], data(){ return{ greeting: 'hello' }}}; let App = { //3使用子组件 template: ` <div> <app-header v-bind:fData="fatherData"></app-header> </div> ` , //2在父组件中注册子组件 components:{ 'app-header': Header }, data(){ return { fatherData:0 }}}; new Vue({ el:'#app', template: `<App></App>`, components:{ App }}) </script> </body>
4 子父之间的通信,
a : emit触发一个函数的执行, 还可以传参数给父组件, 父组件用于监听,
b : 实例:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="content-Type" charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <script src="static/vue.min.js"></script> </head> <body> <div id="app"> </div> <script> //1创建一个obj let Header = { template: `<div> <h1>hello</h1> <button v-on:click="sonClick">点击让字体变大</button> </div>`, methods: { sonClick: function () { this.$emit('change-Size', 0.1) } } }; let App = { //3使用子组件 template: ` <div> <span :style="{fontSize: postFontsize + 'em '}">春暖花开</span> <app-header v-on:change-Size="fatherClick"></app-header> </div> `, //2在父组件中注册子组件 components: { 'app-header': Header }, data() { return { postFontsize: 1 } }, methods: { fatherClick: function (value) { this.postFontsize += value } } }; new Vue({ el: '#app', template: `<App></App>`, components: { App } }) </script> </body> </html>
5 非父子之间的通信:借助中间调度器 $emit, $on
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="content-Type" charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <script src="../static/vue.min.js"></script> </head> <body> <div id="app"> </div> <script> let hanfei = new Vue(); let maweihua = { template:`<div> <h1>这是马卫华</h1> <button v-on:click="my_click">点我向康神说话</button> </div>`, methods:{ my_click:function () { //向康神说话 //向中间调度器提交事件 hanfei.$emit("maweihua_say", "一起玩") } } }; let kanshen = { template:`<div><h1>这是康神</h1>{{say}}</div>`, data(){ return { say:'' } }, mounted(){ //监听中间调度器的方法 let that = this; hanfei.$on("maweihua_say", function (data) { console.log(data); this.say = data }) } }; const app = new Vue({ el:'#app', components:{ maweihua: maweihua, kanshen: kanshen } }) </script> </body> </html>
6 组件系统之混入:假如两个对象中都用到了一个方法, 可以把这个方法提取出来, 定义一个mixs对在用到的地方: mixins:[mixs]
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="content-Type" charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <script src="static/vue.min.js"></script> </head> <body> <div id="app"></div> // <!--第一版, 因为代码重复, 所以引入了混入--> let mixs = { methods:{ show: function (name) { console.log(name + 1) }, hide: function (name) { console.log(name + 0) } } }; let wanrong = { template:`<div> <button v-on:click="show('wanrong')">点击显示蓉蓉1</button> <button v-on:click="hide('wanrong')">点击显示蓉蓉0</button> </div>`, mixins:[mixs] }; let ningning = { template: `<div> <button v-on:click="show('ningning')">点击显示宁宁1</button> <button v-on:click="hide('ningning')">点击显示宁宁0</button> </div>`, mixins:[mixs] }; let App = { template:`<div> <my-wanrong></my-wanrong> <my-ningning></my-ningning> </div>`, components:{ 'my-wanrong': wanrong, 'my-ningning': ningning } }; new Vue({ el: '#app', template:`<div> <App></App> </div>`, components:{ 'App': App } }) </script> </body> </html>
7组件系统之插槽: 可以放多个标签: <slot></slot>
<script src="static/vue.min.js"></script> <style> .body { margin: 0; } .box { width: 80px; height: 50px; background-color:paleturquoise; float: left; line-height: 50px; } </style> </head> <body> <div id="app" > <global-component>首页</global-component> <global-component>免费课程</global-component> <global-component>轻课</global-component> <global-component>智能题库</global-component> <global-component>学位课程</global-component> <global-component>咨询</global-component> </div> <script> //定义一个全局的组件 //插槽就是可以放多个标签 Vue.component('global-component', { template:`<div class="box"><slot></slot></div>` }); new Vue({ el: '#app', }) </script>
8 组件系统之具名插槽: 为每个插槽起具体的名字
<script src="static/vue.min.js"></script> <style> body { margin:0; } .box { width:80px; height:50px; background-color: paleturquoise; float: left; margin-left: 5px; } </style> </head> <body> <div id="app" > <global-component> <div slot="home">首页</div> <div slot="lightcourse">轻课</div> <div slot="degreecourse">学位课程</div> </global-component> </div> <script> //定义一个全局的组件 Vue.component('global-component', { template:`<div class="box"> <slot name="lightcourse"></slot> <slot name="degreecourse"></slot> <slot name="home"></slot> </div>` }); new Vue({ el: '#app', }) </script>
9 template格式, 就是把对象中的template单独隔离出来,
<body> <div id="app"></div> <template id="header"> <div> <h1>Hello Vue</h1> </div> </template> <script> let Header = { template: '#header' }; new Vue({ el: '#app', template:`<div><app-header></app-header></div>`, components:{ 'app-header': Header } }) </script> </body>
10 组件系统之路飞导航栏
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="content-Type" charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <script src="static/vue.min.js"></script> <!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <style> body { margin: 0; padding: 0; } .header { position: fixed; top:0; left:0; width:100%; } .el-menu { display: flex; align-items: center; justify-content: center; } .footer { position: fixed; bottom:0; left:0; width:100%; } .header img { position: absolute; left: 80px; top: -4px; width:118px; height: 70px; z-index:999 } </style> </head> <body> <div id="app"> </div> <!--导航头--> <template id="header"> <div class="header"> <img src="https://www.luffycity.com/static/img/head-logo.a7cedf3.svg"/> <el-menu :default-active="activeIndex" class="el-menu-demo" mode="horizontal" @select="handleSelect" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">> <el-menu-item index="1">首页</el-menu-item> <el-menu-item index="2">免费课程</el-menu-item> <el-menu-item index="3">轻课</el-menu-item> <el-menu-item index="4">学位课程</el-menu-item> <el-menu-item index="5">智能题库</el-menu-item> <el-menu-item index="6">公开课</el-menu-item> <el-menu-item index="7">内部教材</el-menu-item> <el-menu-item index="8">老男孩教育</el-menu-item> </el-menu> </div> </template> <!--导航尾部--> <template id="footer"> <div class="footer"> <el-menu class="el-menu-demo" mode="horizontal" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">> <el-menu-item index="1">关于我们</el-menu-item> <el-menu-item index="2">联系我们</el-menu-item> <el-menu-item index="3">商业合作</el-menu-item> <el-menu-item index="4">帮助中心</el-menu-item> <el-menu-item index="5">意见反馈</el-menu-item> <el-menu-item index="6">新手指南</el-menu-item> </el-menu> </div> </template> <script> let Header = { template: "#header", data() { return { activeIndex: 0 }; }, methods: { handleSelect(key, keyPath) { console.log(key, keyPath); } } }; let Footer = { template:'#footer', }; new Vue({ el: "#app", template: `<div> <app-header></app-header> <app-footer></app-footer> </div> `, components: { "app-header": Header, 'app-footer': Footer } }) </script> </body> </html>