初学vue,组件及插槽

组件是为了解决复用而诞生的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>