组件是为了解决复用而诞生的vue
定义建立,名为todo-item的组件web
<div id="app"> <ul> <todo-item v-for="item in list" :title="item.title" :del="item.del"></todo-item> </ul> </div> <script> <!--todo-item为属性名称--> Vue.component("todo-item",{ <!--定义一个属性声明--> <!--定义title为String类型,del为Boolean类型,且默认值为:false--> props:{ title:String, del:{ type:Boolean, default:false } }, <!--定义模板--> template: '<li>' + ' <span v-if="!del">{{title}}</span>\n' + ' <span v-else style="text-decoration: line-through">{{title}}</span>\n' + ' <button v-show="!del">删除</button>\n' + '</li>', data:function () { return{} }, methods:{ } }) var vm = new Vue({ el:"#app", data: { <!--在list中定义两组数据--> list: [ { title: "课程-1", del: false }, { title: "课程-2", del: true }] } }) </script>
效果:app
另外一种写法svg
<div id="app"> <todo-list></todo-list> </div> <script> <!--todo-item为属性名称--> Vue.component("todo-item",{ <!--定义一个属性声明--> <!--定义title为String类型,del为Boolean类型,且默认值为:false--> props:{ title:String, del:{ type:Boolean, default:false } }, <!--定义模板--> template: '<li>' + '<span v-if![image-20200703182159167](/home/codeyuan-y/.config/Typora/typora-user-images/image-20200703182159167.png)="!del">{{title}}</span>\n' + '<span v-else style="text-decoration: line-through">{{title}}</span>\n' + '<button v-show="!del">删除</button>\n' + '</li>', data:function () { return{} }, methods:{ } }) Vue.component("todo-list",{ template: '<ul>' + '<todo-item v-for="item in list" :title="item.title" :del="item.del"></todo-item>' + '</ul>', data:function () { return{ <!--在list中定义两组数据--> list: [{ title: "课程-1", del: false }, { title: "课程-2", del: true }] } }) var vm = new Vue({ el:"#app" }) </script>
当点击删除时会出现相应 Hello World弹框this
<!--todo-item为属性名称--> Vue.component("todo-item",{ <!--定义一个属性声明--> <!--定义title为String类型,del为Boolean类型,且默认值为:false--> props:{ title:String, del:{ type:Boolean, default:false } }, <!--定义模板--> template:'<li>' + ' <span v-if="!del">{{title}}</span>\n' + ' <span v-else style="text-decoration: line-through">{{title}}</span>\n' + ' <button v-show="!del" @click="handleClick">删除</button>\n' + ' </li>', data:function () { return{} }, methods:{ handleClick(){ alert("Hello World") } } })
使用子组件向父组件传值spa
<!--todo-item为属性名称--> Vue.component("todo-item",{ <!--定义一个属性声明--> <!--定义title为String类型,del为Boolean类型,且默认值为:false--> props:{ title:String, del: { type: Boolean, default: false } }, <!--定义模板--> template:'<li>' + ' <span v-if="!del">{{title}}</span>\n' + ' <span v-else style="text-decoration: line-through">{{title}}</span>\n' + ' <button v-show="!del" @click="handleClick">删除</button>\n' + ' </li>', data:function () { return{} }, methods:{ handleClick(){ alert("Hello World") <!--触发父组件当中的@delete,而且将title参数传入--> this.$emit("delete",this.title) } } }) Vue.component("todo-list",{ template: '<ul>\n' + ' <todo-item v-for="item in list" @delete="handleDelete" :title="item.title" :del="item.del"></todo-item>\n' + '</ul>', data:function () { return{ <!--在list中定义两组数据--> list: [{ title: "课程-1", del: false }, { title: "课程-2", del: true }] } }, methods:{ handleDelete(val){ alert(val) } } }) var vm = new Vue({ el:"#app" }
插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件能够在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。code
<div id="app"> <todo-list> <todo-item slot="first-slot" v-for="item in list" :title="item.title" :del="item.del"></todo-item> <!-- 上面这种是老版本写法:直接在标签中加slot 下面这是新版本写法:加一层template --> <template v-slot:second-slot> <span>Hello World</span> </template> </todo-list> </div> <script> <!--todo-item为属性名称--> Vue.component("todo-item",{ <!--定义一个属性声明--> <!--定义title为String类型,del为Boolean类型,且默认值为:false--> props:{ title:String, del: { type: Boolean, default: false } }, <!--定义模板--> template: '<li>' + '<span v-if="!del">{{title}}</span>\n' + '<span v-else style="text-decoration: line-through">{{title}}</span>\n' + '<button v-show="!del">删除</button>\n' + '</li>' }) Vue.component("todo-list",{ <!--在模板中定义一个插槽,若是不使用name进行对应,一个插槽能显示 <todo-list>里面的全部内容--> template:'<ul>' + '<slot name="first-slot"></slot>'+ '<slot name="second-slot"></slot>'+ '</ul>', }) var vm = new Vue({ el:"#app", data:{ <!--在list中定义两组数据--> list: [{ title: "课程-1", del: false }, { title: "课程-2", del: true }] } }) </script>