Vue与传统HTML:核心差异解析

发表时间: 2024-06-20 14:16

在 HTML 的世界里,我们想创建一个面板,包括标题和文本。你可以像这样创建:

<div class="panel">    <div class="panel__header">Title</div>    <div class="panel__body">        Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, sit!    </div></div>

通过应用 CSS 和 JavaScript 到这些类,我们可以重复使用这段 HTML。这得益于类的存在,这也是像 Bootstrap 这样的 CSS 框架多年来运作的方式。 现在让我们看看 Vue 是如何处理可重用性的: 创建 Vue 组件 首先,我们需要在一个组件中创建一个基础的面板类。 创建 Panel.vue 组件:

<template><div>    <div class="header">Title</div>    <div class="body">        Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, sit!    </div></div></template><script>export default {}</script>

注意,我们可以消除一些类,因为我们的 CSS 将被限制在这个组件内部,同时 header 明确指向面板的头部。

现在,不再重复这个 HTML 块,而是在需要的地方导入这个组件。

在 App.vue 中添加两个面板组件

<template><div>    <Panel />    <Panel /></div></template><script>import Panel from './Panel.vue'export default {    components: { Panel },}</script>

这种关注点的分离非常好,因为我们不再有各种嵌套的 div 容器,而是仅仅使用了 Panel,使得我们的模板非常易于理解。 动态 Props 但是等等!像这样,标题和内容将始终保持不变。没错,所以我们需要让这些属性是动态的。 为此,我们需要让父组件(App.vue)将标题和内容传递给子组件(Panel.vue)。子组件通过 props 定义它接受的属性。 Props 在 Panel.vue 中:

<template><div>    <div class="header">{{ title }}</div>    <div class="body">{{ body }}</div></div></template><script>export default {    props: {        title: {            type: String,            required: true,        },        body: String,    }}</script>

我们的组件接受两个 props。title 必须是字符串并且是必需的,body 也是一个字符串,但不一定是必需的。

App.vue 现在可以将 props 传递给面板组件:

<template><div>   <Panel title="Lorem Ipsum" body="Lorem ipsum dolor sit amet" />   <Panel title="Something else" /></div></template><script>import Panel from './Panel.vue'export default {    components: { Panel },}</script>

Props 与普通 HTML 属性非常相似。

样式

现在,某些面板特别重要,它们的背景颜色需要突出显示。在 HTML 中,现在我们要为面板添加一个 modifier 类并进行样式设置。

让我们添加类 panel--primary:

<div class="panel panel--primary">    <div class="panel__header">Title</div>    <div class="panel__body">        Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, sit!    </div></div>

在 Vue 中,这将简单地成为另一个 prop。

在 Panel.vue 中:

<template><div :class="{primary: isPrimary}">    <div class="header">{{ title }}</div>    <div class="body">{{ body }}</div></div></template><script>export default {    props: {        title: "String,"        body: String,        isPrimary: {            type: Boolean,            default: false,        },    }}</script><style scoped>    .primary {        background-color: #369; /* you might as well have a global CSS rule for the background color */    }</style>

我们在 props 列表中添加了 isPrimary prop。注意如何将其默认为 false。现在,只需在实际需要主要面板时传递 isPrimary prop。

在 App.vue 中:

<template><div>   <Panel isPrimary title="Lorem Ipsum" body="Lorem ipsum dolor sit amet" />   <Panel title="Something else" body="Lorem ipsum dolor sit amet" /></div></template><script>import Panel from './Panel.vue'export default {    components: { Panel },}</script>

传递数据作为 Props

到目前为止,我们只向子组件传递了字符串。但是当我们需要传递其他数据时会发生什么呢?

在 App.vue 中,将标题和内容定义为实际数据,并尝试将其传递给子组件。

<template><div>   <Panel isPrimary title="title" body="body" /></div></template><script>import Panel from './Panel.vue'export default {    components: { Panel },    data() {        return {            title: 'Lorem Ipsum',            body: 'Lorem ipsum dolor sit amet',        }    }}</script>

上述代码将不起作用。它将字面传递字符串 title 和 body,而不是变量的内容。为了修复这个问题,我们必须在 prop 前添加一个前缀。因此,我们只需更改 App.vue 的模板部分:

<template><div>   <Panel :title="title" :body="body" /></div></template>

实际上,你可以简化以上模板,简单地使用:

<template><div>   <Panel :title="title" :body="body" /></div></template>

事实上,v-bind 允许任何 JavaScript 表达式。 总结 通过 Vue 组件,我们实现了 HTML 中面板的重用,并将其做了进一步的改进,使得标题和内容可以动态传递。通过 props 和 slots 的使用,我们能够更加灵活地构建和组织我们的界面组件。