内容简介:我们接着上篇学习完我们先封装一个简单的组件,叫做代码如下:
我们接着上篇学习完 render
函数,下面我们来看下 Vue
中的函数式组件
这也是 Vue
进阶中一个重要的知识点,下面我们一起来学习下吧(我也不是很熟:smile:,有错误就请指正)
组件封装阶段
我们先封装一个简单的组件,叫做 list
代码如下:
<template> <ul> <li v-for="(item, index) in list" :key="`item_${index}`"></li> </ul> </template> <script> export default { name: 'List', props: { list: { type: Array, default: () => [] } } } </script> 复制代码
简单封装后,里面 li
里面的内容我们先不管!
我们再新建一个叫做 render
的组件
我们把刚刚的 list
组件引入到 render
组件里
<template> <div> <list :list="list"></list> </div> </template> <script> import List from '../component/list' export default { data () { return { list: [ { name: lili}, { name: Dreams} ] } }, components: { List } } </script> 复制代码
接下来,我们回到 list
组件里完善下 li
标签里面的内容
<li v-for="(item, index) in list" :key="`item_${index}`"> <span>{{ item.name }}</span> </li> 复制代码
这样我们就把刚刚 render
组件里传递进来的 list
数据给 list
组件使用并且渲染出了名字,这里我们用 span
标签包裹了,那么如果我们想更多的让用户个性化,比如用户想用什么标签包裹就用什么标签包裹,怎么做呢?
那么这里我们就可以使用 render
函数,然后让用户通过 render
函数自己去定义,来看下怎么写
这里我们回到 render
组件,把 render
函数通过 v-bind
传递到 list
里去
render组件的代码: <template> <div> <list :list="list" :render="renderFunc"></list> </div> </template> <script> import List from '../component/list' export default { data () { return { list: [ { name: lili}, { name: Dreams} ] } }, components: { List }, methods:{ renderFunc(h){ return h('i',{ style:{ color:'pink' } },'???') } } } </script> 复制代码
上面我们想使用i标签包裹,且字体颜色为粉红色,但这里我们 打问号的地方
他的值是多少呢?怎么来呢,因为 list
中他是通过 v-for
循环的,
那么我们想知道当前循环的这个值是多少,那么这里我们就要用到一个组件叫做: 函数式组件
函数式组件开始
那么接着上面,我们先创建一个 render-dom.js
代码如下
export default { functional: true,//必须这样写才是一个函数式组件 props: { name: String, renderFunc: Function }, render: (h, ctx) => { //??? } } 复制代码
那么有人会问了,函数式组件有什么作用?
一般而言,我们只给它传入一些数据,它不做任何响应式的操作,不监听传递给他的状态,它也没有生命周期,它只是一个接收参数的函数,当设置 functional
为 true
时,它是一个没有状态的组件,但是当你把他引入到其他vue组件中去用的时候, vue
会把它做相关处理,上面我们写了一个 render
函数, vue
会用 render
函数里的逻辑,把里面返回的节点做渲染!
接着我们回到 list
组件,在 props
里接收父组件(render组件)传递过来的 render
函数
props处新增代码: render: { type: Function, default: () => {} } 复制代码
接下来,我们把函数式组件再完善下
把刚刚 render
方法里的逻辑完善下就是
render: (h, ctx) => { return ctx.props.renderFunc(h,ctx.props.name) } 复制代码
返回的 render
其实就是用户传进来的那个 render
ctx
他其实就指代当前的上下文,那么我们就可以用 ctx
获取到属性里的 renderFunc
接下来继续到 list
组件里使用renderDom函数式组件
模板中新增: <li v-for="(item, index) in list" :key="`item_${index}`"> <span v-if="!render">{{ item.number }}</span> <render-dom v-else :render-func="render" :name="item.name"></render-dom> </li> script引入: import RenderDom from '../component/render-dom' components: { //注册组件 RenderDom }, 复制代码
这里逻辑就是如果用户传入了render,我们就是用传入的render渲染,否则默认span
接下来我们回到render组件里把刚刚的render函数完善下:
renderFunc(h,name){ return h('i',{ style:{ color:'pink' } },name) } 复制代码
那么这里的name其实就是函数式组件返回的name,所以这里我们直接使用name
那么这样我们就完成了可以让用户自己定义这个文字该怎么样展现!render配合函数式组件就是这么灵活!
那么大家应该也发现了,render加函数式组件其实非常繁琐!那么有没有什么东西可以简化呢? 其实是有的, 那就是JSX!
JSX
JSX是React最先提出的,那么后来Vue也做了相关支持!他的本质其实就是在js中写html标签和一些特定的语法,最终呢他会把jsx转换成render函数去渲染。
接下来我们回到render组件里把刚刚的render函数修改下:
之前template是这样的: <list :list="list" :render="renderFunc"></list> 之前js是这样的: renderFunc(h,name){ return h('i',{ style:{ color:'pink' } },name) } 修改之后的template: <list :list="list" :render="renderFunc" :style="{color:'red'}"></list> 修改之后的js: renderFunc(h,name){ return ( <i style={{color:'red'}}>{name}</i> ) } 复制代码
这里要注意了,在jsx中,变量要用花括号包起来!里面是一个对象,然后又有一个花括号.因为name也是变量,所以也需要使用花括号包起来!
这样就完成了和刚刚render函数一样的功能!
如果我们想给i标签绑定一个事件,我们应该怎么绑定?
methods:{ renderFunc(h,name){ return ( <i on-click={this.handleClick} style={{color:'red'}}>{name}</i> ) }, handleClick(event){ console.log(event) } } 复制代码
这里还要注意,绑定事件必须是 on-
开头
那么普通的渲染标签我们会了,那么如果渲染一个组件呢?
渲染组件
那么这里假设我们这里有一个组件CountTo(看过上上篇文章的小伙伴应该知道)组件
我们把他引入到render组件(看过上篇文章的小伙伴应该知道这个组件)中. 再写一遍!
我们这里需要修改之前的一些代码:
render组件中修改后的:(函数式组件和list里需要做一部分修改,我相信大家可以的,就不罗列相关代码了)
<template> <div> <list :list="list" :style="{color: 'red'}"></list> </div> </template> <script> import List from '_c/list' import CountTo from '_c/count-to' export default { data () { return { list: [ { number: 100 }, { number: 45 } ] } }, components: { List }, methods: { renderFunc (h, number) { return ( <CountTo nativeOn-click={this.handleClick} on-on-animation-end={this.handleEnd} endVal={number} style={{color: 'pink'}}></CountTo> ) }, handleClick (event) { // console.log(event) }, handleEnd () { // console.log('end!') } } } </script> 复制代码
我们如果是在render或者jsx里写的组件是不需要进行注册的!
那么这里我们也使用了JSX做了相同的事情。其实这里还可以使用作用域插槽做同样的事情,这篇文章我们主要讲JSX和函数式组件,所以就不再举插槽相关的代码哦,有兴趣的可以下去自己试试!
总结
本篇文章我们一起学习了render+函数式组件,最终我们完成了之前的需求,但过程还是比较繁琐的,结尾我们也提到了JSX的解决方案, 感兴趣的小伙伴可以关注我,大家一起学习vue中比较难理解的知识点哦!
各位大佬,如果发现文中的错误,请指正,我会及时修改!
感谢大佬们能在百忙中能阅读完这篇文章!
再次总结
相信大家看完这篇文章后再去看vue文档就不会觉得那么吃力了!大家共勉!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 每日一题(开开森森学前端之Object系列)
- 每日一题(开开森森学前端之常见笔试题)
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端技术演进(三):前端安全
- 【前端优化】前端常见性能优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
郎咸平说:新经济颠覆了什么
郎咸平 / 东方出版社 / 2016-8 / 39.00元
正所谓“上帝欲其灭亡,必先令其疯狂”,在当下中国,“互联网+资本催化”的新经济引擎高速运转,大有碾压一切、颠覆一切之势。在新经济狂热之下,每个人都在全力以赴寻找“下一个风口”,幻想成为下一只飞起来的猪。 对此,一向以“危机论”著称的郎咸平教授再次发出盛世危言:新经济光环背后,危机已悄然而至!中国式O2O还能烧多久?P2P监管黑洞有多大?互联网造车为什么不靠谱?共享经济为什么徒有虚名?BAT为......一起来看看 《郎咸平说:新经济颠覆了什么》 这本书的介绍吧!