vue单页面引入CDN链接

vue

不想在index.html文件中全局引入CDN资源,那么如何在Vue单文件组件中引入?下面来瞅瞅~

虚拟DOM创建

Vue 通过创建一个虚拟 DOM 来追踪自己要改变的真实 DOM

  • 什么是虚拟DOM?

return createElement('h1', this.blogTitle)

createElement实际返回的是createNodeDescription而非实际上的DOM元素,因为它所包含的信息会告诉Vue页面上需要渲染什么样的节点,包括及其子节点的描述信息。这样的节点称为“虚拟节点 (virtual node)”,也常简写为“VNode”。“虚拟 DOM”是整个 VNode 树(由 Vue 组件树建立起来)的称呼。

  • createElement函数参数

createElement函数中可以使用模板中的功能,它接收的参数有:

// @returns {VNode}

createElement(

// {String | Object | Function}

// 一个 HTML 标签名、组件选项对象,或者

// resolve 了上述任何一种的一个 async 函数。必填项。

'div',

// {Object}

// 一个与模板中属性对应的数据对象。可选。

{

// 与 `v-bind:class` 的 API 相同,

// 接受一个字符串、对象或字符串和对象组成的数组

'class': {

foo: true,

bar: false

},

// 与 `v-bind:style` 的 API 相同,

// 接受一个字符串、对象,或对象组成的数组

style: {

color: 'red',

fontSize: '14px'

},

// 普通的 HTML 特性

attrs: {

id: 'foo'

},

// 组件 prop

props: {

myProp: 'bar'

},

// DOM 属性

domProps: {

innerHTML: 'baz'

},

// 事件监听器在 `on` 属性内,

// 但不再支持如 `v-on:keyup.enter` 这样的修饰器。

// 需要在处理函数中手动检查 keyCode。

on: {

click: this.clickHandler

},

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

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

nativeOn: {

click: this.nativeClickHandler

},

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

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

directives: [

{

name: 'my-custom-directive',

value: '2',

expression: '1 + 1',

arg: 'foo',

modifiers: {

bar: true

}

}

],

// 作用域插槽的格式为

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

scopedSlots: {

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

},

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

slot: 'name-of-slot',

// 其它特殊顶层属性

key: 'myKey',

ref: 'myRef',

// 如果你在渲染函数中给多个元素都应用了相同的 ref 名,

// 那么 `$refs.myRef` 会变成一个数组。

refInFor: true

},

// {String | Array}

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

// 也可以使用字符串来生成“文本虚拟节点”。可选。

[

'先写一些文字',

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

createElement(MyComponent, {

props: {

someProp: 'foobar'

}

})

]

)


渲染函数render

Vue 推荐在绝大多数情况下使用模板来创建HTML,然而在一些场景中,你需要发挥 JavaScript 最大的编程能力,这时可以用渲染函数,它比模板更接近编译器。

  • 类型

(createElement: () => VNode) => VNode

渲染函数接收一个createElement方法作为第一个参数来创建VNode;如果组件是一个函数组件,渲染函数还会接收一个额外的 context 参数,为没有实例的函数组件提供上下文信息。

例子:假设我们要生成一些带锚点的标题

<h1>

<a name="hello-world" href="#hello-world">

Hello world!

</a>

</h1>

  • 模板实现

<anchored-heading :level="1">Hello world!</anchored-heading>

<script type="text/x-template" >

<h1 v-if="level === 1">

<slot></slot>

</h1>

<h2 v-else-if="level === 2">

<slot></slot>

</h2>

<h3 v-else-if="level === 3">

<slot></slot>

</h3>

<h4 v-else-if="level === 4">

<slot></slot>

</h4>

<h5 v-else-if="level === 5">

<slot></slot>

</h5>

<h6 v-else-if="level === 6">

<slot></slot>

</h6>

</script>

Vue.component('anchored-heading', {

template: '#anchored-heading-template',

props: {

level: {

type: Number,

required: true

}

}

})

这里用模板并不是最好的选择:不但代码冗长,而且在每一个级别的标题中重复书写了<slot></slot>,在要插入锚点元素时还要再次重复。

  • render实现

<anchored-heading :level="1">Hello world!</anchored-heading>

Vue.component('anchored-heading', {

render: function (createElement) {

return createElement(

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

this.$slots.default // 子节点数组

)

},

props: {

level: {

type: Number,

required: true

}

}

})

这样代码就精简很多,需要注意的是向组件中传递不带v-slot指令的子节点时,比如anchored-heading中的 Hello world!,这些子节点被存储在组件实例中的$slots.default中。

Vue单页面引入CDN链接

在了解了render函数createElement函数的基础上,想要实现Vue单页面引入CDN链接就简单很多了。

  • 首先采用createElement创建不同资源类型(以js、css为例)的VNode

// js CDN

createElement('script', {

attrs: {

type: 'text/javascript',

src: this.cdn

}

})

// css CDN

createElement('link', {

attrs: {

rel: 'stylesheet',

type: 'text/css',

href: this.cdn

}

})

  • 然后基于上述VNode,采用render创建函数式组件remote-jsremote-css

components: {

'remote-js': {

render(createElement) {

return createElement('script', {

attrs: {

type: 'text/javascript',

src: this.cdn

}

})

},

props: {

cdn: {

type: String,

required: true

}

}

},

'remote-css': {

render(createElement) {

return createElement('link', {

attrs: {

rel: 'stylesheet',

type: 'text/css',

href: this.cdn

}

})

},

props: {

cdn: {

type: String,

required: true

}

}

}

}

  • Vue单页面引入

<template>

<div class="my-page">

<remote-js cdn="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></remote-js>

<remote-css cdn="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css"></remote-css>

</div>

</template>

  • 彩蛋(=。=)

如果你觉得render函数写起来很费劲的话,就可以利用Bable插件,在Vue 中使用 JSX ,让我们可以无限接近于模板语法。上述代码就变成下面这样了,好像是顺眼了一丢丢吧:

components: {

'remote-js': {

render(h) {

return (

<script type= 'text/javascript' src={this.cdn}></script>

)

},

props: {

cdn: {

type: String,

required: true

}

}

},

'remote-css': {

render(h) {

return (

<link rel='stylesheet' type='text/css' href={this.cdn} />

)

},

props: {

cdn: {

type: String,

required: true

}

}

}

}

Ps:将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。

最终效果就是只有访问当前页(my-page)时,CDN资源才会加载,不会像以前放在index.htmlmain.js中那样全局加载。

参考资料

1、render:https://cn.vuejs.org/v2/guide/render-function.html

2、createElement:https://cn.vuejs.org/v2/guide/render-function.html#createElement-%E5%8F%82%E6%95%B0

3、如何在VUE单页面引入CSS、JS(CDN链接):https://blog.csdn.net/kielin/article/details/86649074

以上是 vue单页面引入CDN链接 的全部内容, 来源链接: utcz.com/z/380204.html

回到顶部