列表渲染v-for
你也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:
- 数组里
在 v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2"><li v-for="(item, index) in items">{{ parentMessage }} - {{ index }} - {{ item.message }}</li>
</ul>
- 在 v-for 里使用对象
你也可以提供第二个的参数为 property 名称 (也就是键名):
<div v-for="(value, name) in object">{{ name }}: {{ value }}
</div>
还可以用第三个参数作为索引:
<div v-for="(value, name, index) in object">{{ index }}. {{ name }}: {{ value }}
</div>
处理事件
<div id="example-2"><!-- `greet` 是在下面定义的方法名 --><button v-on:click="greet">Greet</button>
</div>
除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:
<div id="example-3"><button v-on:click="say('hi')">Say hi</button><button v-on:click="say('what')">Say what</button>
</div>
有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit
</button>
表单输入绑定
.lazy
默认情况下,v-model 会在每次 input 事件后更新数据 (IME 拼字阶段的状态例外)。你可以添加 lazy 修饰符来改为在每次 change 事件后更新数据:
侦听器watch
https://cn.vuejs.org/guide/essentials/watchers.html
侦听数据源类型
watch 的第一个参数可以是不同形式的“数据源”:它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组:
const x = ref(0)
const y = ref(0)// 单个 ref
watch(x, (newX) => {console.log(`x is ${newX}`)
})// getter 函数
watch(() => x.value + y.value,(sum) => {console.log(`sum of x + y is: ${sum}`)}
)// 多个来源组成的数组
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})
注意,你不能直接侦听响应式对象的属性值,例如:
const obj = reactive({ count: 0 })// 错误,因为 watch() 得到的参数是一个 number
watch(obj.count, (count) => {console.log(`Count is: ${count}`)
})
这里需要用一个返回该属性的 getter 函数:
// 提供一个 getter 函数
watch(() => obj.count,(count) => {console.log(`Count is: ${count}`)}
)
watchEffect()
侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 todoId 的引用发生变化时使用侦听器来加载一个远程资源:
我们可以用 watchEffect 函数 来简化上面的代码。watchEffect() 允许我们自动跟踪回调的响应式依赖。
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})
这个例子中,回调会立即执行,不需要指定 immediate: true。在执行期间,它会自动追踪 todoId.value 作为依赖(和计算属性类似)。每当 todoId.value 变化时,回调会再次执行。有了 watchEffect(),我们不再需要明确传递 todoId 作为源值。
watch vs. watchEffect
watch 和 watchEffect 都能响应式地执行有副作用的回调。它们之间的主要区别是追踪响应式依赖的方式:
watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外,仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖,因此,我们能更加精确地控制回调函数的触发时机。
watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。这更方便,而且代码往往更简洁,但有时其响应性依赖关系会不那么明确。
is动态组件在原生html上的使用
<table><tr is="vue:blog-post-row"></tr>
</table>
当使用在原生 HTML 元素上时,is 的值必须加上前缀 vue: 才可以被解析为一个 Vue 组件。这一点是必要的,为了避免和原生的自定义内置元素相混淆。
https://cn.vuejs.org/guide/essentials/component-basics.html
props—单向数据流
对于组件名我们推荐使用 PascalCase,因为这提高了模板的可读性,能帮助我们区分 Vue 组件和原生 HTML 元素。然而对于传递 props 来说,使用 camelCase 并没有太多优势,因此我们推荐更贴近 HTML 的书写风格。
另外,每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。若你这么做了,Vue 会在控制台上向你抛出警告
const props = defineProps(['foo'])// ❌ 警告!prop 是只读的!
props.foo = 'bar'
Prop 校验
https://cn.vuejs.org/guide/components/props.html
触发与监听事件
<!-- MyComponent -->
<button @click="$emit('someEvent')">Click Me</button>
父组件可以通过 v-on (缩写为 @) 来监听事件:
<MyComponent @some-event="callback" />
动态组件 & 异步组件
keep-alive缓存
- 异步组件
new Vue({// ...components: {'my-component': () => import('./my-async-component')}
})
访问根实例
在每个 new Vue 实例的子组件中,其根实例可以通过 $root property 进行访问。例如,在这个根实例中:
// Vue 根实例
new Vue({data: {foo: 1},computed: {bar: function () { /* ... */ }},methods: {baz: function () { /* ... */ }}
})
// 获取根组件的数据
this.$root.foo// 写入根组件的数据
this.$root.foo = 2// 访问根组件的计算属性
this.$root.bar// 调用根组件的方法
this.$root.baz()
组合式函数 hooks
https://cn.vuejs.org/guide/reusability/composables.html
自定义指令
指令钩子
指令钩子 https://cn.vuejs.org/guide/reusability/custom-directives.html
const myDirective = {// 在绑定元素的 attribute 前// 或事件监听器应用前调用created(el, binding, vnode) {// 下面会介绍各个参数的细节},// 在元素被插入到 DOM 前调用beforeMount(el, binding, vnode) {},// 在绑定元素的父组件// 及他自己的所有子节点都挂载完成后调用mounted(el, binding, vnode) {},// 绑定元素的父组件更新前调用beforeUpdate(el, binding, vnode, prevVnode) {},// 在绑定元素的父组件// 及他自己的所有子节点都更新后调用updated(el, binding, vnode, prevVnode) {},// 绑定元素的父组件卸载前调用beforeUnmount(el, binding, vnode) {},// 绑定元素的父组件卸载后调用unmounted(el, binding, vnode) {}
}