目录
三、局部组件:根组件 components内绑定,只能在相应实例结构内使用。
1 - 父组件 ->子组件(通过props建立联系绑定属性)
一、组件概念
- 组件与实例一一对应,创建一个实例等同于创建了一个组件;创建一个组件等同于创建一个实例。
- 根组件(new Vue())的挂载点是根组件的模板。
- 组件都具有模板(template),根组件的模板是挂载点(el)
- 子组件具有自身模板,且根组件是所有子组件的父级(1级…n级)
- template:模板,替换根组件挂载元素。(内部HTML代码块只能包含一个根节点)
二、根组件
总结:
- 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件)
- 每个组件组件均拥有模板,template
- 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量
- 根组件如果不书写自身模板,那么模板就采用挂载点;如果显式书写模块,就会替换挂载点,但根组件必须拥有挂载点
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>根组件</title> </head> <body> <p>app之上</p> <div id="app"> <h1>{{ msg }}</h1> </div> <p>app之下</p> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> var app = new Vue({ // 根组件的模板就是挂载点 el: "#app", data : { msg: "根组件" }, template: "<div>显式模板</div>" }) // app.$template </script> </html>
三、局部组件:根组件 components内绑定,只能在相应实例结构内使用。
定义: 满足vue语法规则的对象,并且以局部注册,只能在父组件内使用。目的是达到html+css+js的代码复用
总结:
- 局部组件注册 - template:"替换的html语法结构模板"
- 局部组件注册 - data(){ return { template 内需要的参数:对应值 } }: 或者 data: function(){ return { template 内需要的参数:对应值 } }:
- 局部组件注册 - methods:{ template 内所需方法名 () { 方法内执行代码 } }
- 根组件注册 - el:‘css选择器语法’
- 根组件注册 - components:{进行全局属性名:组件名} (components:绑定属性和组件)
设:全局属性名local-tag,组件名localTag
1) "localtag": localTag
2)"localTag": localTag
3)"local-tag": localTag
4) localTag: localTag
5) localTag, (ES6语法,当二者写法相同时,可以省略,建议)注意:html不区分大小写,建议使用链接语法;js语言不支持链接语法,建议使用小驼峰写法;
解决方法:使用下划线连接语法<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>局部组件</title> <style type="text/css"> .sup { width: 100px; height: 100px; background-color: orange; } .sub { width: 100px; height: 100px; background-color: red; border-radius: 50% } </style> </head> <body> <div id="app"> <!-- 错误: html不区分大小写 --> <!-- <localTag></localTag> --> <!-- html中组件命名提倡-的链接语法 --> <!-- <local-tag></local-tag> --> <!-- 1 --> <!-- <localtag></localtag> <localtag></localtag> <localtag></localtag> --> <!-- 2 3 4 5 --> <local-tag></local-tag> <!-- <aaa></aaa> --> <btn-tag></btn-tag> <btn-tag></btn-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 语法规则 // 有自身模板template,有data/methods/computed/watch... var localTag = { template: "<div class='sup'><div class='sub'></div></div>" } // var a = { // template: "<div class='sup'><div class='sub'></div></div>" // } var btnTag = { // template: "<div><button>按钮1</button><button>按钮2</button></div>" template: "<button @click='btnAction'>点击了{{ num }}下</button>", // data需要绑定方法,数据通过方法返回值进行处理,达到组件复用时,数据的私有化 data: function() { return { num: 0 } }, methods: { btnAction: function () { this.num++ } } } // 根组件 new Vue({ el: "#app", // 注册子组件 components: { // 全局变量名:组件名 // 1 // "localtag": localTag // 2 // "localTag": localTag // 3 // "local-tag": localTag // 4 // localTag: localTag // 5 ES6对象语法,key value写法相同,可以省略value localTag, btnTag, // a:aaa, 错 // aaa:a, } }) </script> </html>
三、全局组件:在任意vue实例下都可调用
总结:
- 创建全局组件 - Vue.component("组件名", {}
- 全局组件实例内部 - template:“html语法结构”
- 全局组件实例内部 - data(){return{template所需变量名:值}} 或者 data:function(){return{template所需变量名:值}}
- 全局组件实例内部 - methods:{template所需事件方法名(){}}
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>全局组件</title> </head> <body> <div id="app"> <!-- 遍历渲染出三个组件,三个组件都被覆盖 --> <global-tag v-for="(o, i) in ls" :key="i"></global-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 全局组件 // 用Vue.component("组件名", {})来创建全局组件 // 全局组件附属于Vue实例,可以不需要注册就可以使用 Vue.component("global-tag", { template: "<button @click='btnClick'>{{ n }}</button>", data () { return { n: 0 } }, methods: { btnClick () { // 修改对应组件data内的n值 this.n++ } } }) new Vue({ el: "#app", data: { // ls内的数字,只是提供显示的初始值 ls: [0, 0, 0] } }) </script> </html>
四、组件之间的数据传递
1 - 父组件 ->子组件(通过props建立联系绑定属性)
总结:
- html结构内建立关系,使用 <自定义组件名 :全局变量名="变量名" ></自定义组件名>
- 创建组件,内部使用props接受需要从父组件传入的全局属性名
- 全局属性的内部值,由父组件的data内进行处理赋值
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>父传子</title> </head> <body> <div id="app"> <!-- <local-tag :num="num" :sup_data="sup_data"></local-tag> --> <local-tag :num0="num" :sup_data0="sup_data"></local-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 父组件与子组件建立联系的关键点 // 同绑定属性的方式进行数据传输 // 1.给在父组件中出现的子组件名定义标签的全局属性 // 2.全局属性的值赋值为父组件的数据变量 // 3.在子组件内部,通过props拿到标签中的全局属性名 var localTag = { props: ['num0', 'sup_data0'], template: "<div @click='divActive'>{{ num0 }}</div>", methods: { divActive () { console.log(this.num0); console.log(this.sup_data0); } } } // 数据属于父组件,子组件来接收使用数据 new Vue({ el: "#app", components: { localTag }, data: { num: 10, sup_data: [1, 2, 3, 4, 5] } }) </script> </html>
2 - 子组件 -> 父组件(通过事件触发)
总结:
- html内设置自定义事件,<自定义组件名 @自定义事件名="父组件内相应方法名"></自定义组件名>
- 组件内,template 设置覆盖事件
- 组件内,methods内设置template触发调用方法,方法内部进行html事件绑定传参
this.$emit("html内自定义事件名", this.组件data内变量)- 数据定义在子组件的data内
- 父组件内,methods内对html结构相应的方法进行编码,子组件内data的数据以形参传入
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>子传父</title> </head> <body> <div id="app"> <global-tag @send_data="receive_data"></global-tag> {{ n }} </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 子传父: // 通过发生事件的方式进行数据传输 // 数据由子组件提供, 父组件通过事件的回调方法获取数据 // 发生数据的关键: $emit("事件名", ...args) Vue.component("global-tag", { template: "<div @click='divAction'>我是div</div>", data () { return { num: 10, arrList: [1, 2, 3, 4, 5] } }, methods: { divAction () { // 发生事件 // console.log("要发生事件,携带参数了"); this.$emit("send_data", this.num, this.arrList) } } }); new Vue({ el: "#app", data: { n: 0 }, methods: { receive_data (num, arrList) { console.log("接收到的数据:", num, arrList); this.n = num; } } }) </script> </html>