vue :【组件、插槽、自定义事件】

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

参考:https://cn.vuejs.org/v2/guide/components.html

猜你喜欢

转载自www.cnblogs.com/ressso/p/12099231.html