这次我们来学习slot这个概念。‍‍
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_插槽

代码解读:

首先我定义一个组件叫做form,然后我去使用 form 组件,‍‍ form 组件它展示的是比如说input框,你可以填写一些内容,‍‍
然后我们有一个submit这样的按钮,写个button,提交‍‍。

【第28行】这块我们写一个onClick等于handleClick。‍‍
这块我们写一个methods,handleClick,‍‍​​​alert(123)​​。

执行代码会报错:

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_02

我们看哪里写错了,‍‍它说你不要用 form 原生的这样的一个东西作为组件的名字,我可以改一下,‍‍换一个名字把它叫做myform,

代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_vue.js_03

再次执行,点击提交,这块它会打印错误说‍‍死循环了:

猿创征文 | 使用插槽解决组件内容传递问题(1)_vue.js_04

我们看一下哪里死循环了。

修改代码:【第28行】

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_05

handleClick methods这块【第28行】,我写成原声的事件了,在Vue里面是不是应该用​​@click="handleClick"​​,这么写才对,

再次执行代码,点击提交,‍‍我们能打印出123没问题:

猿创征文 | 使用插槽解决组件内容传递问题(1)_javascript_06

回到我的代码里面,我有这样的一个需求,我希望现在‍‍你的按钮它是什么样子的呢?

不是固定的,比如说‍‍你现在都要我的时候想让它展示成一个button,那么我就展示 button,比如说你让我展示一个div,这样去写:

代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_插槽_07

我这块就展示一个div,什么意思?
把上述代码示例再写成这个样子:

猿创征文 | 使用插槽解决组件内容传递问题(1)_vue.js_08

我们再来看现在有两个这样的input框,两个提交:

猿创征文 | 使用插槽解决组件内容传递问题(1)_代码示例_09

现在都是一样的功能,我希望上面 myform 去使用我组件的时候【第15行】,这块的提交是一个div,
而下面的myform使用我组件的时候,它的提交是一个button,‍‍

现在这么去写是不是就实现不了了,使用slot这样的语法就能解决我们的问题,我们看一下slot怎么写。‍‍
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_插槽_10

首先我把一个单标签写成一个双标签,下面也是一样的写成一个双标签,‍‍
然后我在这里定一个内容,比如说我希望第一个组件用的时候,它的提交按钮是一个div,所以我就写一个div提交。‍‍
第二个标签调用组件的时候,我希望它展示一个button,那么我就这么去写button提交,‍‍我能用一个双标签把我想要传递给子组件的一些内容包在这个标签里面,‍‍这块写的东西我们就把它叫做一个slot插槽,‍‍为什么叫做插槽?‍‍

我们可以看到,因为你是插在两个标签里面的,写在调用子组件‍‍这个标签内部的一个东西,插入里面的东西,所以我们把它叫做一个插槽,

我通过插槽已经把我的 dom 标签插到子组件里面了,子组件我怎么去用这个插槽呢?‍‍

其实很简单,我只需要在子组件里面不再使用下面这个提交按钮了,取而代之我用一个标签,这个标签叫做slot‍‍:
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_11

执行代码,刷新浏览器:

猿创征文 | 使用插槽解决组件内容传递问题(1)_javascript_12

你会发现第一个组件用的提交是不是一个字符串,
而第二个组件用的提交就变成了一个button按钮 对不对?‍‍怎么做到?

是因为你上面调组件的时候,插槽插入了不同的内容,‍‍而在下面我写的不再是我组件固定的一个button或者div了,我用的是你的插槽传递过来的数据,‍‍怎么去用?
通过slot这样的一个标签去用就可以了。‍‍但是在使用slot的时候有一个点大家要注意一下,‍‍slot是没有办法直接绑定事件的,
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_vue.js_13

比如说我想在这上面去绑定一个​​@click​​​事件,
你可以在外层包一个span标签,‍‍然后我们在span标签上面去绑定一个click事件,让它等于handleClick就可以解决这个问题,‍‍
执行代码,刷新浏览器:

猿创征文 | 使用插槽解决组件内容传递问题(1)_javascript_14

点提交都可以正确的执行。‍‍
通过这个例子我们就能够知道slot这个插槽它的意思是什么了。

当我涉及到一些组件之间传值的时候,‍‍以前我们可以通过 props 的形式
但是传递dom如果这么传写起来实在太复杂了,‍‍或者传递起来太麻烦了,

在Vue里面给我们提供了一个插槽的概念,‍‍如果我们父组件想往子组这里传递一些dom节点或者元素标签的时候,我没必要通过属性的方式去传,‍‍直接把这些元素写在这个标签中间就可以了。‍‍

代码案例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_15

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_15

子组件想去调用你传递过来的这些标签怎么去调用?
直接通过一个slot插槽的方式‍‍去调你传递过来的内容即可。‍‍

插槽里面除了可以传这个标签之外,其实它还可以传一些比如字符串,‍‍
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_17

效果:

猿创征文 | 使用插槽解决组件内容传递问题(1)_vue.js_18

这都是可以的。‍‍除了字符串和刚才我们写到的这种标签之外,它还可以传一些子组件,
比如我再定一个非常简单的子组件,‍‍非常简单app.component叫test这样的一个组件,
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_插槽_19

我里面只有一个template,那就是一个div test。‍‍在这里我还可以把 test的组件直接传下去,看下效果:

猿创征文 | 使用插槽解决组件内容传递问题(1)_前端_20

没有任何的问题。‍‍

通过这个例子,把slot这个概念先理解了,然后我们继续往下再去讲更复杂的内容。‍‍

使用 slot 的时候,有的时候文案是什么,我希望可定制,‍‍那么我可以在data里面去定一个数据,现在我的文案是提交是写死的对不对?假设我让它可以定制,‍‍数据变化自动跟着变,我该怎么写?
代码示例:

猿创征文 | 使用插槽解决组件内容传递问题(1)_javascript_21

代码解读:

我就可以在这里写一个data,我们可以写个text,它叫做提交。‍‍
然后在这里面我们去用text就可以了【插值表达式】,看下效果:

猿创征文 | 使用插槽解决组件内容传递问题(1)_vue.js_22

没有任何的问题,实现的是一样的效果。‍‍
通过这个例子,当我去向子组件插入一些内容的时候,‍‍我这个模板实际上是放在子组件里面会替换掉 slot 的,

那么大家会想 text‍‍它是不是用的是子组件里面的 text?
实际上不是的,大家刚才也能看到,虽然说‍‍你传递给子组件这个东西会替换掉slot,

但是你传递过来的‍‍标签里面如果有一些变量的话,它不会用子组件里的变量,而会用父组件作用域里面的 text 的数据变量,‍‍

这块大家可以这么样的去方便你记忆,父模板里调用的数据属性,‍‍使用的都是父模板里的数据,同样的子模板里‍‍调用的数据属性,使用的都是子模板里调用的数据。‍‍

我们来看你虽然这个东西‍‍是要传递给子组件替换掉 slot的,
但是我们来看你现在的变量现在‍‍它直观上来看到底是写在你的父模板里,还是写在你的子模板里?

很显然子模板里现在并没有它,你是把这个标签写在父模板里的,如果在父模板里,text就从哪里拿?
就从父模板里的数据里拿。‍‍

比如说下面你写的不是slot,你写的是这样的一个text:

猿创征文 | 使用插槽解决组件内容传递问题(1)_javascript_23

那么这个text从哪拿?它在子组件的子模板里,所以它会从子组件的data里面拿,‍‍所以大家这么记就行了,我们要直观的去看,现在这个text到底是在你父组件的模板里,还是在子组件的模板里,‍‍如果它现在就是在父组件的模板里,那么它调用的数据就一定是父模板里的 text的数据,‍‍这块就是 slot 中使用的数据作用域的问题。