初学vue,组件及插槽

    技术2025-10-23  10

    组件是为了解决复用而诞生的

    创建组建

    定义创建,名为todo-item的组件

    <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>

    效果:

    另一种写法

    <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弹框

    <!--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") } } })

    使用子组件向父组件传值

    <!--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、组件等,填充的内容会替换子组件的标签。

    <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>
    Processed: 0.020, SQL: 9