组件 component
- 在 vue 中通过 Vue.component("name",{...}); 来定义组件,(vue 的组件其实就是一个 自定义 的 HTML 标签,我们可以在这个自定义的标签中嵌入多个HTML 标签,以达到复用的效果,类似于java 的对象)
- 组件是可复用的 Vue 实例对象,且带有一个名字,组件内定义和 Var vm = new Vue({...}); 类似,都是以 键值对 的形式
-
Vue.component("ca",{ props:["url"], template:"<a :href='url' >{{url}}</a>" });
-
在上面例子中,定义了一个组件,名称为 "ca",我们可以在 HTML 中的 <body> 标签中 把 <ca >当成一个 HTML 的标签来使用,如下
template 是一个模板,该模板中定义的是一个或者多个 HTML 标签。使用这个自定义标签,效果就相当于使用 template (模板) 定义的 HTML 标签 -
<ca v-bind:url="message"></ca>
-
通过 v-bind:url="message" 可以向组件中的 props:["url"], 传入参数,参数来源于 Vue 对象中 data:{message:"https://cn.vuejs.org/v2/guide/components.html"} 定义的参数,这样就可以在组件中获取到 message 的值了
组件插槽 <slot></slot>
Vue.component("name-todo",{// name-todo 组件
props:["mesg"],
template:"<div>\
<h3>{{mesg}}</h3>\
<slot name='slot-1'></slot>\
<ul>\
<slot name='slot-2'></slot>\
</ul>\
</div>"
});
// 组件可以定义多个;
// <slot></slot> 插槽,相当于占位符,通过属性 name 来识别区分,插槽通过 组件来替代,通过在组件标签中使用属性 slot="slot-1",引用插槽名称,表示当前组件替换到该插槽位置
Vue.component("name-todo-title",{
props:["title","title_url"],
template:"<a :href='title_url'>{{title}}</a>"
});
- 组件 "name-todo" 中定义了多个 HTML 标签,同时在标签之间 留下了几个 插槽<slot>,在使用 <name-todo></name-todo> 的标签时
<name-todo :title="message">
<name-todo-title slot="slot-1" v-bind:title="title" :title_url="my_url"></name-todo-title>
<name-xxx slot="slot-2" v-bind:title="xxx" :xxx="xxx"></name-todo-title>
</name-todo>
自定义标签的顺序 不会影响 HTML 页面的展现效果,只有插槽 name 的引用才会改变 页面的展现
- <name-xxx slot="slot-2" ... 表示 标签 <name-xxx> 插入到 组件 name-todo 中定义的模板中,在 <slot name="slot-2"></slot> 这个 插槽为 (就是被 <ul> 标签包括的那个插槽位置)
- 倘若 <name-xxx slot="slot-1",则表示 该 标签 插入到 <slot name="slot-1"></slot> 这个插槽位置
自定义事件内容分发 v-on:abc="method(param)"
自定义事件
- 在页面标签中使用 v-on:abc="method(param)" 自定义一个事件,事件名是:abc
在 vue 中,每个组件是一个独立的 vue 实例,在页面中只能绑定 vue根对象的方法和参数,却无法绑定 组件中的方法(而绑定组件的参数,只能在自定义标签中通过 v-bind:props="param" 使用)
- 页面可以展示组件的模板,模板中可以 获取页面传递的参数(页面可以向组件传递参数)。但 面中无法调用 组件定义的方法
- 页面也可以 展示 vue 根对象中的的数据,也可以通过 v-on:click 等事件来绑定 vue 根对象的方法
- 但是,组件和 vue根对象 无法相互通信,即:在 Vue.component 中 无法直接调用 new Vue() 的方法
于是有了组件方法 $emit
- 通过在组件内使用: this.$emit("abc",this.index) ,该方法可以调用页面中的 自定义事件 "abc"
- 自定义事件 可以绑定一个 vue 根对象方法
- 这样就可以在组件中 通过 $emit 间接的调用 vue根对象的方法了
- $emit ----调用---->自定义事件"abc"-----绑定---> vue根对象方法
实例:
<body>
<div id="app">
<span :mesg="message">{{message}}</span>
<name-todo-tiems v-for="(arg,index) in args" :arg="arg" :index="index"
v-on:abc="removeArgs(index)"></name-todo-tiems>
<!--v-on:abc="removeArgs(index)" :这是事件绑定的一种写法,常规事件绑定写法是:v-on:click="method(xxx)"
自定义一个事件,名字为:abc,将这个是绑定到 removeArgs 方法 -->
</div>
</body>
<script>
Vue.component("name-todo-tiems",{
props:["arg","index"],
template:"<ul><li>{{arg}}---<button @click='remove'>删除</button></li></ul>",
methods:{
//点击 组件内定义的删除 按钮,调用 方法'remove'
remove:function () {
//使用 $emit() 方法来调用 HTML 页面 中定义的事件,该事件名是 abc,abc这个事件绑定了 vue 根对象中的 removeArgs 方法
this.$emit("abc",this.index)
}
}
});
var vm = new Vue({
el:"#app",
data:{
message:"一个普通的信息",
args:["视频","音药","直播"],
},
methods:{
//在组件中想办法调用这个方法,该方法能够真实的删除 data中的源数据
removeArgs:function (index) {
console.log("删除了"+this.args[index] + " 元素,OK");
this.args.splice(index,1);
}
}
});
</script>