Vue2.x 自定义组件

  • 自定义全局组件
    • Vue中如何创建组件?
    • 创建组件的其它方式 - 组件模板
  • 自定义局部组件
  • 组件中的data和methods
  • 组件中的data为什么是一个函数
  • 组件切换
  • 动态组件
  • 组件动画
  • 父子组件
  • 父子组件数据传递
  • 父子组件方法传递
  • 子组件传递数据给父组件
  • 组件命名注意点
  • 组件多级传递
  • 匿名插槽
  • 具名插槽
  • 组件 v-slot 指令
  • 作用域插槽
  • 组件 v-slot 接收作用域插槽暴露的数据

写在前面: 此博客记录自己学习vue学习笔记,如有侵权,联系删!
学习来源: Vue + Vue-Cli 快速入门教程
李南江老师各平台账号:

  • 微博:极客江南
  • 微信公众号:李南江
  • 腾讯课堂: 李南江
  • 网易云课堂:李南江

Vue两大核心:

  • 数据驱动界面改变
  • 组件化

什么是组件?
在前端开发中组件就是把一个很大的界面拆分为多个小的界面, 每一个小的界面就是一个组件
什么是组件化?
将大界面拆分成小界面就是组件化

组件化的好处
1、可以简化Vue实例的代码
2、可以提高复用性

自定义全局组件

Vue中如何创建组件?

1、创建组件构造器
2、注册已经创建好的组件
3、使用注册好的组件

html代码:

<div id="app"><!-- 3.使用注册好的组件--><abc></abc>
</div>

vue代码:

// 1.创建组件构造器
let Profile = Vue.extend({// 注意点: 在创建组件指定组件的模板的时候, 模板只能有一个根元素template: `<div><img src="data:images/fm.jpg"/><p>我是描述信息</p></div>`
});
// 2.注册已经创建好的组件
// 第一个参数: 指定注册的组件的名称
// 第二个参数: 传入已经创建好的组件构造器
Vue.component("abc", Profile );// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {}
});

创建组件的其它方式 - 组件模板

1、在注册组件的时候, 除了传入一个组件构造器以外, 还可以直接传入一个对象
2、在编写组件模板的时候, 除了可以在字符串模板中编写以外, 还可以像过去的art-templatee一样在scripte中编写
3、在编写组件模板的时候, 除了可以在scripte中编写以外, vue还专门提供了一个编写模板的标签templatee

html代码:

<div id="app"><abc></abc>
</div>

script中编写模板组件代码:

<script id="info" type="text/html"><div><img src="data:images/fm.jpg"/><p>我是描述信息</p></div>
</script>

template 中编写模板组件代码:

<template id="info"><div><img src="data:images/fm.jpg"/><p>我是描述信息</p></div>
</template>

vue代码:

Vue.component("abc", {// 注意点: 在创建组件指定组件的模板的时候, 模板只能有一个根元素template: "#info"
});// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {}
});

自定义局部组件

自定义全局组件特点
在任何一个Vue实例控制的区域中都可以使用

自定义局部组件特点
只能在自定义的那个Vue实例控制的区域中可以使用

如何自定义一个局部组件
在vue实例中新增components: {}
在{}中通过key:value形式注册组件

components:{abc: {}
}

html代码:

<div id="app1"><abc></abc>
</div>
<div id="app2"><abc></abc>
</div>
<template id="info"><div><img src="data:images/fm.jpg"/><p>我是描述信息</p></div>
</template>

vue代码:

// 这里就是MVVM中的View Model
let vue1 = new Vue({el: '#app1',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {}
});
// 这里就是MVVM中的View Model
let vue2 = new Vue({el: '#app2',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {"abc": {// 注意点: 在创建组件指定组件的模板的时候, 模板只能有一个根元素template: "#info"}}
});

组件中的data和methods

自定义组件中的data和methods
Vue实例控制的区域相当于一个大的组件, 在大组件中我们可以使用data和methods
而我们自定义的组件也是一个组件, 所以在自定义的组件中也能使用data和methods

自定义组件中data注意点
在自定义组件中不能像在vue实例中一样直接使用data
而是必须通过返回函数的方式来使用data

html代码:

<div id="app"><!--由于我们是在Vue实例控制的区域中使用的函数所以系统会去Vue实例中查找有没有对应的方法所以我们需要在Vue实例中实现对应的方法--><button @click="appFn">我是按钮</button><!--由于我们是在Vue实例控制的区域中使用了数据所以系统回去Vue实例中查找有没有对应的数据所以我们需要在Vue实例中添加对应的数据--><p>{{appMsg}}</p><abc></abc>
</div>
<template id="info"><div><img src="data:images/fm.jpg"/><!--由于我们是在自定义组件中使用了函数所以系统会去自定义的组件中查找有没有对应的方法所以我们需要在自定义的组件中实现对应的方法--><button @click="abcFn">我是按钮</button><p>{{abcMsg}}</p></div>
</template>

vue代码:

// 自定义全局组件
Vue.component("abc", {// 注意点: 在创建组件指定组件的模板的时候, 模板只能有一个根元素template: "#info",methods: {abcFn(){alert("abcFn");}},// data: {//     abcMsg: "学院"// }// 注意点: 虽然在自定义的组件中也可以使用data, 但是在使用的时候, 使用的方式和Vue实例中不太一样//         在自定义组件中使用data必须赋值一个函数, 然后通过函数的返回值来定义有哪些数据data: function () {return {abcMsg: "学院"}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {appMsg:"知播渔"},// 专门用于存储监听事件回调函数methods: {appFn(){alert("appFn");}},// 专门用于定义计算属性的computed: {}
});

组件中的data为什么是一个函数

自定义组件中的data为什么是一个函数
因为自定义组件可以复用, 为了保证复用时每个组件的数据都是独立的, 所以必须是一个函数

html代码:

<!--
1.自定义组件中的datadata为什么是一个函数
因为自定义组件可以复用, 为了保证复用时每个组件的数据都是独立的, 所以必须是一个函数
-->
<!--这里就是MVVM中的View-->
<div id="app"><abc></abc><abc></abc><abc></abc>
</div>
<template id="info"><div><button @click="add">累加</button><p>{{number}}</p></div>
</template>

vue代码:

// 自定义全局组件
Vue.component("abc", {template: "#info",/*组件中的data如果不是通过函数返回的, 那么多个组件就会公用一份数据, 就会导致数据混乱如果组件中的data是通过函数返回的, 那么每创建一个新的组件, 都会调用一次这个方法将这个方法返回的数据和当前创建的组件绑定在一起, 这样就有效的避免了数据混乱* */data: function () {return {number: 0}},methods: {add(){this.number++;}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {}
});

组件切换

组件切换
对于普通的元素我们可以通过v-if来实现切换
对于组件我们也可以通过v-if来实现切换
因为组件的本质就是一个自定义元素

html代码:

<!--这里就是MVVM中的View-->
<div id="app"><button @click="toggle">切换</button><!--<p v-if="isShow">我是首页</p><img v-else src="data:images/fm.jpg" alt="">--><home v-if="isShow"></home><photo v-else></photo>
</div>
<template id="home"><div><p>我是首页</p></div>
</template>
<template id="photo"><div><img src="data:images/fm.jpg" alt=""></div>
</template>

vue代码:

// 自定义全局组件
Vue.component("home", {template: "#home",
});
Vue.component("photo", {template: "#photo",
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {isShow: true},// 专门用于存储监听事件回调函数methods: {toggle(){this.isShow = !this.isShow;}},// 专门用于定义计算属性的computed: {}
});

动态组件

什么是动态组件?
通过v-if/v-else-if/v-else确实能够切换组件
但是在Vue中切换组件还有一种更专业的方式

component我们称之为动态组件, 也就是你让我显示谁我就显示谁

为什么可以通过v-if切换还要有component
因为component可以配合keep-alive来保存被隐藏组件隐藏之前的状态

html代码:

<div id="app"><button @click="toggle">切换</button><!--<p v-if="isShow">我是首页</p><img v-else src="data:images/fm.jpg" alt="">--><!--<home v-if="isShow"></home><photo v-else></photo>--><keep-alive><component v-bind:is="name"></component></keep-alive></div>
<template id="home"><div><p>我是首页</p><input type="checkbox"></div>
</template>
<template id="photo"><div><img src="data:images/fm.jpg" alt=""></div>
</template>

vue代码:

// 自定义全局组件
Vue.component("home", {template: "#home",
});
Vue.component("photo", {template: "#photo",
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {isShow: true,name: "home"},// 专门用于存储监听事件回调函数methods: {toggle(){this.isShow = !this.isShow;this.name = this.name === "home" ? "photo" : "home";}},// 专门用于定义计算属性的computed: {}
});

组件动画

如何给组件添加动画?
给组件添加动画和过去给元素添加动画一样
如果是单个组件就使用transition
如果是多个组件就使用transition-group

过渡动画注意点
默认情况下进入动画和离开动画是同时执行的, 如果想一个做完之后再做另一个, 需要指定动画模式

css代码

<style>.v-enter{opacity: 0;margin-left: 500px;}.v-enter-to{opacity: 1;}.v-enter-active{transition: all 3s;}.v-leave{opacity: 1;}.v-leave-to{opacity: 0;}.v-leave-active{transition: all 3s;margin-left: 500px;}
</style>

html代码:

<!--这里就是MVVM中的View-->
<div id="app"><button @click="toggle">切换</button><transition mode="out-in"><component v-bind:is="name"></component></transition>
</div>
<template id="home"><div><p>我是首页</p><input type="checkbox"></div>
</template>
<template id="photo"><div><img src="data:images/fm.jpg" alt=""></div>
</template>

vue代码:

// 自定义全局组件
Vue.component("home", {template: "#home",
});
Vue.component("photo", {template: "#photo",
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {name: "home"},// 专门用于存储监听事件回调函数methods: {toggle(){this.name = this.name === "home" ? "photo" : "home";}},// 专门用于定义计算属性的computed: {}
});

父子组件

什么是父子组件?

  • 在一个组件中又定义了其它组件就是父子组件
  • 其实局部组件就是最简单的父子组件, 因为我们说过可以把Vue实例看做是一个大组件
  • 我们在Vue实例中定义了局部组件, 就相当于在大组件里面定义了小组件, 所以实局部组件就是最简单的父子组件

如何定义其它的父子组件
前面我们说过, 自定义组件中可以使用data, 可以使用methods. 当然自定义组件中也可以使用components,所以我们也可以在自定义组件中再定义其它组件

html代码:

<div id="app">
<!--    <home></home>--><father></father>
<!--    <son></son>-->
</div>
<template id="father"><div><p>我是父组件</p><son></son></div>
</template>
<template id="son"><div><p>我是子组件</p></div>
</template>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {// "home": {//     template: "#home"// }"father": {template: "#father",components: {"son": {template: "#son"}}}}
});

父子组件数据传递

父子组件数据传递?
在Vue中子组件是不能访问父组件的数据的,
如果子组件想要访问父组件的数据, 必须通过父组件传递

如何传递数据
1、在父组件中通过v-bind传递数据
传递格式v-bind:自定义接收名称 = "要传递数据"
2、在子组件中通过props接收数据
接收格式props: ["自定义接收名称"]

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><!--注意点: 组件是可以使用自己的数据的--><p>{{name}}</p><p>{{age}}</p><!--这里将父组件的name通过parentname传递给了子组件--><son :parentname="name" :abc="age"></son></div>
</template>
<template id="son"><div><!--这里通过parentname使用了父组件传递过来的数据--><p>{{parentname}}</p><p>{{abc}}</p></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",data: function(){return {name: "lnj",age: 33}},// 子组件components: {"son": {template: "#son",// 这里通过parentname接收了父组件传递过来的数据props: ["parentname", "abc"]}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

父子组件方法传递

父子组件方法传递?
在Vue中子组件是不能访问父组件的方法的,
如果子组件想要访问父组件的方法, 必须通过父组件传递

如何传递方法
1、在父组件中通过v-on传递方法
传递格式 v-on:自定义接收名称 = “要传递方法”
2、在子组件中自定义一个方法
3、在自定义方法中通过 this.$emit(‘自定义接收名称’);触发传递过来的方法

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><button @click="say">我是按钮</button><!--这里通过parentsay将父组件的say方法传递给了子组件--><son @parentsay="say"></son></div>
</template>
<template id="son"><div><button @click="sonFn">我是按钮</button></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",methods: {say(){alert("www.it666.com");}},// 子组件components: {"son": {template: "#son",/*注意点: 和传递数据不同, 如果传递的是方法, 那么在子组件中不需要接收如果传递的是方法, 那么需要在子组件中自定义一个方法如果传递的是方法, 那么在子组件中直接使用自定义的方法即可如果传递的是方法, 那么需要在子组件自定义的方法中通过this.$emit("自定义接收的名称")的方法来触发父组件传递过来的方法* */// props: ["parentsay"]methods: {sonFn(){this.$emit("parentsay");}}}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

子组件传递数据给父组件

如何将子组件数据传递给父组件

  • 既然我们可以将父组件的方法传递给子组件
  • 既然我们可以在子组件中调用父组件中的方法,
  • 那么我们就可以在调用方法的时候给方法传递参数
  • 传递的参数, 就是我们需要传递的数据

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><button @click="say">我是按钮</button><!--这里通过parentsay将父组件的say方法传递给了子组件--><son @parentsay="say"></son></div>
</template>
<template id="son"><div><button @click="sonFn">我是按钮</button></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",methods: {say(data){// alert("www.it666.com");console.log(data);}},// 子组件components: {"son": {template: "#son",methods: {sonFn(){// 第一个参数: 需要调用的函数名称// 后续的参数: 给调用的函数传递的参数this.$emit("parentsay", "知播渔");}}}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

组件命名注意点

组件中的命名注意点
1、注册组件的时候使用了"驼峰命名", 那么在使用时需要转换成"短横线分隔命名"
例如: 注册时: myFather -> 使用时: my-father
2、在传递参数的时候如果想使用"驼峰名称", 那么就必须写"短横线分隔命名"
例如: 传递时: parent-name=“name” -> 接收时: props: [“parentName”]
3、在传递方法的时候不能使用"驼峰命名", 只能用"短横线分隔命名"
@parent-say="say" -> this.$emit("parent-say")

html代码:

<div id="app"><my-father></my-father>
</div>
<template id="father"><div><p>{{name}}</p><button @click="say">我是按钮</button><son :parent-name="name" @parent-say="say"></son></div>
</template>
<template id="son"><div><p>{{parentName}}</p><button @click="sonFn">我是按钮</button></div>
</template>

vue代码:

// 父组件
Vue.component("myFather", {template: "#father",data: function(){return {name: "lnj"}},methods: {say(){console.log("www.it666.com");}},// 子组件components: {"son": {template: "#son",props: ["parentName"],methods: {sonFn(){this.$emit("parent-say");}}}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

组件多级传递

数据和方法的多级传递
在Vue中如果儿子想使用爷爷的数据, 必须一层一层往下传递
在Vue中如果儿子想使用爷爷的方法, 必须一层一层往下传递

html代码:

<div id="app"><grandfather></grandfather>
</div>
<template id="grandfather"><div><p>{{name}}</p><button @click="say">我是按钮</button><father :gfname="name" @gfsay="say"></father></div>
</template>
<template id="father"><div><p>{{gfname}}</p><button @click="fatherFn">我是按钮</button><son :fname="gfname" @fsay="fatherFn"></son></div>
</template>
<template id="son"><div><p>{{fname}}</p><button @click="sonFn">我是按钮</button></div>
</template>

vue代码:

// 爷爷组件
Vue.component("grandfather", {template: "#grandfather",data: function(){return {name: "lnj"}},methods: {say(){console.log("我是爷爷的方法");}},// 爸爸组件components: {"father": {template: "#father",props: ["gfname"],methods:{fatherFn(){this.$emit("gfsay");}},// 儿子组件components: {"son": {template: "#son",props: ["fname"],methods: {sonFn(){this.$emit("fsay");}},}}}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

匿名插槽

什么是插槽?
默认情况下使用子组件时在子组件中编写的元素是不会被渲染的
如果子组件中有部分内容是使用时才确定的, 那么我们就可以使用插槽
插槽就是在子组件中放一个"坑", 以后由父组件来"填"

什么是匿名插槽
没有名字的插槽, 会利用使用时指定的能容替换整个插槽

注意点:
如果有多个匿名插槽, 每一个匿名插槽都会被指定的内容替换
虽然写多个匿名插槽不会报错, 但是在企业开发中推荐只能有一个匿名插槽

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><!--需求: 在使用子组件的时候给子组件动态的添加一些内容--><son><!--注意点: 默认情况下是不能在使用子组件的时候, 给子组件动态的添加内容的如果想在使用子组件的时候, 给子组件动态的添加内容, 那么就必须使用插槽--><div>我是追加的内容1</div><div>我是追加的内容2</div><div>我是追加的内容3</div></son></div>
</template>
<template id="son"><div><div>我是头部</div><!--这里的slot标签就是插槽, 插槽其实就是一个坑只要有了这个坑, 那么以后使用者就可以根据自己的需要来填这个坑--><!--注意点: 插槽可以指定默认数据, 如果使用者没有填这个坑, 那么就会显示默认数据如果使用者填了这个坑, 那么就会利用使用者天坑的内容替换整个插槽--><!--注意点: 插槽是可以指定名称的, 默认情况下如果没有指定名称, 我们称之为 匿名插槽--><!--匿名插槽的特点: 有多少个匿名插槽, 填充的数据就会被拷贝几份虽然我们可以指定多个匿名插槽, 但是在企业开发中推荐只写一个匿名插槽--><slot>我是默认数据</slot>
<!--        <slot>我是默认数据</slot>--><div>我是底部</div></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",// 子组件components: {"son": {template: "#son",}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

具名插槽

什么是具名插槽
默认情况下有多少个匿名插槽, 我们填充的数据就会被拷贝多少份
这导致了所有插槽中填充的内容都是一样的
那么如果我们想给不同的插槽中填充不同的内容怎么办呢?
这个时候就可以使用具名插槽

具名插槽使用
通过插槽的name属性给插槽指定名称
在使用时可以通过slot="name"方式, 指定当前内容用于替换哪一个插槽

注意点: 如果没有指定要替换哪个插槽中的内容, 则不会被替换

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><son><!--这里通过slot属性告诉Vue,当前的内容是要填充到哪一个插槽中的--><div slot="one">我是追加的内容1</div><div slot="one">我是追加的内容11</div><div slot="two">我是追加的内容2</div><div slot="two">我是追加的内容22</div></son></div>
</template>
<template id="son"><div><div>我是头部</div><!--可以在定义插槽的时候给插槽添加一个name属性, 通过这个name属性来指定插槽的名称如通插槽指定了名称, 那么我们就称之为具名插槽--><!--注意点: 默认情况下填充的内容是不会被填充到具名插槽中的,只有给填充的内容指定了要填充到哪一个具名插槽之后,才会将填充的内容填充到具名插槽中--><slot name="one">我是默认内容</slot><slot name="two">我是默认内容</slot><div>我是底部</div></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",// 子组件components: {"son": {template: "#son",}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

组件 v-slot 指令

什么是v-slot指令?
v-slot指令是Vue2.6中用于替代slot属性的一个指令
在Vue2.6之前, 我们通过slot属性告诉Vue当前内容填充到哪一个具名插槽
从Vue2.6开始, 我们通过v-slot指令告诉Vue当前内容填充到哪一个具名插槽

注意点:
v-slot指令只能用在template标签上
可以使用#号替代v-slot:

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><son><!--这里通过slot属性告诉Vue,当前的内容是要填充到哪一个插槽中的--><!--<div slot="one">我是追加的内容1</div><div slot="one">我是追加的内容11</div><div slot="two">我是追加的内容2</div><div slot="two">我是追加的内容22</div>--><!--<template v-slot:one><div>我是追加的内容1</div><div>我是追加的内容11</div></template><template v-slot:two><div>我是追加的内容2</div><div>我是追加的内容22</div></template>--><!--v-bind: :  v-on: @--><template #one><div>我是追加的内容1</div><div>我是追加的内容11</div></template><template #two><div>我是追加的内容2</div><div>我是追加的内容22</div></template></son></div>
</template>
<template id="son"><div><div>我是头部</div><slot name="one">我是one默认内容</slot><slot name="two">我是two默认内容</slot><div>我是底部</div></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",// 子组件components: {"son": {template: "#son",}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

作用域插槽

什么是作用域插槽
作用域插槽就是带数据的插槽, 就是让父组件在填充子组件插槽内容时也能使用子组件的数据

如何使用作用域插槽
1、在slot中通过 v-bind:数据名称=“数据名称” 方式暴露数据
2、在父组件中通过 接收数据
3、在父组件的中通过 作用域名称.数据名称 方式使用数据

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><son><!--<div>我是填充的内容 {{names}}</div>--><!--slot-scope="abc"作用: 接收子组件插槽暴露的数据--><!--作用域插槽的应用场景: 子组件提供数据, 父组件决定如何渲染--><template slot-scope="abc"><!--<div>我是填充的内容 {{abc.names}}</div>--><li v-for="(name, index) in abc.names">{{name}}</li></template></son></div>
</template>
<template id="son"><div><div>我是头部 {{names}}</div><!--v-bind:names="names"作用: 将当前子组件的names数据暴露给父组件--><slot v-bind:names="names">我是默认内容 {{names}}</slot><div>我是底部</div></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",// 子组件components: {"son": {template: "#son",data:function () {return {names: ["zs", "ls", "ww", "zl"]}}}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

组件 v-slot 接收作用域插槽暴露的数据

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。
它取代了 slot 和 slot-scope

也就是说我们除了可以通过v-slot指令告诉Vue内容要填充到哪一个具名插槽中
还可以通过v-slot指令告诉Vue如何接收作用域插槽暴露的数据

v-slot:插槽名称=“作用域名称”

html代码:

<div id="app"><father></father>
</div>
<template id="father"><div><son><!--<template slot-scope="abc"><li v-for="(name, index) in abc.names">{{name}}</li></template>--><!--<template v-slot:default="abc"><li v-for="(name, index) in abc.names">{{name}}</li></template>--><!--<template #default="abc"><li v-for="(name, index) in abc.names">{{name}}</li></template>--><template #one="abc"><li v-for="(name, index) in abc.names">{{name}}</li></template></son></div>
</template>
<template id="son"><div><div>我是头部 {{names}}</div>
<!--        <slot v-bind:names="names">我是默认内容 {{names}}</slot>--><slot name="one" v-bind:names="names">我是默认内容 {{names}}</slot><div>我是底部</div></div>
</template>

vue代码:

// 父组件
Vue.component("father", {template: "#father",// 子组件components: {"son": {template: "#son",data:function () {return {names: ["zs", "ls", "ww", "zl"]}}}}
});
// 这里就是MVVM中的View Model
let vue = new Vue({el: '#app',// 这里就是MVVM中的Modeldata: {},// 专门用于存储监听事件回调函数methods: {},// 专门用于定义计算属性的computed: {},// 专门用于定义局部组件的components: {}
});

Vue2.X 自定义组件相关推荐

  1. vue 添加全局组件_自定义vue2.0全局组件(下篇)

    在上篇中,老K为大家介绍了一个初级自定义按钮组件的编写方法.虽然能用,但是还不算完美,可扩展性不够强大.在这一篇中,老K继续为大家完善这个按钮组件. 启动命令窗口, 进入在上篇中我们搭建的vue目录中 ...

  2. 【Vue2.0】— 组件的自定义事件(十八)

    [Vue2.0]- 组件的自定义事件(十八) <template><div ><h2>{{msg}}</h2><!-- 通过父组件给子组件传递函数 ...

  3. computed set 自定义参数_深入理解vmodel之自定义组件用法

    根据上一篇<深入理解 v-model 之表单用法>基本对 v-model 有了比较深的理解,接下来我们看看它如何在自定义组件中使用. 首先,我们知道下面两个用法等价的: <input ...

  4. Vue:自定义组件引入单页面+动态绑定图片

    Vue2,Vue3,动态绑定图片 通过自定义组件向单页面组件引入普通属性 component文件下的Header.vue: <template><div><h1>{ ...

  5. Vue3 高级语法以及自定义组件

    文章目录 1 .render函数 1. 1 h函数 1 .1 .1 h()函数的基本使用 1 .1 .2 h()函数中组件与插槽的使用 1 .2 jsx语法糖 1 .2 .1 jsx的配置(旧版本) ...

  6. 前端组件库(Element UI)的实现原理:教你如何实现自定义组件库,并打包发布至npm

    前端组件库实现原理 前言 Demo地址 一. 组件库开发流程 1)新建vue项目: 2)编写自定义组件,封装成插件: 3)修改配置项 webpack.config.js: pakage.json: 4 ...

  7. vue2知识点:组件的props属性、非props属性、props属性校验

    文章目录 3.10props属性 举例:父组件给子组件传递属性msg和greetText,子组件用属性a和b接收,并打印输出 3.11props校验 举例 3.12非props属性 举例:定义子组件设 ...

  8. vue 自定义组件双向数据绑定

    文章目录 序 属性&事件传值双向绑定 v-model组件双向绑定 .sync修饰符双向绑定 总结 !!!这边文章记录的是 vue2 的概念,vue3 对双向绑定进行了改动,不要把一下代码放到 ...

  9. vue自定义组件实现双向绑定

    场景: 我们比较常用的父子组件之间的交互方式: 父组件通过props将数据流入到子组件: 子组件通过$emit将更新后的数组发送的父组件: 今天,我们通过另一种方式实现交互,参考input框的v-mo ...

最新文章

  1. 百度之星试题每周一练
  2. Android应用程序键盘(Keyboard)消息处理机制分析(3)
  3. iOS逆向之深入解析App签名的双向验证机制和原理
  4. 计算机应用全能,全能计算助手
  5. 5个数中取三个数组合 不重复 php,PHP产生不重复随机数的5个方法总结
  6. 程序结构程序设计(三)
  7. BOOL与bool区别
  8. IAR移植FreeRTOS
  9. 360se html怎么删除,如何卸载360浏览器?怎么彻底删除360浏览器?
  10. 异常详细信息: System.ComponentModel.Win32Exception: 信号灯超时时间已到
  11. python官方文档(自翻译)
  12. 如何玩转腾讯云学生服务器(新手指南)
  13. RFM用户分层模型|原理+Python全流程实现
  14. NTT科学家武居博士:用光去开拓和改变世界
  15. 深度丨《纽约时报》两万字长文,深度剖析谷歌大脑简史
  16. (windows) node-sass 安装报错
  17. 118.网络安全渗透测试—[权限提升篇16]—[Windows MSF提权模块提权审计工具]
  18. php__file__用法,PHP 的常量__FILE__的用法图解
  19. html中波浪线线怎么设置,如何在PPT中加波浪线?
  20. Ubuntu18.04安装交叉编译工具链gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf

热门文章

  1. 联发科最新资料下载:MT6771 ATM’s
  2. 在本地计算机无法启动t6,急急急急用友T6启动服务显示依存服务或组无法启动105...
  3. 中国水资源现状分析,水资源人均占有率不足「图」
  4. 基于大数据的智慧城市环境气候图
  5. shell脚本系列-正则表达式介绍
  6. CF1468C Berpizza
  7. 使用微软云人工智能,合成带感情的语音
  8. C语言课设-----工资管理系统(附全部源码)
  9. opencv实现车牌提取
  10. 新浪微博MD5D签名生成器