Vue render深入开发讲解

网友投稿 376 2023-02-08


Vue render深入开发讲解

简介

在使用vue进行开发的时候,大多数情况下都是使用template进行开发,使用template简单、方便、快捷,可是有时候需要特殊的场景使用template就不是很适合。因此为了很好使用render函数,我决定深入窥探一下。各位看官如果觉得下面写的有不正确之处还望看官指出,你们与我的互动就是写作的最大动力。

场景

官网描述的场景当我们开始写一个通过 level prop 动态生成 heading 标签的组件,你可能很快想到这样实现:

Vue.component('anchored-heading', {

template: '#anchored-heading-template',

props: {

level: {

type: Number,

required: true

}

}

})

在这种场景中使用 template 并不是最好的选择:首先代码冗长,为了在不同级别的标题中插入锚点元素,我们需要重复地使用

虽然模板在大多数组件中都非常好用,但是在这里它就不是很简洁的了。那么,我们来尝试使用 render 函数重写上面的例子:

Vue.component('anchored-heading', {

render: function (createElement) {

return createElement(

'h' + this.level, // tag name 标签名称

this.$slots.default // 子组件中的阵列

)

},

props: {

level: {

type: Number,

required: true

}

}

})

简单清晰很多!简单来说,这样代码精简很多,但是需要非常熟悉 Vue 的实例属性。在这个例子中,你需要知道当你不使用 slot 属性向组件中传递内容时,比如 anchored-heading 中的 Hello world!,这些子元素被存储在组件实例中的 $slots.default中。

createElement参数介绍

接下来你需要熟悉的是如何在 createElement 函数中生成模板。这里是 createElement 接受的参数:

createElement(

// {String | Object | Function}

// 一个 HTML 标签字符串,组件选项对象,或者

// 解析上述任何一种的一个 async 异步函数,必要参数。

'div',

// {Object}

// 一个包含模板相关属性的数据对象

// 这样,您可以在 template 中使用这些属http://性。可选参数。

{

// (详情见下一节)

},

// {String | Array}

// 子节点 (VNodes),由 `createElement()` 构建而成,

// 或使用字符串来生成“文本节点”。可选参数。

[

'先写一些文字',

createElement('h1', '一则头条'),

createElement(MyComponent, {

props: {

someProp: 'foobar'

}

})

]

)

深入 data 对象

有一件事要注意:正如在模板语法中,v-bind:class 和 v-bind:style ,会被特别对待一样,在 VNode 数据对象中,下列属性名是级别最高的字段。该对象也允许你绑定普通的 HTML 特性,就像 DOM 属性一样,比如 innerHTML (这会取代 v-html 指令)。

{

// 和`v-bind:class`一样的 API

'class': {

foo: true,

bar: false

},

// 和`v-bind:style`一样的 API

style: {

color: 'red',

fontSize: '14px'

},

// 正常的 HTML 特性

attrs: {

id: 'foo'

},

// 组件 props

props: {

myProp: 'bar'

},

// DOM 属性

domProps: {

innerHTML: 'baz'

},

// 事件监听器基于 `on`

// 所以不再支持如 `v-on:keyup.enter` 修饰器

// 需要手动匹配 keyCode。

on: {

click: this.clickHandler

},

// 仅对于组件,用于监听原生事件,而不是组件内部使用

// `vm.$emit` 触发的事件。

nativeOn: {

click: this.nativeClickHandler

},

// 自定义指令。注http://意,你无法对 `binding` 中的 `oldValue`

// 赋值,因为 Vue 已经自动为你进行了同步。

directives: [

{

name: 'my-custom-directive',

value: '2',

expression: '1 + 1',

arg: 'foo',

modifiers: {

bar: true

}

}

],

// Scoped slots in the form of

// { name: props => VNode | Array }

scopedSlots: {

default: props => createElement('span', props.text)

},

// 如果组件是其他组件的子组件,需为插槽指定名称

slot: 'name-of-slot',

// 其他特殊顶层属性

key: 'myKey',

ref: 'myRef'

}

条件渲染

既然熟读以上api接下来咱们就来点实战。

之前这样写

//HTML

//js

//组件形式

Vue.component('vv-isshow', {

props:['show'],

template:'

});

var vm = new Vue({

el: "#app",

data: {

isShow:true

}

});

render这样写

//HTML

我被你发现啦3!!!

//js

//组件形式

Vue.component('vv-isshow', {

props:{

show:{

type: Boolean,

default: true

}

},

render:function(h){

if(this.show ) return h('div',this.$slots.default);

},

});

var vm = new Vue({

el: "#app",

data: {

isShow:true

}

});

列表渲染

之前是这样写的,而且v-for 时template内必须被一个标签包裹

//HTML

//js

//组件形式

Vue.component('vv-aside', {

props:['list'],

methods:{

handelClick(item){

console.log(item);

}

},

template:'

//template:'

});

var vm = new Vue({

el: "#app",

data: {

list: [{

id: 1,

txt: 'javascript',

odd: true

}, {

id: 2,

txt: 'Vue',

odd: false

}, {

id: 3,

txt: 'React',

odd: true

}]

}

});

render这样写

//HTML

//js

//侧边栏

Vue.component('vv-aside', {

render: function(h) {

var _this = this,

ayy = this.list.map((v) => {

return h('div', {

'class': {

odd: v.odd

},

attrs: {

title: v.txt

},

on: {

click: function() {

return _this.handelClick(v);

}

}

}, v.txt);

});

return h('div', ayy);

},

props: {

list: {

type: Array,

default: () => {

return this.list || [];

}

}

},

methods: {

handelClick: function(item) {

console.log(item, "item");

}

}

});

var vm = new Vue({

el: "#app",

data: {

list: [{

id: 1,

txt: 'javaScript',

odd: true

}, {

id: 2,

txt: 'Vue',

odd: false

}, {

id: 3,

txt: 'React',

odd: true

}]

}

});

v-model

之前的写法

//HTML

//js

//input

Vue.component('vv-models', {

props: ['txt'],

template: '

看官你输入的是:{{txtcout}}

\

computed: {

txtcout:{

get(){

return this.txt;

},

set(val){

this.$emit('input', val);

}

}

}

});

var vm = new Vue({

el: "#app",

data: {

YDbCRgiKwf txt: '',

}

});

render这样写

//HTML

//js

//input

Vue.component('vv-models', {

props: {

txt: {

type: String,

default: ''

}

},

render: function(h) {

var self=this;

return h('div',[h('p','你猜我输入的是啥:'+this.txt),h('input',{

on:{

input(event){

self.$emit('input', event.target.value);

}

}

})] );

},

});

var vm = new Vue({

el: "#app",

data: {

txt: '',

}

});

总结

render函数使用的是JavaScript 的完全编程的能力,在性能上是占用绝对的优势,只是对http://它进行剖析。至于实际项目你选择那种方式进行渲染依旧需要根据你的项目以及实际情况而定。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何管理api接口(如何管理api接口设置)
下一篇:vue组件的写法汇总
相关文章

 发表评论

暂时没有评论,来抢沙发吧~