优化排名对网站不好,标书制作收费标准,wordpress tax input,最简单的网站模板青少年编程与数学 02-006 前端开发框架VUE 16课题、组件基础 一、定义一个组件二、使用组件三、传递 props四、监听事件五、通过插槽来分配内容六、动态组件七、DOM 内模板解析注意事项1、大小写区分2、闭合标签3、元素位置限制 课题摘要:本文介绍了Vue.js中的组件基础#xf… 青少年编程与数学 02-006 前端开发框架VUE 16课题、组件基础 一、定义一个组件二、使用组件三、传递 props四、监听事件五、通过插槽来分配内容六、动态组件七、DOM 内模板解析注意事项1、大小写区分2、闭合标签3、元素位置限制 课题摘要:本文介绍了Vue.js中的组件基础包括组件的定义、使用、props传递、事件监听、插槽分配内容以及动态组件。组件允许将UI划分为独立、可重用的部分通常以单文件组件SFC的形式组织。通过script setup和template标签定义组件使用ref和defineProps等API管理状态和props。组件可以通过props接收数据并通过$emit抛出事件与父组件通信。使用slot元素分配内容实现内容的插入。动态组件允许在多个组件间切换使用:is属性控制显示哪个组件。文章还讨论了DOM内模板解析的注意事项如大小写敏感性和闭合标签的要求。这些基础知识为构建Vue应用提供了必要的理解。 本文内容主要来自官方文档并进行了适当删减有需要请参看原文。
组件允许我们将 UI 划分为独立的、可重用的部分并且可以对每个部分进行单独的思考。在实际应用中组件常常被组织成一个层层嵌套的树状结构 这和我们嵌套 HTML 元素的方式类似Vue 实现了自己的组件模型使我们可以在每个组件内封装自定义内容与逻辑。Vue 同样也能很好地配合原生 Web Component。
一、定义一个组件
当使用构建步骤时我们一般会将 Vue 组件定义在一个单独的 .vue 文件中这被叫做[单文件组件](简称 SFC)
script setup
import { ref } from vueconst count ref(0)
/scripttemplatebutton clickcountYou clicked me {{ count }} times./button
/template当不使用构建步骤时一个 Vue 组件以一个包含 Vue 特定选项的 JavaScript 对象来定义
import { ref } from vueexport default {setup() {const count ref(0)return { count }},template: button clickcountYou clicked me {{ count }} times./button// 也可以针对一个 DOM 内联模板// template: #my-template-element
}这里的模板是一个内联的 JavaScript 字符串Vue 将会在运行时编译它。你也可以使用 ID 选择器来指向一个元素 (通常是原生的 template 元素)Vue 将会使用其内容作为模板来源。
上面的例子中定义了一个组件并在一个 .js 文件里默认导出了它自己但你也可以通过具名导出在一个文件中导出多个组件。
二、使用组件
我们会在接下来的指引中使用单文件组件语法无论你是否使用构建步骤组件相关的概念都是相同的。[示例]一节中展示了两种场景中的组件使用情况。
要使用一个子组件我们需要在父组件中导入它。假设我们把计数器组件放在了一个叫做 ButtonCounter.vue 的文件中这个组件将会以默认导出的形式被暴露给外部。
script setup
import ButtonCounter from ./ButtonCounter.vue
/scripttemplateh1Here is a child component!/h1ButtonCounter /
/template通过 script setup导入的组件都在模板中直接可用。
当然你也可以全局地注册一个组件使得它在当前应用中的任何组件上都可以使用而不需要额外再导入。关于组件的全局注册和局部注册两种方式的利弊我们放在了[组件注册]这一章节中专门讨论。
组件可以被重用任意多次
h1Here is a child component!/h1
ButtonCounter /
ButtonCounter /
ButtonCounter /你会注意到每当点击这些按钮时每一个组件都维护着自己的状态是不同的 count。这是因为每当你使用一个组件就创建了一个新的实例。
在单文件组件中推荐为子组件使用 PascalCase 的标签名以此来和原生的 HTML 元素作区分。虽然原生 HTML 标签名是不区分大小写的但 Vue 单文件组件是可以在编译中区分大小写的。我们也可以使用 / 来关闭一个标签。
如果你是直接在 DOM 中书写模板 (例如原生 template 元素的内容)模板的编译需要遵从浏览器中 HTML 的解析行为。在这种情况下你应该需要使用 kebab-case 形式并显式地关闭这些组件的标签。
!-- 如果是在 DOM 中书写该模板 --
button-counter/button-counter
button-counter/button-counter
button-counter/button-counter三、传递 props
如果我们正在构建一个博客我们可能需要一个表示博客文章的组件。我们希望所有的博客文章分享相同的视觉布局但有不同的内容。要实现这样的效果自然必须向组件中传递数据例如每篇文章标题和内容这就会使用到 props。
Props 是一种特别的 attributes你可以在组件上声明注册。要传递给博客文章组件一个标题我们必须在组件的 props 列表上声明它。这里要用到 [defineProps]宏
!-- BlogPost.vue --
script setup
defineProps([title])
/scripttemplateh4{{ title }}/h4
/templatedefineProps 是一个仅 script setup 中可用的编译宏命令并不需要显式地导入。声明的 props 会自动暴露给模板。defineProps 会返回一个对象其中包含了可以传递给组件的所有 props
const props defineProps([title])
console.log(props.title)如果你没有使用 script setupprops 必须以 props 选项的方式声明props 对象会作为 setup() 函数的第一个参数被传入
export default {props: [title],setup(props) {console.log(props.title)}
}一个组件可以有任意多的 props默认情况下所有 prop 都接受任意类型的值。
当一个 prop 被注册后可以像这样以自定义 attribute 的形式传递数据给它
BlogPost titleMy journey with Vue /
BlogPost titleBlogging with Vue /
BlogPost titleWhy Vue is so fun /在实际应用中我们可能在父组件中会有如下的一个博客文章数组
const posts ref([{ id: 1, title: My journey with Vue },{ id: 2, title: Blogging with Vue },{ id: 3, title: Why Vue is so fun }
])这种情况下我们可以使用 v-for 来渲染它们
BlogPostv-forpost in posts:keypost.id:titlepost.title/留意我们是如何使用 [v-bind 语法] (:titlepost.title) 来传递动态 prop 值的。当事先不知道要渲染的确切内容时这一点特别有用。
四、监听事件
让我们继续关注我们的 BlogPost 组件。我们会发现有时候它需要与父组件进行交互。例如要在此处实现无障碍访问的需求将博客文章的文字能够放大而页面的其余部分仍使用默认字号。
在父组件中我们可以添加一个 postFontSize ref 来实现这个效果
const posts ref([/* ... */
])const postFontSize ref(1)在模板中用它来控制所有博客文章的字体大小
div :style{ fontSize: postFontSize em }BlogPostv-forpost in posts:keypost.id:titlepost.title/
/div然后给 BlogPost 组件添加一个按钮
!-- BlogPost.vue, 省略了 script --
templatediv classblog-posth4{{ title }}/h4buttonEnlarge text/button/div
/template这个按钮目前还没有做任何事情我们想要点击这个按钮来告诉父组件它应该放大所有博客文章的文字。要解决这个问题组件实例提供了一个自定义事件系统。父组件可以通过 v-on 或 来选择性地监听子组件上抛的事件就像监听原生 DOM 事件那样
BlogPost...enlarge-textpostFontSize 0.1/子组件可以通过调用内置的 [$emit 方法]通过传入事件名称来抛出一个事件
!-- BlogPost.vue, 省略了 script --
templatediv classblog-posth4{{ title }}/h4button click$emit(enlarge-text)Enlarge text/button/div
/template因为有了 enlarge-textpostFontSize 0.1 的监听父组件会接收这一事件从而更新 postFontSize 的值。
我们可以通过 [defineEmits] 宏来声明需要抛出的事件
!-- BlogPost.vue --
script setup
defineProps([title])
defineEmits([enlarge-text])
/script这声明了一个组件可能触发的所有事件还可以对事件的参数进行验证。同时这还可以让 Vue 避免将它们作为原生事件监听器隐式地应用于子组件的根元素。
和 defineProps 类似defineEmits 仅可用于 script setup 之中并且不需要导入它返回一个等同于 $emit 方法的 emit 函数。它可以被用于在组件的 script setup 中抛出事件因为此处无法直接访问 $emit
script setup
const emit defineEmits([enlarge-text])emit(enlarge-text)
/scriptTypeScript 用户请参考[为组件 emits 标注类型]
如果你没有在使用 script setup你可以通过 emits 选项定义组件会抛出的事件。你可以从 setup() 函数的第二个参数即 setup 上下文对象上访问到 emit 函数
export default {emits: [enlarge-text],setup(props, ctx) {ctx.emit(enlarge-text)}
}以上就是目前你需要了解的关于组件自定义事件的所有知识了。如果你看完本章节后还想知道更多细节请深入阅读组件事件章节。
五、通过插槽来分配内容
一些情况下我们会希望能和 HTML 元素一样向组件中传递内容
AlertBoxSomething bad happened.
/AlertBox我们期望能渲染成这样
This is an Error for Demo Purposes
Something bad happened.
这可以通过 Vue 的自定义 slot 元素来实现
!-- AlertBox.vue --
templatediv classalert-boxstrongThis is an Error for Demo Purposes/strongslot //div
/templatestyle scoped
.alert-box {/* ... */
}
/style如上所示我们使用 slot 作为一个占位符父组件传递进来的内容就会渲染在这里。
六、动态组件
有些场景会需要在两个组件间来回切换比如 Tab 界面
上面的例子是通过 Vue 的 component 元素和特殊的 is attribute 实现的
!-- currentTab 改变时组件也改变 --
component :istabs[currentTab]/component在上面的例子中被传给 :is 的值可以是以下几种
被注册的组件名导入的组件对象
你也可以使用 is attribute 来创建一般的 HTML 元素。
当使用 component :is... 来在多个组件间作切换时被切换掉的组件会被卸载。我们可以通过 [ 组件]强制被切换掉的组件仍然保持“存活”的状态。
七、DOM 内模板解析注意事项
如果你想在 DOM 中直接书写 Vue 模板Vue 则必须从 DOM 中获取模板字符串。由于浏览器的原生 HTML 解析行为限制有一些需要注意的事项。
请注意下面讨论只适用于直接在 DOM 中编写模板的情况。如果你使用来自以下来源的字符串模板就不需要顾虑这些限制了
单文件组件内联模板字符串 (例如 template: ...)script typetext/x-template
1、大小写区分
HTML 标签和属性名称是不分大小写的所以浏览器会把任何大写的字符解释为小写。这意味着当你使用 DOM 内的模板时无论是 PascalCase 形式的组件名称、camelCase 形式的 prop 名称还是 v-on 的事件名称都需要转换为相应等价的 kebab-case (短横线连字符) 形式
// JavaScript 中的 camelCase
const BlogPost {props: [postTitle],emits: [updatePost],template: h3{{ postTitle }}/h3
}!-- HTML 中的 kebab-case --
blog-post post-titlehello! update-postonUpdatePost/blog-post2、闭合标签
我们在上面的例子中已经使用过了闭合标签 (self-closing tag)
MyComponent /这是因为 Vue 的模板解析器支持任意标签使用 / 作为标签关闭的标志。
然而在 DOM 内模板中我们必须显式地写出关闭标签
my-component/my-component这是由于 HTML 只允许[一小部分特殊的元素]省略其关闭标签最常见的就是 input 和 img。对于其他的元素来说如果你省略了关闭标签原生的 HTML 解析器会认为开启的标签永远没有结束用下面这个代码片段举例来说
my-component / !-- 我们想要在这里关闭标签... --
spanhello/span将被解析为
my-componentspanhello/span
/my-component !-- 但浏览器会在这里关闭标签 --3、元素位置限制
某些 HTML 元素对于放在其中的元素类型有限制例如 uloltable 和 select相应的某些元素仅在放置于特定元素中时才会显示例如 litr 和 option。
这将导致在使用带有此类限制元素的组件时出现问题。例如
tableblog-post-row/blog-post-row
/table自定义的组件 blog-post-row 将作为无效的内容被忽略因而在最终呈现的输出中造成错误。我们可以使用特殊的 is attribute 作为一种解决方案
tabletr isvue:blog-post-row/tr
/table当使用在原生 HTML 元素上时is 的值必须加上前缀 vue: 才可以被解析为一个 Vue 组件。这一点是必要的为了避免和原生的[自定义内置元素。
以上就是你需要了解的关于 DOM 内模板解析的所有注意事项同时也是 Vue 基础部分的所有内容。 row
自定义的组件 blog-post-row 将作为无效的内容被忽略因而在最终呈现的输出中造成错误。我们可以使用特殊的 is attribute 作为一种解决方案
tabletr isvue:blog-post-row/tr
/table当使用在原生 HTML 元素上时is 的值必须加上前缀 vue: 才可以被解析为一个 Vue 组件。这一点是必要的为了避免和原生的[自定义内置元素。
以上就是你需要了解的关于 DOM 内模板解析的所有注意事项同时也是 Vue 基础部分的所有内容。