前端系列13集

您所在的位置:网站首页 attribute的固定搭配 前端系列13集

前端系列13集

#前端系列13集| 来源: 网络整理| 查看: 265

示例

{{msg}} 复制代码

在你的站点上动态渲染任意的 HTML 是非常危险的,因为它很容易导致 [XSS 攻击]。请只对可信内容使用 HTML 插值,绝不要将用户提供的内容作为插值

在[单文件组件],scoped 样式将不会作用于 v-html 里的内容,因为 HTML 内容不会被 Vue 的模板编译器解析。如果你想让 v-html 的内容也支持 scoped CSS,你可以使用 [CSS modules]或使用一个额外的全局  元素,手动设置类似 BEM 的作用域策略。

当同时使用时,v-if 比 v-for 优先级更高。我们并不推荐在一元素上同时使用这两个指令

表示 v-if 或 v-if / v-else-if 链式调用的“else 块”。

基于原始数据多次渲染元素或模板块。

期望的绑定值类型: Array | Object | number | string | Iterable

详细信息

指令值必须使用特殊语法 alias in expression 为正在迭代的元素提供一个别名:

{{ item.text }} 复制代码

或者,你也可以为索引指定别名 (如果用在对象,则是键值):

复制代码

v-for 的默认方式是尝试就地更新元素而不移动它们。要强制其重新排序元素,你需要用特殊 attribute (归于) key 来提供一个排序提示:

{{ item.text }} 复制代码

给元素绑定事件监听器。

缩写: @

期望的绑定值类型: Function | Inline Statement | Object (不带参数)

参数: event (使用对象语法则为可选项)

修饰符:

.stop - 调用 event.stopPropagation()。 .prevent - 调用 event.preventDefault()。 .capture - 在捕获模式添加事件监听器。 .self - 只有事件从元素本身发出才触发处理函数。 .{keyAlias} - 只在某些按键下触发处理函数。 .once - 最多触发一次处理函数。 .left - 只在鼠标左键事件触发处理函数。 .right - 只在鼠标右键事件触发处理函数。 .middle - 只在鼠标中键事件触发处理函数。 .passive - 通过 { passive: true } 附加一个 DOM 事件。

当监听原生 DOM 事件时,方法接收原生事件作为唯一参数。如果使用内联声明,声明可以访问一个特殊的 $event 变量:v-on:click="handle('ok', $event)"。

示例:

复制代码

监听子组件的自定义事件 (当子组件的“my- event (事件) ”事件被触发,处理函数将被调用):

复制代码

动态的绑定一个或多个 attribute (归于) ,也可以是组件的 prop。

缩写: : 或者 . (当使用 .prop 修饰符)

期望: any (带参数) | Object (不带参数)

参数: attrOrProp (可选的)

修饰符:

.camel - 将短横线命名的 attribute (归于) 转变为驼峰式命名。 .prop - 强制绑定为 DOM property (属性) 。3.2+ .attr - 强制绑定为 DOM attribute (归于) 。3.2+

示例:

复制代码

当在 DOM 内模板使用 .camel 修饰符,可以驼峰化 v-bind attribute (归于) 的名称,例如 SVG viewBox attribute (归于) :

复制代码

如果使用字符串模板或使用构建步骤预编译模板,则不需要 .camel。

在表单输入元素或组件上创建双向绑定。

期望的绑定值类型:根据表单输入元素或组件输出的值而变化

仅限:

components (组件)

修饰符:

[.lazy] - 监听 change 事件而不是 input [.number] - 将输入的合法字符串转为数字 [.trim] - 移除输入内容两端空格

用于声明具名插槽或是期望接收 props 的作用域插槽。

示例:

Header content Default slot content Footer content {{ slotProps.item.text }} Mouse position: {{ x }}, {{ y }} 复制代码

跳过该元素及其所有子元素的编译。

无需传入

详细信息

元素内具有 v-pre,所有 Vue 模板语法都会被保留并按原样渲染。最常见的用例就是显示原始双大括号标签及内容。

在随后的重新渲染,元素/组件及其所有子项将被当作静态内容并跳过渲染。这可以用来优化更新时的性能。

仅渲染元素和组件一次,并跳过之后的更新。

This will never change: {{msg}} comment {{msg}} {{i}} 复制代码

缓存一个模板的子树。在元素和组件上都可以使用。为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。

... 复制代码

当组件重新渲染,如果 valueA 和 valueB 都保持不变,这个  及其子项的所有更新都将被跳过。实际上,甚至虚拟 DOM 的 vnode 创建也将被跳过,因为缓存的子树副本可以被重新使用。

正确指定缓存数组很重要,否则应该生效的更新可能被跳过。v-memo 传入空依赖数组 (v-memo="[]") 将与 v-once 效果相同。

与 v-for 一起使用

v-memo 仅用于性能至上场景中的微小优化,应该很少需要。最常见的情况可能是有助于渲染海量 v-for 列表 (长度超过 1000 的情况):

ID: {{ item.id }} - selected: {{ item.id === selected }} ...more child nodes 复制代码

当组件的 selected 状态改变,默认会重新创建大量的 vnode,尽管绝大部分都跟之前是一模一样的。v-memo 用在这里本质上是在说“只有当该项的被选中状态改变时才需要更新”。这使得每个选中状态没有变的项能完全重用之前的 vnode 并跳过差异比较。注意这里 memo (备忘录) 依赖数组中并不需要包含 item.id,因为 Vue 也会根据 item (项目) 的 :key 进行判断。

当搭配 v-for 使用 v-memo,确保两者都绑定在同一个元素上。v-memo 不能用在 v-for 内部。

用于隐藏尚未完成编译的 DOM 模板。

无需传入

详细信息

该指令只在没有构建步骤的环境下需要使用。

当使用直接在 DOM 中书写的模板时,可能会出现一种叫做“未编译模板闪现”的情况:用户可能先看到的是还没编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。

v-cloak 会保留在所绑定的元素上,直到相关组件实例被挂载后才移除。配合像 [v-cloak] { display: none } 这样的 CSS 规则,它可以在组件编译完毕前隐藏原始模板。

示例:

[v-cloak] { display: none; } 复制代码 {{ message }} 复制代码

组件注册和使用

内置组件无需注册便可以直接在模板中使用。它们也支持 tree- shake (动摇) :仅在使用时才会包含在构建中。

在[渲染函数]中使用它们时,需要显式导入。例如:

import { h, Transition } from 'vue' h(Transition, { /* props */ }) 复制代码

不是组件

、 和  具有类似组件的特性,也是模板语法的一部分。但它们并非真正的组件,同时在模板编译期间会被编译掉。因此,它们通常在模板中用小写字母书写。

按注册名渲染组件 (选项式 API):

import Foo from './Foo.vue' import Bar from './Bar.vue' export default { components: { Foo, Bar }, data() { return { view: 'Foo' } } } 复制代码

按定义渲染组件 ( 组合式 API):

import Foo from './Foo.vue' import Bar from './Bar.vue' 复制代码

[内置组件]都可以传递给 is,但是如果想通过名称传递则必须先对其进行注册。举例来说:

import { Transition, TransitionGroup } from 'vue' export default { components: { Transition, TransitionGroup } } ... 复制代码

如果在  标签上使用 v-model,模板编译器会将其扩展为 modelValue prop 和 update:modelValue 事件监听器,就像对任何其他组件一样。但是,这与原生 HTML 元素不兼容,例如  或 。因此,在动态创建的原生元素上使用 v-model 将不起作用:

import { ref } from 'vue' const tag = ref('input') const username = ref('') 复制代码

当我们想要使用内置指令而不在 DOM 中渲染元素时, 标签可以作为占位符使用。

单文件组件使用[顶层的  标签]来包裹整个模板。这种用法与上面描述的  使用方式是有区别的。该顶层标签不是模板本身的一部分,不支持指令等模板语法。

举例来说:

{{ text }} 复制代码

使用选项式 API,引用将被注册在组件的 this.$refs 对象里:

hello 复制代码

使用组合式 API,引用将存储在与名字匹配的 ref 里:

import { ref } from 'vue' const p = ref() hello 复制代码

关于 ref 注册时机的重要说明:因为 ref 本身是作为渲染函数的结果来创建的,必须等待组件挂载后才能对它进行访问。

this.$refs 也是非响应式的,因此你不应该尝试在模板中使用它来进行数据绑定。

在 is attribute (归于) 的值中加上 vue: 前缀,这样 Vue 就会把该元素渲染为 Vue 组件:

复制代码

 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。当同时使用 SFC 与组合式 API 时该语法是默认推荐。相比于普通的  语法,它具有更多优势:

更少的样板内容,更简洁的代码。 能够使用纯 TypeScript 声明 props 和自定义事件。 更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)。 更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。

 中的代码会在每次组件实例被创建的时候执行。

当使用  的时候,任何在  声明的顶层的绑定 (包括变量,函数声明,以及 import (进口) 导入的内容) 都能在模板中直接使用:

// 变量 const msg = 'Hello!' // 函数 function log() { console.log(msg) } {{ msg }} 复制代码

import (进口) 导入的内容也会以同样的方式暴露。这意味着我们可以在模板表达式中直接使用导入的 helper (帮手) 函数,而不需要通过 methods 选项来暴露它:

import { capitalize } from './helpers' {{ capitalize('hello') }} 复制代码

响应式状态需要明确使用[响应式 API]来创建。和 setup() 函数的返回值一样,ref 在模板中使用的时候会自动解包:

vue

import { ref } from 'vue' const count = ref(0) {{ count }} 复制代码

 范围里的值也能被直接作为自定义组件的标签名使用:

import MyComponent from './MyComponent.vue' 复制代码

由于组件是通过变量引用而不是基于字符串组件名注册的,在  中要使用动态组件的时候,应该使用动态的 :is 来绑定:

import Foo from './Foo.vue' import Bar from './Bar.vue' 复制代码

一个单文件组件可以通过它的文件名被其自己所引用。例如:名为 FooBar.vue 的组件可以在其模板中用  引用它自己。

请注意这种方式相比于导入的组件优先级更低。如果有具名的导入和组件自身推导的名字冲突了,可以为导入的组件添加别名:

import { FooBar as FooBarChild } from './components' 复制代码

为了在声明 props 和 emits 选项时获得完整的类型推导支持,我们可以使用 defineProps 和 defineEmits API,它们将自动地在  中可用:

const props = defineProps({ foo: String }) const emit = defineEmits(['change', 'delete']) // setup 代码 复制代码 defineProps 和 defineEmits 都是只能在  中使用的编译器宏。他们不需要导入,且会随着  的处理过程一同被编译掉。 defineProps 接收与 props 选项相同的值,defineEmits 接收与 emits 选项相同的值。 defineProps 和 defineEmits 在选项传入后,会提供恰当的类型推导。 传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的作用域。因此,传入的选项不能引用在 setup 作用域中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块作用域内。

可以通过 defineExpose 编译器宏来显式指定在  组件中要暴露出去的属性:

import { ref } from 'vue' const a = 1 const b = ref(2) defineExpose({ a, b }) 复制代码

在  使用 slots 和 attrs 的情况应该是相对来说较为罕见的,因为可以在模板中直接通过 $slots 和 $attrs 来访问它们。在你的确需要使用它们的罕见场景中,可以分别用 useSlots 和 useAttrs 两个辅助函数:

import { useSlots, useAttrs } from 'vue' const slots = useSlots() const attrs = useAttrs() 复制代码

useSlots 和 useAttrs 是真实的运行时函数,它的返回与 setupContext.slots 和 setupContext.attrs 等价。它们同样也能在普通的组合式 API 中使用。

 中可以使用顶层 await。结果代码会被编译成 async setup():

const post = await fetch(`/api/post/1`).then((r) => r.json()) 复制代码

创建原生元素:

import { h } from 'vue' // 除了 type 外,其他参数都是可选的 h('div') h('div', { id: 'foo' }) // attribute 和 property 都可以用于 prop // Vue 会自动选择正确的方式来分配它 h('div', { class: 'bar', innerHTML: 'hello' }) // class 与 style 可以像在模板中一样 // 用数组或对象的形式书写 h('div', { class: [foo, { bar }], style: { color: 'red' } }) // 事件监听器应以 onXxx 的形式书写 h('div', { onClick: () => {} }) // children 可以是一个字符串 h('div', { id: 'foo' }, 'hello') // 没有 prop 时可以省略不写 h('div', 'hello') h('div', [h('span', 'hello')]) // children 数组可以同时包含 vnode 和字符串 h('div', ['hello', h('span', 'hello')]) 复制代码

创建组件:

import Foo from './Foo.vue' // 传递 prop h(Foo, { // 等价于 some-prop="hello" someProp: 'hello', // 等价于 @update="() => {}" onUpdate: () => {} }) // 传递单个默认插槽 h(Foo, () => 'default slot') // 传递具名插槽 // 注意,需要使用 `null` 来避免 // 插槽对象被当作是 prop h(MyComponent, null, { default: () => 'default slot', foo: () => h('div', 'foo'), bar: () => [h('span', 'one'), h('span', 'two')] }) 复制代码

如果你不需要合并行为而是简单覆盖,可以使用原生 object (目的) spread 语法来代替。

示例

import { h, cloneVNode } from 'vue' const original = h('div') const cloned = cloneVNode(original, { id: 'foo' }) 复制代码

示例

import { h, withModifiers } from 'vue' const vnode = h('button', { // 等价于 v-on:click.stop.prevent onClick: withModifiers(() => { // ... }, ['stop', 'prevent']) }) 复制代码

示例

import type { PropType } from 'vue' interface Book { title: string author: string year: number } export default { props: { book: { // 提供一个比 `Object` 更具体的类型 type: Object as PropType, required: true } } } 复制代码

示例

import axios from 'axios' declare module 'vue' { interface ComponentCustomProperties { $http: typeof axios $translate: (key: string) => string } } 复制代码

用来扩展组件选项类型以支持自定义选项。

示例

import { Route } from 'vue-router' declare module 'vue' { interface ComponentCustomOptions { beforeRouteEnter?(to: any, from: any, next: () => void): void } } 复制代码

用于扩展全局可用的 TSX props,以便在 TSX 元素上使用没有在组件选项上定义过的 props。

示例

declare module 'vue' { interface ComponentCustomProps { hello?: string } } export {} 复制代码 // 现在即使没有在组件选项上定义过 hello 这个 prop 也依然能通过类型检查了 复制代码

用于扩展在样式属性绑定上允许的值的类型。

示例

允许任意自定义 CSS 属性:

declare module 'vue' { interface CSSProperties { [key: `--${string}`]: string } } 复制代码 复制代码 复制代码

加群联系作者vx:xiaoda0423

仓库地址:github.com/webVueBlog/…



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3