前端工程师-Vue-component的创建、注册、使用
本文参考了跬步者的文章,请戳这里,真的写得太详细了,在这里只是直接总结,方便自己记忆
ps:本博客的代码均是可以直接拷贝运行的,希望能对大家有帮助
1.component的创建,注册,使用
a.Vue.extend({...})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue.extend</title> <script src="http://lib.baomitu.com/vue/2.3.4/vue.js"></script> </head> <body> <div id="app"> <p>我是全局注册</p> <qj-example></qj-example> <p>我是局部注册的</p> <jb-example></jb-example> </div> <script> //使用组件构造器构造一个组件 var example = Vue.extend({ template: "<h1>我是使用Vue.extend这个组件构造器所构造的组件</h1>" }); //将构造好的组件注册在需要用这个组件的实例上 //你可以进行全局注册:Vue.component(组件的名称,{组件的选项对象}就是使用组件构造器所返回的对象) Vue.component('qj-example', example); var vue = new Vue({ el: '#app', //你也可以进行局部注册,此时components可是复数哦! components: { 'jb-example': example } }); </script> </body> </html>

b.每次创建都要使用一遍Vue.extend({...}),这样过于繁琐,我们可以使用Vue.extend({...})的语法糖,这种方式就是我们在各个教程上看到的最普遍的方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue.extend</title> <script src="http://lib.baomitu.com/vue/2.3.4/vue.js"></script> </head> <body> <div id="app"> <p>我是全局注册</p> <qj-example></qj-example> <p>我是局部注册的</p> <jb-example></jb-example> </div> <script> //使用组件构造器构造一个组件 // var example = Vue.extend({ // template: "<h1>我是使用Vue.extend这个组件构造器所构造的组件</h1>" // }); //将构造好的组件注册在需要用这个组件的实例上 //你可以进行全局注册 //这样写,vue会自动帮你调用'组件构造器'的 Vue.component('qj-example', { template: "<h1>我是使用Vue.extend的语法糖所构造的组件</h1>" }); var vue = new Vue({ el: '#app', //你也可以进行局部注册,此时components可是复数哦! components: { 'jb-example': { template: "<h2>我是使用Vue.extend的语法糖所构造的组件</h2>" } } }); </script> </body> </html>

2.template的一些问题
如果模板非常庞大,岂不是要写的很麻烦,也不容易维护,比如如果你把上面template的参数换成下面这一段,那你维护起来岂不是要哭,so...(下方代码请注意颜色的标注)
'<p>本文参考了<a href="http://home.cnblogs.com/u/jhj117/">跬步者</a>的文章,请戳<a href="https://www.cnblogs.com/jhj117/p/5634034.html" target="_blank">这里</a>,真的写得太详细了,在这里只是直接总结,方便自己记忆</p> <p>ps:本博客的代码均是可以直接拷贝运行的,希望能对大家有帮助</p>'
a.使用script标签来注册一个模板 这里要注意script标签的type类型要使用'text/x-template',不知道大家使用过那个小小的juicer.js没有,他就是使用了type属性。
ps1:script不写type默认是text/javascript,如果写了不被识别的type将被浏览器忽略。 script的type为各种template的时候,可能就是使用了模板引擎。
ps2.请记住,Component template should contain exactly one root element.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue.extend</title> <script src="http://lib.baomitu.com/vue/2.3.4/vue.js"></script> </head> <body> <div id="app"> <p>我是全局注册</p> <qj-example></qj-example> <p>我是局部注册的</p> <jb-example></jb-example> </div> <!-- 我是使用script标签定义的模板 用编辑器分分钟整理好结构--> <script type="text/x-template" id="my-component"> <div>//如果你不给定一个根元素,会报错哦,在这里就是你吧这对div标签删掉 <p>本文参考了 <a href="http://home.cnblogs.com/u/jhj117/">跬步者</a>的文章, 请戳 <a href="https://www.cnblogs.com/jhj117/p/5634034.html" target="_blank">这里</a>, 真的写得太详细了,在这里只是直接总结,方便自己记忆 </p> <p>ps:本博客的代码均是可以直接拷贝运行的,希望能对大家有帮助</p> </div> </script> <script> Vue.component('qj-example', { template: '#my-component' }); var vue = new Vue({ el: '#app', //你也可以进行局部注册,此时components可是复数哦! components: { 'jb-example': { template: '#my-component' } } }); </script> </body> </html>

b.vue支持对html5的<template>标签做处理,对这个标签不熟悉的话,可以戳这里
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue.extend</title> <script src="http://lib.baomitu.com/vue/2.3.4/vue.js"></script> </head> <body> <div id="app"> <p>我是全局注册</p> <qj-example></qj-example> <p>我是局部注册的</p> <jb-example></jb-example> </div> <!-- 我是使用template标签定义的模板 用编辑器分分钟整理好结构--> <template id="my-component"> <div> <p>本文参考了 <a href="http://home.cnblogs.com/u/jhj117/">跬步者</a>的文章, 请戳 <a href="https://www.cnblogs.com/jhj117/p/5634034.html" target="_blank">这里</a>, 真的写得太详细了,在这里只是直接总结,方便自己记忆 </p> <p>ps:本博客的代码均是可以直接拷贝运行的,希望能对大家有帮助</p> </div> </template> <script> Vue.component('qj-example', { template: '#my-component' }); var vue = new Vue({ el: '#app', //你也可以进行局部注册,此时components可是复数哦! components: { 'jb-example': { template: '#my-component' } } }); </script> </body> </html>
2.组件的data选项,想看所有选项的话,请戳这里
我就自己不瞎说了,直接贴个文档,如果不明白可以留言,我会尽力解释的

3.父组件向子组件传递数据
这里我改写了跬步者的例子,基本是一样的。
<!-- component --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue.extend</title> <script src="http://lib.baomitu.com/vue/2.3.4/vue.js"></script> <link href="http://lib.baomitu.com/twitter-bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script> <style> #app { padding: 10% 30%; } </style> </head> <body> <div id="app"> <input type="text" v-model="searchWord" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"> <my-table :title="tableName" :list="tableList" :search-key="searchWord"></my-table> </div> <template id="my-grid"> <table class="table"> <thead> <tr> <th scope="col" v-for="item in title">{{item}}</th> </tr> </thead> <tbody> <tr v-for="(item,index) in grid"> <th scope="row">{{index+1}}</th> <td>{{grid[index].name}}</td> <td>{{grid[index].sex}}</td> <td>{{grid[index].age}}</td> </tr> </tbody> </table> </template> <script> var vue = new Vue({ el: '#app', data: { searchWord: '', tableName: ['#', 'name', 'sex', 'age'], tableList: [{ name: 'li', sex: 'boy', age: '10' }, { name: 'zhang', sex: 'gril', age: '20' }, { name: 'yang', sex: 'boy', age: '40' }, ] }, components: { 'my-table': { template: '#my-grid', props: { title: Array, list: Array, searchKey: String }, data() { return { grid: this.list, //子组件接收一个父组件数据的副本 } }, watch: { searchKey: function(val) { console.log(val); if (val != '') { this.grid = this.list.filter(function(item, index, arr) { for (let elem of Object.values(item)) { if (elem.includes(val)) { return item; } } }, this); } else { this.grid = this.list; } this.$forceUpdate(); } } } } }); </script> </body> </html>

3.子组件向父组件传递数据(这个我回头写好例子了再补上)
在之前的例子上加以改动,添加需求,让组件以数组形式返回符合条件的姓名,让父组件显示,在之前代码基础上添加橙色色代码即可即可
<!-- component --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>vue.extend</title> <script src="http://lib.baomitu.com/vue/2.3.4/vue.js"></script> <link href="http://lib.baomitu.com/twitter-bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script> <style> #app { padding: 10% 30%; } </style> </head> <body> <div id="app"> <input type="text" v-model="searchWord" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1"> <my-table :title="tableName" :list="tableList" :search-key="searchWord" @searchresult="showSearch"></my-table>在使用子组件时用v-on/@注册searchresult这个自定义事件,父组件用showSearch这个函数接收自定义事件返回的参数 <div> <p>符合条件的学生姓名:{{showName.join(",")}}</p> </div> </div> <template id="my-grid"> <table class="table"> <thead> <tr> <th scope="col" v-for="item in title">{{item}}</th> </tr> </thead> <tbody> <tr v-for="(item,index) in grid"> <th scope="row">{{index+1}}</th> <td>{{grid[index].name}}</td> <td>{{grid[index].sex}}</td> <td>{{grid[index].age}}</td> </tr> </tbody> </table> </template> <script> var vue = new Vue({ el: '#app', data: { searchWord: '', tableName: ['#', 'name', 'sex', 'age'], tableList: [{ name: 'li', sex: 'boy', age: '10' }, { name: 'zhang', sex: 'gril', age: '20' }, { name: 'yang', sex: 'boy', age: '40' }], showName: [], }, methods: { showSearch(val) { this.showName = val;这个val就是result }, }, components: { 'my-table': { template: '#my-grid', props: { title: Array, list: Array, searchKey: String }, data() { return { grid: this.list, //子组件接收一个父组件数据的副本 } }, watch: { searchKey: function(val) { console.log(val); let result = []; if (val != '') { this.grid = this.list.filter(function(item, index, arr) { for (let elem of Object.values(item)) { if (elem.includes(val)) { result.push(arr[index].name); return item; } } }, this); } else { this.grid = this.list; } this.$forceUpdate(); this.$emit('searchresult', result);使用vue的实例方法$emit发送自定义事件,饼返回result这个参数 } } } } }); </script> </body> </html>

连雨不知春去,一晴方觉夏深

浙公网安备 33010602011771号