5. 组件化开发
本节内容:
注意: 在组建中template ,写组件中的html标签时,外层一定要套一个标签
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="vue.js"></script> </head> <body> <div id="app"> <div class="vheader"> 这是头部{{msg}} </div> <App/> <!--3 使用子组件--> </div> </body> <script> //子组件的名称尽量不要叫做Header或者vHeader等,以防和最新的H5中的标签名称冲突,导致组件无法使用 // 1 声明子组件 let App = { data(){ return { //组件中必须写成函数形式的 'appmsg':'hello app!' } }, // 写组件的html标签的地方 template:` <div class="content"> 内容部分{{appmsg}} </div> ` }; let vm = new Vue({ el:'#app', data(){ return { 'msg':'hello' } }, components:{ //App:App //键的名臣和组件名称相同时,可以简写 App, // 2 挂载子组件 } }) </script> </html>
<div id="app"> <addnum></addnum> </div> <script> Vue.component("addnum",{ template:'<div><input type="text" v-model="num"><button @click="num+=1">点击</button></div>', data: function(){ // 写在这里的数据只有当前组件可以使用 return { num:1, } } }); var vm = new Vue({ el:"#app", data:{ } }) </script>
1.在子组件中使用props属性声明,然后可以直接在子组件中任意使用
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="vue.js"></script> </head> <body> <div id="app"> <div class="vheader"> 这是头部{{msg}} </div> <App :xx="msg"/> </div> </body> <script> let App = { data(){ return { 'appmsg':'hello app!' } }, template:` <div class="content"> 内容部分{{appmsg}}--{{xx}} </div> `, props:['xx',] }; let vm = new Vue({ el:'#app', data(){ return { 'msg':'hello' } }, components:{ App, } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ background-color: green; } </style> </head> <body> <div id="app"> <h1>{{ganmao}}</h1> <!-- 用子: 使用子组件 --> <App></App> </div> </body> <script src="../vue.js"></script> <script src="../axios.js"></script> <script> // 局部组件 //1 声子: 声明子组件 let Vheader = { data(){ return { msg:'我是子组件1号' } }, // 写组件的html标签的地方 template: ` <div class="c1"> <h3 style="color:#ff0000">{{msg}}</h3> <h2 style="color:blue;">{{son}}</h2> </div> ` , props:['son', ], //第二步: 写父组件中使用子组件时的自定义标签属性名称,那么他就可以拿到标签属性对应的值,并且可以作为当前子标签的一个数据属性来使用 }; let App = { data(){ return { app_num:80, } }, components: { Vheader, }, // 注意: 写组件中的html标签时,外层一定要套一个标签 // 第一步: 使用子组件的地方写自定义属性 // 静态传值: <Vheader son="20"></Vheader> // 动态传值: <Vheader :son="app_num"></Vheader> template: ` <div class="app"> <h2>我是app组件</h2> <Vheader :son="app_num"></Vheader> </div> ` } let vm = new Vue({ el:'#app', // data:{} data(){ return { ganmao:'xxx', } }, components:{ App, } }) </script> </html>
使用父组件传递数据给子组件时, 注意一下几点:
1. 传递数据是变量,则需要在属性左边添加冒号.
传递数据是变量,这种数据称之为"动态数据传递"
传递数据不是变量,这种数据称之为"静态数据传递"
2. 父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据.
这种情况,在开发时,也被称为"单向数据流"
a.子组件中使用this.$emit('fatherHandler',val);fatherHandler是父组件中使用子组件的地方添加的绑定自定义事件,
第一步:在父组件使用子组件的地方写自定义事件
<Vheader @fatherHandler="xx"></Vheader>
第二步: 在子组件中this.$emit('fatherHandler', 200);
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="vue.js"></script> </head> <body> <div id="app"> <div class="vheader"> 这是头部{{msg}} -- {{sondata}} </div> <App @son="sonDataHandler"/> </div> </body> <script> let App = { data(){ return { 'appmsg':'hello app!' } }, template:` <div class="content"> 内容部分{{appmsg}} <button @click="xH"></button> </div> `, methods:{ xH(){ this.$emit('son',this.appmsg) } } }; let vm = new Vue({ el:'#app', data(){ return { 'msg':'hello', 'sondata':'xxx', } }, components:{ App, }, methods:{ sonDataHandler(val){ console.log(val); this.sondata = val; } } }) </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ background-color: green; } </style> </head> <body> <div id="app"> <h1>{{ganmao}}</h1> <!-- 用子: 使用子组件 --> <App></App> </div> </body> <script src="../vue.js"></script> <script src="../axios.js"></script> <script> // 局部组件 //1 声子: 声明子组件 let Vheader = { data(){ return { msg:'我是子组件1号', header_num:99, } }, // 写组件的html标签的地方 template: ` <div class="c1"> <h3 style="color:#ff0000">{{msg}}</h3> <button @click="zouni">zouni</button> </div> ` , methods: { zouni(){ console.log(this); // this -- 组件对象 this.$emit('fatherHandler', this.header_num); } } }; let App = { data(){ return { app_num:80, // 声明数据属性,承接子组件传递来的值 son_data:0, } }, components: { Vheader, }, // 第一步:在父组件使用子组件的地方写自定义事件 // <Vheader @fatherHandler="xx"></Vheader> // 第二步: 在子组件中this.$emit('fatherHandler', 200); template: ` <div class="app"> <h2>我是app组件</h2> <Vheader @fatherHandler="xx"></Vheader> <h3 style="color:yellow;">{{son_data}}</h3> </div> ` , methods:{ xx(val){ this.son_data = val; console.log(this); // console.log('>>>>>', val); }, } } let vm = new Vue({ el:'#app', // data:{} data(){ return { ganmao:'xxx', } }, components:{ App, }, }) console.log(vm); </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ background-color: green; } </style> </head> <body> <div id="app"> <h1>{{ganmao}}</h1> <!-- 用子: 使用子组件 --> <App></App> </div> </body> <script src="../vue.js"></script> <script src="../axios.js"></script> <script> // 第一步:声明公交车 let bus = new Vue(); let Vheader2 = { data(){ return { msg:'我是子组件2号', header2_num:88, vheader_data:'', } }, // 写组件的html标签的地方 template: ` <div class="c1"> <h3 style="color:#ff0000">{{msg}}</h3> <h3>{{vheader_data}}</h3> </div> `, created(){ // 第三步:在公交车上获取值 bus.$on('xxx',(val) => { console.log('???', val); // ??? 99 this.vheader_data = val; }); } } // 局部组件 //1 声子: 声明子组件 let Vheader = { data(){ return { msg:'我是子组件1号', header_num:99, } }, // 写组件的html标签的地方 template: ` <div class="c1"> <h3 style="color:#ff0000">{{msg}}</h3> <button @click="zouni">zouni</button> </div> ` , methods: { zouni(){ // 第二步:往公交车上添加值 bus.$emit('xxx', this.header_num) } } }; let App = { data(){ return { app_num:80, // 声明数据属性,承接子组件传递来的值 son_data:0, } }, components: { Vheader, Vheader2, }, // 第一步:在父组件使用子组件的地方写自定义事件 // <Vheader @fatherHandler="xx"></Vheader> // 第二步: 在子组件中this.$emit('fatherHandler', 200); template: ` <div class="app"> <h2>我是app组件</h2> <Vheader></Vheader> <Vheader2></Vheader2> </div> ` , methods:{ xx(val){ this.son_data = val; console.log(this); // console.log('>>>>>', val); }, } } let vm = new Vue({ el:'#app', // data:{} data(){ return { ganmao:'xxx', } }, components:{ App, }, }) console.log(vm); </script> </html>
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="vue.js"></script> </head> <body> <div id="app"> <div class="vheader"> 这是头部{{msg}} -- {{sondata}} </div> <!--<App :xx="msg"/>--> <App @sonHa="sonDataHandler"/> </div> </body> <script> let bus = new Vue(); Vue.component('T1',{ data(){ return { 't1num':100, } }, template:` <div class="t1"> {{t1num}} <button @click="f1">走你</button> </div> `, methods:{ f1(){ // console.log(this.t1num); bus.$emit('TestData',this.t1num) } } }); Vue.component('T2',{ data(){ return { 't2num':200, 't1n':0, } }, template:` <div class="t2"> <h1>{{t2num}}</h1> <h2 style="color:red;">{{t1n}}</h2> </div> `, created(){ // console.log(this.t1n); bus.$on('TestData',(val)=>{ console.log(val); this.t1n = val; }) } }); let App = { data(){ return { 'appmsg':'hello app!' } }, template:` <div class="content"> 内容部分{{appmsg}} <button @click="xH">点击</button> <T1></T1> <T2></T2> </div> `, methods:{ xH(){ this.$emit('sonHa',this.appmsg) } // console.log(this); } // props:['xx',] }; let vm = new Vue({ el:'#app', data(){ return { 'msg':'hello', 'sondata':'xxx', } }, components:{ App, }, methods:{ sonDataHandler(val){ console.log(val); this.sondata = val; } } }) </script> </html>