Vue:组件
组件
通常一个应用会以一棵嵌套的组件树的形式来组织:

例如,你可能会有页头、侧边栏、内容区等组件,每个组件又包含了其它的像导航链接、博文之类的组件。
为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。
一、局部组件
1、什么是局部组件?
局部组件,只能在局部使用,如果想要在其他组件中使用,需要挂载。
let APP = {
}
2、局部组件的使用?
声明,挂载,使用((局部组件需要挂载之后才能使用))
打油诗: 声子 挂子 用子 (声子:创建组件,挂子:在父组件挂载创建的字组件,用子:在父组件template中使用子组件中的东西)
<body> <div id="app"> {{ msg }} </div> <script src="../vue.js"></script> <script> ------------------------------------子组件------------------------------------------------------------ //如果仅仅是实例化vue对象中 既有el 又有template,如果template中定义模板的内容 // 那么template模板的优先级大于el // 1.声子(创建子组件,相当于自定义的标签) Vue中 组件的名字 首字母要大写 跟标签区分 组件中的data必须是个函数 一定要有返回值 (注意子组件没有el,其它都有) let App = { data(){ //数据属性 return{
msg:'chen'
} //一定要有return }, //template相当于表示自定义组件(标签)的具体功能 template:` <div id="a"> <h2>{{ msg }}</h2> </div> `, methods:{ // }, }; ------------------------------根VUE------------------------------------------------------ new Vue({ el:'#app', data(){ return{ msg:'alex' } }, //3 使用子组件。template渲染整个子组件(相当于自定义一个标签),template定义模板的内容 template:` <div class="app"> <App/> </div> `, //这里注意:template里面所有的内容在一个div内(闭合标签包裹起来);否则会报错:Component template should contain exactly one root element components:{ //components字面意思:组件们 //2.挂子组件 //如果key和value一样 可以只写一个 //App:App App } }) </script> </body>
注意:
1)第三步,用子,也可以在el中绑定的元素标签中,直接使用子组件。
2)子组件中的template必须得使用,不然会有报错的,因为不用template就无法知道子组件的结构,根vue里的template可以不用,因为可以直接放在el绑定的标签里面
二、全局组件
1、什么是全局组件?
全局组件可以再任意组件中使用
Vue.component("组件名",{
})
2、全局组件的使用
先声明创建,不需要挂载,在其他组件中直接使用
<slot></slot> 是Vue的内置组件,
<Vbtn>登录</Vbtn> 中的文字会代替<slot></slot>
<div id="app"> <App></App> <Vbtn></Vbtn> </div> <script src="../vue.js"></script> <script> ----------------------全局子组件------------------------------------------------ //全局组件:第一个参数是组件的名字,第二个参数 options参数 它是全局组件 Vue.component('Vbtn',{ data(){ return{ } }, template:`<button> <slot></slot> //设置<slot>可以先占位,以后使用全局组件时,<Vbtn>d注册<Vbtn>,那么'注册'会代替<slot>。如果没有事先设置的话,那么即便写了注册,也不能更改<button>中的内容 </button> `, }); ---------------------局部子组件-------------------------------------------------------- //如果仅仅是实例化vue对象中 既有el 又有template,如果template中定义模板的内容 // 那么template模板的优先级大于el let Vheader = { data(){ return{} }, template:` <div> <h2>alex</h2> <Vbtn>登录</Vbtn> //使用,之所以写登录有用,是因为全局组件<Vvbtn>中设置了<slot> </div> `, }; -------------------------局部子组件--------------------------------------------------------- // 1.声子(创建子组件,相当于自定义的标签) Vue中 组件的名字 首字母要大写 跟标签区分 组件中的data必须是个函数 一定要有返回值 (注意没有el,其它都有) let App = { data(){ //数据属性 return{} }, //template相当于表示自定义组件(标签)的具体功能 template:` <div id="a"> <!--<h2>我是lilz</h2>--> <Vheader/> <Vbtn></Vbtn> </div> `, methods:{ // }, components:{ Vheader } }; ------------------------根vue-------------------------------------------------- new Vue({ el:'#app', data(){ return{ msg:'alex' } }, components:{ //字面意思:组件们 //2.挂子组件 //如果key和value一样 可以只写一个 //App:App App } }) </script>
组件的嵌套
数据,数据是单向数据流的,因此组件之间存在着嵌套关系
组件传值
组件之间不管是全局组件还是子组件,都有可能是父组件或子组件
一、父组件向子组件传值(props)
子组件使用父组件中的数据,也就是父组件往子组件中传值
<div id="app"> <App></App> </div> <script src="../vue.js"></script> <script> ------------------------------------子组件------------------------------------------------------------------- let Vheader = { data(){ return{} }, //1.在子组件中声明一个props,挂载父组件中的属性,就可以在模板中使用 props:['msg','post'], template:` <div> <h2>alex</h2> <h2>{{ msg }}</h2> <h2>{{ post.title }}</h2> </div> `, }; ------------------------------------父组件-------------------------------------------------- let App = { data(){ //数据属性 return{ text:"我是父组件中的数据", post:{ id:1, title:'my book' } } },
//2.绑定自定义属性msg(必须与子组件中的名字相同) template:` <div id="a"> <Vheader :msg = 'text' :post = 'post'></Vheader> </div> `, methods:{ }, components:{ Vheader } }; ---------------------------------------------------------------------------------------------- new Vue({ el:'#app', data(){ return{ msg:'alex' } }, components:{ //字面意思:组件们 //2.挂子组件 //如果key和value一样 可以只写一个 //App:App App } }) </script>
二、子组件往父组件中传值($.emit)
<div id="app"> <App></App> </div> <script src="../vue.js"></script> <script> --------------------子组件:VBtn----------------------------------------------------------- Vue.component('VBtn', { data() { return {} }, template: ` <button @click = 'clickHandler1'>{{ id }}</button> 一:点击按钮,调用clickHandler1方法 `, props: ['id'], methods: { clickHandler1() { this.id ++, //1.子组件 this.$emit('父组件中声明的自定义的事件','传值') 触发参数一的事件 this.$emit('clickHandler2',this.id) 二:调用clickHandler1方法执行$emit事件,触发父组件的clickHandler2点击事件,携带值 } }, }); ---------------------VBtn组件的父组件:Vheader-------------------------------------------------------------------------------------- let Vheader = { data() { return {} }, //1.在子组件中声明一个props,挂载父组件中的属性,就可以在模板中使用 props: ['msg', 'post'], template: ` <div> <h2>alex</h2> <h2>{{ msg }}</h2> <VBtn :id = 'post.id' @clickHandler2 = 'clickHandler3'></VBtn> 三:父组件中clickHandler2事件调用clickHandler3方法 </div> `, //2.clickHandler2 自定义监控的事件,调用clickHandler3方法 methods:{ clickHandler3(value){ alert(value); this.$emit('fatherHandler1',value) 四:该方法获取到子组件中传递的值 } } }; ------------------Vheader组件的父组件----------------------------------------------------------------------------- let App = { data() { //数据属性 return { text: "我是父组件中的数据", post: { id: 1, title: 'My Journey with Vue' } } }, template: ` <div id="a"> <div>{{ post.id }} </div> <Vheader :msg = 'text' :post = 'post' @fatherHandler1="fatherHandler2"></Vheader> </div> `, //2.绑定自定义属性msg(必须与子组件中的名字相同) methods: { fatherHandler2(value){ this.post.id = value; } }, components: { Vheader } }; new Vue({ el: '#app', data() { return { msg: 'alex' } }, components: { //字面意思:组件们 //2.挂子组件 //如果key和value一样 可以只写一个 //App:App App } }) </script>
三、平行组件之间传值( $.on $.emit)
首先声明一个公交车 vue 对象
$.emit:将数据放到公交车上
$.on:接收公交车上的数据
<div id="app"> <App></App> </div> <script src="../vue.js"></script> <script> let bus = new Vue(); 公交车(通过公交车传送数据) ---------------------------平行组件Test2------------------------------------------------------------- // 这里我们可以看到Test和Test2是平行组件 // Test==传值===》Test2 ;那么Test2要声明事件 :$on('声明的事件的名字',function(val){}) ; Test要触发事件$emit('Test2组件中声明的事件名','要传的值') // // 前提:这两个方法必须绑定在同一个实例化对象(bus对象) Vue.component('Test2',{ data(){ return{ text:'', //Test2组件数据是空的 } }, template:` <div> <h2>{{ text }}</h2> </div> `, methods:{ }, created(){ bus.$on('testDate', (val)=> { alert(val); this.text = val; //当另一个平行组件传值过来的时候,这里接受到数据,要使用箭头函数 }) } }); -------------------------平行组件Test--------------------------------------------------------------------------- Vue.component('Test',{ data(){ return{ msg:'我是test组件的数据', } }, props:['txt'], template:` <div> <button @click = 'clickHander'>{{ txt }}</button> //我们点击这个按钮是调用下面的方法 </div> `, methods:{ clickHander(){ bus.$emit('testDate',this.msg) //触发事件,把数据放在bus公交车上 } } }); -------------------------------------------------------------------------------------------- let Vheader = { data(){ return{ txt:'wusir' } }, template:` <div class="header"> <Test :txt = 'txt'></Test> <Test2></Test2> </div> `, //这里可以看出Test和Test2组件是平行组件 }; let App = { data(){ return{ } }, template:` <div class="app"> <Vheader></Vheader> </div> `, components:{ Vheader }, }; new Vue({ el:'#app', data(){ return{ } }, components:{ App } }) </script>

浙公网安备 33010602011771号