使用不带 .vue 单文件组件

我们看到的大多数 Vue.js 组件示例都利用了 .vue 单文件组件。

这不是定义 Vue.js 组件的唯一方法。在本节中,我们将了解在不使用 .vue 文件的情况下定义 Vue.js 组件的四种不同方法。

评估这些选项将帮助我们了解 Vue.js 组件的核心是什么。

使用字符串模板的运行时定义

组件可以使用接受字符串值的模板属性。这通常称为字符串模板。该模板在运行时(在浏览器中)进行计算。

我们可以通过定义具有 template 属性的对象来在 StringTemplate.js 文件中定义组件:

export default {
    template: `<div>String Template Component</div>`
}

然后可以从 App.vue 文件中使用它,如下所示:

<template>
    <div id="app">
        <StringTemplate />
    </div>
</template>

<script>
import StringTemplate from './components/StringTemplate.js'

export default {
    components: {
        StringTemplate
    }
}
</script>

不幸的是,这会在加载时崩溃并在控制台中显示以下 Vue 警告:

image 2023 10 13 20 59 04 320
Figure 1. Figure 5.11: Vue runtime compiler missing warning

根据 Vue 警告,为了使该组件在导入时正常工作,我们需要在运行时构建中包含 Vue.js 编译器。为此,在 Vue CLI 项目中,我们可以在 vue.config.js(Vue CLI 配置文件)中将 runtimeCompiler 选项设置为 true。

你的 vue.config.js 应如下所示:

module.exports = {
    runtimeCompiler: true
};

设置此选项并重新启动开发服务器后,浏览器中会出现一条来自 StringTemplate 组件的消息:

String Template Component

Props 和其它组件实例属性可以使用 .vue 组件对象定义。

渲染函数

Vue.js 单文件组件模板(template)部分在构建时编译为渲染(render)函数。

渲染(render)函数往往用在 Vue CLI 项目的 main.js 文件中——具体来说,是 new Vue() 调用:

new Vue({
    render: h => h(App),
}).$mount('#app')

渲染(render)函数接受 createElement 参数并返回虚拟 DOM 节点。这是通过调用 createElement 函数来完成的(在前面的示例中,这是 h)。

由于其紧凑性,h 通常用作 createElement 的简写。

我们可以在 JavaScript 文件 (RenderFunction.js) 中定义一个具有 render 属性的组件,如下所示:

export default {
    render(createElement) {
        return createElement(
            'h2',
            'Render Function Component'
        )
    }
}

这可以在 App.vue 文件中渲染,如下所示:

<template>
    <div id="app">
        <RenderFunction />
    </div>
</template>
<script>
import RenderFunction from './components/RenderFunction.js'

export default {
    components: {
        RenderFunction
    }
}
</script>

该组件在浏览器中显示一个以 Render Function Component 为内容的 h2:

Render Function Component

除了在非 .vue 文件中编写组件之外,渲染(render)函数对于高度动态的组件也很有用。

JSX

JSX 因 React 而变得流行。根据 React 文档,JSX 是 JavaScript 的语法扩展。我们建议将它与 React 一起使用来描述 UI 应是什么样子 (https://reactjs.org/docs/introducing-jsx.html )。JSX 是 JavaScript 的超集,允许使用大括号进行 HTML 样式标记和插值。

React 与 Vue.js 一样,不会将 JSX 渲染到 DOM。与 Vue.js 模板一样,React 应用程序构建工具编译 JSX 以渲染运行时使用的函数,以便将它们渲染到虚拟 DOM。然后,虚拟 DOM 与真实 DOM 进行协调(同步)。

JSX 编译为渲染(render)函数,Vue.js 支持使用渲染(render)函数的组件定义。此外,Vue CLI 3+ 可以开箱即用地编译 JSX。

这意味着我们可以编写以下内容,相当于 RenderFunction 组件 JSXRender.js 文件:

export default {
    render() {
        return <h2>JSX Render Function Component</h2>
    }
}

没有 JSX 的等效渲染(render)函数如下所示(基于上一节的示例):

export default {
    render(createElement) {
        return createElement(
            'h2',
            'JSX Render Function Component'
        )
    }
}

以下 App.vue 文件将 JSXRender 渲染到浏览器:

<template>
    <div id="app">
        <JSXRender />
    </div>
</template>

<script>
import JSXRender from './components/JSXRender.js'

export default {
    components: {
        JSXRender
    }
}
</script>

现在,我们可以在屏幕上看到 JSXRender 的 h2 和预期内容:

JSX Render Function Component

至此,我们了解到 Vue.js 组件只是具有渲染(render)或模板(template)功能的对象。.vue 组件模板(template)部分在构建时被编译为 render 函数,这意味着要使用字符串模板,我们需要在应用程序运行时包含 Vue.js 编译器。我们还学习了如何使用 render 函数以及 JSX 来定义组件,并从实现的角度指出了 React 和 Vue.js 的一些共同点。在选择使用 JSX 还是渲染(render)函数时,JSX 更易于阅读,而且渲染函数具有充分的灵活性(普通模板并不总是具有这种灵活性)。

现在,我们将了解如何使用 Vue.js 组件(component)标签从运行时数据动态渲染组件。