vuejs3 第9页
#key 预期:number | string key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除/销毁 key 不存在的元素。 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。 最常见的用例是结合 v-for: <ul> <li v-for="item in items" :key="item.id">...</li> </ul> 它也可以用于强制替换元素/组件而不是重复使用它。当你遇到如下场景时它可能会很有用: 完整地触发组件的生命周期钩子 触发过渡 例如: <transition> <span :key="text">{{ text }}</span> </transition> 当 text 发生改变时,<span> 总是会被替换而不是被修改,因此会触发过渡。 #ref 预期:string | Function ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例: <!-- vm.$refs.p 会是 DOM 节点 --> <p ref="p">hello</p> <!-- vm.$refs.child 会是子组件实例 --> <child-component ref="child"></child-component> <!-- 当动态绑定时,我们可以将ref定义为回调函数,显式地传递元素或组件实例 --> <child-component :ref="(el) => child = el"></child-component> 当 v-for 用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。 关于 ref 注册时间的重要说明:因为 ref 本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 – 它们还不存在!$refs 也是非响应式的,因此你不应该试图用它在模板中做数据绑定。 参考子组件 Refs #is 预期:string | Object (component’s options object) 使用动态组件。 例如: <!-- component changes when currentView changes --> <component :is="currentView"></component> 更多的使用细节,请移步至下面的链接。 参考...
#v-text 预期:string 详细: 更新元素的 textContent。如果要更新部分的 textContent,需要使用 Mustache 插值。 示例: <span v-text="msg"></span> <!-- 等价于 --> <span>{{msg}}</span> 参考:数据绑定语法 – 插值 #v-html 预期:string 详细: 更新元素的 innerHTML。注意:内容按普通 HTML 插入 – 不会作为 Vue 模板进行编译。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。 WARNING 在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 XSS 攻击。只在可信内容上使用 v-html,永不用在用户提交的内容上。 在单文件组件里,scoped 的样式不会应用在 v-html 内部,因为那部分 HTML 没有被 Vue 的模板编译器处理。如果你希望针对 v-html 的内容设置带作用域的 CSS,你可以替换为 CSS modules 或用一个额外的全局 <style> 元素手动设置类似 BEM 的作用域策略。 示例: <div v-html="html"></div> 参考:数据绑定语法 – 插值 #v-show 预期:any 用法: 根据表达式的真假值,切换元素的 display CSS property。 当条件变化时该指令触发过渡效果。 参考:条件渲染 – v-show #v-if 预期:any 用法: 根据表达式的真假值来有条件地渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 <template>,将提取它的内容作为条件块。 当条件变化时该指令触发过渡效果。 当和 v-if 一起使用时,v-for 的优先级比 v-if 更高。详见列表渲染教程 参考:条件渲染 – v-if #v-else 不需要表达式 限制:前一兄弟元素必须有 v-if 或 v-else-if。 用法: 为 v-if 或者 v-else-if 添加“else 块”。 <div v-if="Math.random() > 0.5"> Now you see me </div> <div v-else> Now you don't </div> 参考:条件渲染 –...
#directives 类型:Object 详细: 包含组件实例可用指令的哈希表。 参考自定义指令 #components 类型:Object 详细: 包含组件实例可用组件的哈希表。 参考 Components
注意 所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对 property 和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos()) 。这是因为箭头函数绑定了父上下文,因此 this 与你期待的组件实例不同,this.fetchTodos 的行为未定义。 #beforeCreate 类型:Function 详细: 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。 参考:生命周期图示 #created 类型:Function 详细: 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el property 目前尚不可用。 参考:生命周期图示 #beforeMount 类型:Function 详细: 在挂载开始之前被调用:相关的 render 函数首次被调用。 该钩子在服务器端渲染期间不被调用。 参考:生命周期图示 #mounted 类型:Function 详细: 实例被挂载后调用,这时 Vue.createApp({}).mount() 被新创建的 vm.$el 替换了。如果根实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内。 注意 mounted 不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted 内部使用 vm。$nextTick: mounted() { this.$nextTick(function () { // 仅在渲染整个视图之后运行的代码 }) } 该钩子在服务器端渲染期间不被调用。 参考:生命周期图示 #beforeUpdate 类型:Function 详细: 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。 该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。 参考:生命周期图示 #updated 类型:Function 详细: 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或侦听器取而代之。 注意,updated 不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated 里使用 vm.$nextTick: updated() { this.$nextTick(function () { // 仅在渲染整个视图之后运行的代码 }) } 该钩子在服务器端渲染期间不被调用。 参考:生命周期图示 #activated 类型:Function 详细: 被 keep-alive 缓存的组件激活时调用。 该钩子在服务器端渲染期间不被调用。 参考: 动态组件 – keep-alive...
#template 类型:string 详细: 一个字符串模板作为 component 实例的标识使用。模板将会替换挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽。 如果值以 # 开始,则它将被用作 querySelector,并使用匹配元素的 innerHTML 作为模板。常用的技巧是用 <script type="x-template"> 包含模板。 注意 出于安全考虑,你应该只使用你信任的 Vue 模板。避免使用其他人生成的内容作为你的模板。 注意 如果 Vue 选项中包含渲染函数,该模板将被忽略。 参考 生命周期图示 通过插槽分发内容 #render 类型:Function 详细: 字符串模板的另一种选择,允许你充分利用 JavaScript 的编程功能。 用法: <div id="app" class="demo"> <my-title blog-title="A Perfect Vue"></my-title> </div> const app = Vue.createApp({}) app.component('my-title', { render() { return Vue.h( 'h1', // 标签名称 this.blogTitle // 标签内容 ) }, props: { blogTitle: { type: String, required: true } } }) app.mount('#app') 注意 render 函数的优先级高于从挂载元素 template 选项或内置 DOM 提取出的 HTML 模板编译渲染函数。 参考 Render Functions
#createApp 返回一个提供应用上下文的应用实例。应用实例挂载的整个组件树共享同一个上下文。 const app = Vue.createApp({}) 你可以在 createApp 之后链式调用其它方法,这些方法可以在应用 API 中找到。 #参数 该函数接收一个根组件选项对象作为第一个参数: const app = Vue.createApp({ data() { return { ... } }, methods: {...}, computed: {...} ... }) 使用第二个参数,我们可以将根 prop 传递给应用程序: const app = Vue.createApp( { props: ['username'] }, { username: 'Evan' } ) <div id="app"> <!-- 会显示 'Evan' --> {{ username }} </div> #类型声明 interface Data { [key: string]: unknown } export type CreateAppFunction<HostElement> = ( rootComponent: PublicAPIComponent, rootProps?: Data | null ) => App<HostElement> #h 返回一个”虚拟节点“,通常缩写为 VNode:一个普通对象,其中包含向 Vue 描述它应在页面上渲染哪种节点的信息,包括所有子节点的描述。它的目的是用于手动编写的渲染函数: render() { return Vue.h('h1', {}, 'Some title') } #参数 接收三个参数:type,props 和 children #type 类型:String | Object | Function 详细: HTML 标签名、组件或异步组件。使用返回 null 的函数将渲染一个注释。此参数是必需的。 #props 类型:Object 详细: 一个对象,与我们将在模板中使用的 attribute、prop 和事件相对应。可选。 #children 类型:String | Array | Object 详细: 子代...
在 Vue 3 中,改变全局 Vue 行为的 API 现在被移动到了由新的 createApp 方法所创建的应用实例上。此外,现在它们的影响仅限于该特定应用实例: import { createApp } from 'vue' const app = createApp({}) 调用 createApp 返回一个应用实例。该实例提供了一个应用上下文。应用实例挂载的整个组件树共享相同的上下文,该上下文提供了之前在 Vue 2.x 中“全局”的配置。 另外,由于 createApp 方法返回应用实例本身,因此可以在其后链式调用其它方法,这些方法可以在以下部分中找到。 #component 参数: {string} name {Function | Object} [definition] 返回值: 如果传入 definition 参数,返回应用实例。 如果不传入 definition 参数,返回组件定义。 用法: 注册或检索全局组件。注册还会使用给定的 name 参数自动设置组件的 name。 示例: import { createApp } from 'vue' const app = createApp({}) // 注册一个名为my-component的组件 app.component('my-component', { /* ... */ }) // 检索注册的组件(始终返回构造函数) const MyComponent = app.component('my-component', {}) 参考:组件基础 #config 用法: 包含应用配置的对象。 示例: import { createApp } from 'vue' const app = createApp({}) app.config = {...} 参考:应用配置 #directive 参数: {string} name {Function | Object} [definition] 返回值: 如果传入 definition 参数,返回应用实例。 如果不传入 definition 参数,返回指令定义。 用法: 注册或检索全局指令。 示例: import { createApp } from 'vue' const app...
config 是一个包含了 Vue 应用全局配置的对象。你可以在应用挂载前修改其以下 property: const app = Vue.createApp({}) app.config = {...} #errorHandler 类型:Function 默认:undefined 用法: app.config.errorHandler = (err, vm, info) => { // 处理错误 // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子 } 指定一个处理函数,来处理组件渲染方法执行期间以及侦听器抛出的未捕获错误。这个处理函数被调用时,可获取错误信息和应用实例。 错误追踪服务 Sentry 和 Bugsnag 使用此选项提供官方集成。 #warnHandler 类型:Function 默认:undefined 用法: app.config.warnHandler = function(msg, vm, trace) { // `trace` 是组件的继承关系追踪 } 为 Vue 的运行时警告指定一个自定义处理函数。注意这只会在开发环境下生效,在生产环境下它会被忽略。 #globalProperties 类型:[key: string]: any 默认:undefined 用法: app.config.globalProperties.foo = 'bar' app.component('child-component', { mounted() { console.log(this.foo) // 'bar' } }) 添加可以在应用程序内的任何组件实例中访问的全局 property。属性名冲突时,组件的 property 将具有优先权。 这可以代替 Vue 2.x Vue.prototype 扩展: // 之前(Vue 2.x) Vue.prototype.$http = () => {} // 之后(Vue 3.x) const app = Vue.createApp({}) app.config.globalProperties.$http = () => {} #isCustomElement 类型:(tag: string) => boolean 默认:undefined 用法: // 任何以“ion-”开头的元素都将被识别为自定义元素 app.config.isCustomElement = tag => tag.startsWith('ion-') 指定一个方法,用来识别在 Vue 之外定义的自定义元素(例如,使用 Web Components...
Vue 已经遍布全球,核心团队至少在 6 个不同的时区。论坛包括 7 种语言和计数,我们的许多文档积极维护翻译。我们为 Vue 的国际影响力感到骄傲,但我们可以做得更好。 #我们可以开始翻译 Vue 3 文档了吗? 目前,VUE3 文档仍处于测试阶段,随时可能更改。因此,我们会谨慎对待任何重要的工作,因为我们仍在收集反馈,并根据需要重新编写。当文档处于发布候选阶段时,我们将确保发布公告,以便你可以开始使用! #我如何参与翻译? 开始的最好方法是检查此处固定 issues Vuejs.org 其中包含了对社区内各种倡议的积极讨论。
译者:本章节大部分内容是针对母语是英文的读者,中文用户可略读,除非你想以英文文档编写者的身份参与 Vue docs 的编写, 编写文档是一种换位思考的练习。我们并不是在描述客观现实——源代码已经做到了。我们的工作是帮助塑造用户与 Vue 生态系统之间的关系。这份不断发展的指南提供了一些规则和建议,说明如何在 Vue 生态系统中始终如一地做到这一点。 #原则 除非有充分的文档证明,否则功能不存在。 尊重用户的认知能力 (即脑力)。当用户开始阅读时,他们从一定量的有限脑力开始,而当他们用完时,他们停止学习。 复杂的句子、一次必须学习一个以上的概念,以及与用户的工作没有直接关系的抽象例子,认知能力消耗得更快。 当我们帮助他们持续感到聪明、强大和好奇时,他们的认知能力会慢慢消耗殆尽。把事情分解成可消化的部分并注意文档的流动可以帮助它们保持这种状态。 总是试着从用户的角度看问题。当我们彻底理解某件事情时,它就变得显而易见了。这就是所谓的知识诅咒。为了编写好的文档,记住在学习这个概念时首先需要知道什么。你需要学什么行话?你误解了什么?什么花了很长时间才真正掌握?好的文档可以满足用户的需求。这可能有助于练习向人们解释这个概念 首先描述*问题*,然后描述解决方案。在展示功能如何工作之前,解释其存在的原因非常重要。否则,用户将无法知道这些信息对他们是否重要 (这是他们遇到的问题吗?) 或与之前的知识/经验相联系。 在写作时,不要害怕问问题,尤其是如果你害怕他们“蠢”的话。脆弱是很难的,但这是我们更充分地理解我们需要解释的唯一途径。 参与特性讨论。最好的 API 来自于文档驱动的开发,我们在开发中构建易于解释的特性,而不是试图在以后解释它们。提前提出问题 (尤其是“愚蠢的”问题) 通常有助于揭示困惑、不一致和有问题的行为,然后才需要进行破坏性的更改来修复它们。 #组织 安装/集成:提供有关如何将软件集成到尽可能多的不同项目中的全面概述。 介绍/起步: 提供一个不到 10 分钟的项目解决的问题及其存在原因的概述。 提供一个不到 30 分钟的项目解决的问题和如何解决的概述,包括何时和为什么使用项目以及一些简单的代码示例。最后,链接到安装页面和要点指南的开头。 指南:让用户感到聪明、强大、好奇,然后保持这种状态,让用户保持不断学习的动力和认知能力。指南页是按顺序阅读的,因此通常应该从最高到最低的功率/工作比排序。 要点:阅读要领的时间不应超过 5 个小时,但越短越好。它的目标是提供 20%的知识来帮助用户处理 80%的用例。Essentials 可以链接到更高阶的指南和 API,不过,在大多数情况下,你应该避免此类链接。当它们被提供时,你还需要提供一个上下文,以便用户知道他们是否应该在第一次阅读时遵循这个链接。否则,许多用户最终会耗尽他们的认知能力,跳转链接,试图在继续之前全面了解一个功能的各个方面,结果是,永远无法完成第一次通读的要领。记住,通顺的阅读比彻底的阅读更重要。我们想给人们提供他们需要的信息,以避免令人沮丧的经历,但他们总是可以回来继续阅读,或者在谷歌遇到一个不太常见的问题。 高阶:虽然要点帮助人们处理大约 80%的用例,但后续的指南帮助用户了解 95%的用例,以及关于非基本特性 (例如转换、动画)、更复杂的便利特性 (例如 mixin、自定义指令) 和开发人员体验改进 (例如 JSX、插件) 的更详细信息。最后 5%的用例是更利基的、更复杂的和/或更容易被滥用的,将留给烹饪书和 API 参考,它们可以从这些高阶指南链接到。 引用/API:提供功能的完整列表,包括类型信息,每个要解决的问题的描述,选项的每种组合的示例以及指向指南,食谱的食谱以及提供更多详细信息的其他内部资源的链接。与其他页面不同,此页面无意自上而下阅读,因此可以提供大量详细信息。这些参考资料还必须比指南更容易浏览,因此格式应比指南的讲故事格式更接近字典条目。 迁移: 版本:当进行了重要的更改时,包含一个完整的更改列表是很有用的,包括对为什么进行更改以及如何迁移其项目的详细解释。 从其他项目:这个软件与同类软件相比如何?这对于帮助用户了解我们可能为他们解决或创造的其他问题,以及他们可以在多大程度上转移他们已经拥有的知识,这一点很重要。 风格指南:开发中必然有一些关键部分需要决策,但它们不是 API 的核心。风格指南提供了受过教育的、有主见的建议,以帮助指导这些决策。他们不应该盲目遵循,但可以帮助团队节省时间,在较小的细节上保持一致。 Cookbook:Cookbook 中的秘诀是基于对 Vue 及其生态系统的熟悉程度而编写的。每一个文档都是一个高度结构化的文档,它详细介绍了 Vue 开发人员可能遇到的一些常见实现细节。 #写作 & 语法 #风格 标题应该描述问题,不是解决方案。例如,一个不太有效的标题可能是“使用 prop”,因为它描述了一个解决方案。一个更好的标题可能是“通过 Props 将数据传递给子组件”,因为它提供了 Props 解决问题的上下文。用户不会真正开始注意某个功能的解释,直到他们知道为什么/何时使用它。 当你假设知识时,就要声明它,在开始时,链接到参考资料,以获得你期望的不太常见的知识。 尽可能一次只引入一个新概念 (包括文本和代码示例),即使当你介绍不止一个的时候很多人都能理解,也有很多人会迷失方向,即使那些没有迷失方向的人也会耗尽更多的认知能力。 尽可能避免使用特殊的内容块来获取提示和注意事项,一般来说,最好将这些内容更自然地融合到主要内容中,例如,通过构建示例来演示边缘案例。 每页不要超过两个相互交织的提示和注意事项,如果你发现一个页面需要两个以上的提示,请考虑添加一个警告部分来解决这些问题。本指南的目的是通读,提示和注意事项可能会让试图理解基本概念的人不知所措或分心。 避免诉诸权威 (例如,“你应该做 X,因为这是一个最佳实践”或“X 是最好的,因为它能让你完全分离关注点”)。相反,用例子来演示由模式引起和/或解决的具体人类问题。 当决定先教什么时,想想哪些知识能提供最好的动力/努力比。这意味着教任何能帮助用户解决最大痛苦或最大数量问题的东西,而学习的努力相对较少。这有助于学习者感到聪明、强大和好奇,因此他们的认知能力会慢慢流失。 除非上下文采用字符串模板或构建系统,否则只能编写在软件的任何环境中工作的代码 (例如 Vue、Vuex 等) 显示,不要说例如,“要在页面上使用 Vue,可以将其添加到 HTML 中”(然后显示脚本标记),而不是“要在页面上使用 Vue,可以添加一个具有 src 属性的脚本元素,该属性的值应为指向 Vue 编译源的链接”。 几乎总是避免幽默 (对于英文文档), 尤其是讽刺和通俗文化的引用,因为它在不同文化之间的翻译并不好。 永远不要假设比你必须的更高阶的上下文。 在大多数情况下,比起在多个部分中重复相同的内容,更喜欢在文档的各个部分之间建立链接。在内容上有些重复是不可避免的,甚至是学习的必要条件。然而,过多的重复也会使文档更难维护,因为 API 的更改将需要在许多地方进行更改,而且很容易遗漏某些内容。这是一个很难达到的平衡。 具体的比一般的好例如,一个 <BlogPost> 组件例子比 <ComponentA> 更好。 相对胜于晦涩。例如,一个 <BlogPost> 组件例子比 <CurrencyExchangeSettings> 更好。 保持情感相关。与人们有经验并关心的事物相关的解释和示例将永远更加有效。 始终喜欢使用简单,简单的语言,而不是复杂或专业的语言。例如:...