Vue 基础
文档
模板语法
页面中显示用 {{welcome}}'
html 属性中直接写 <div :id="id"></div>
为属性绑定值的语法是 v-bind:attr-name
,例如 v-bind:id
,简写为 :id
。
类与样式绑定
class 可以接受数组和对象。
数组可以用三元运算符,对象用布尔值。
<div :class="[a, b, c ? 'classA' : 'classB']"></div>
<div :class="{classA: true, classB: false}"></div>
style 接受对象。
<div :style="{}"></div>
计算属性
计算属性可以直接当一个值来用,这个值是基于某种计算得到的。
const a = 1
const b = 2
const sum = computed(() => {
return a + b
})
可写的计算属性
如果想要给计算属性赋值,定义计算属性时要指定 setter。
const firstName = ref('xt')
const lastName = ref('zero')
const computed({
get() {
return `${firstName.value} ${lastName.value}`
},
set(v) {
[firstName.value, lastName.value] = v.split(' ')
}
})
条件渲染
v-if
<div v-if="dialog.show">
This is a dialog.
</div>
为 false
时会直接不渲染。
支持 v-else-if
和 v-else
。
<div v-if="isLogin">
欢迎你,{{ user.nickname }}!
</div>
<div v-else-if="isGuest && !isLogin">
欢迎你,游客!
</div>
<div v-else>
请注册或登录!
</div>
支持在 <template>
上使用
v-show
为 false
时会加上样式 display:none
,DOM 元素依然会渲染。
不支持在 <template>
上使用
不能和 v-else
一起使用。
v-if 和 v-for
不推荐一起使用。
如果一个元素同时存在二者,v-if
会先执行。
列表渲染 v-for
v-for
使用 item in items
语法,items
需要是一个可遍历的对象。
最好在每个循环项目上使用 key
来保证唯一性。
<div class="list">
<div
v-for="(v, k) in items"
:key="k"
class="list-item">
{{ v }}
</div>
</div>
v-for 使用范围值
items
可以传入一个整数值,这时 v-for
会依次遍历整数。
<span v-for="i in 10">{{ i }}</span>
这里的 i
是从 1
开始的。
v-for 与 template
v-for
和 v-if
一样,可以放在 template
元素上。
v-for 与 v-if
不建议二者一起使用。
v-if
优先级更高,所以 v-if
中不能使用 v-for
的遍历值。
<!-- 这样写是错误的,v-if 执行时 i 还未定义 -->
<span v-for="i in 10" v-if="i <= 5">{{ i }}</span>
可以使用 template
来包裹元素,将 v-for
放在 template
上来避免这个问题。
<template v-for="i in 10">
<span v-if="i <= 5">{{ i }}</span>
</template>
事件处理
使用 v-on
来绑定事件,可以简写为 @
,例如
<div v-on:click="onDivClick"></div>
<!-- 简写为 -->
<div @click="onDivClick"></div>
内联式
可以在 v-on
中直接写 js 表达式。
<div @click="count ++"></div>
方法式
可以在 v-on
中绑定一个方法。
<script setup>
const handleInc = () => {
count ++
}
</script>
<div @click="handleInc"> +1 </div>
调用方法时可以传参数。
<script setup>
const handleInc = num => {
count += num
}
</script>
<div @click="handleInc(2)"> +2 </div>
如果需要访问原生 onclick
方法中的 event
,可以使用箭头函数,或者使用 @click
的特殊变量 $event
。
<div @click="e => handleClick(e)"> Click Me </div>
<div @click="handleClick($event)"> Click Me </div>
表单输入绑定
v-model
。
<div>
name: <input v-model="name" />
</div>
默认是在 @input
时触发,添加修饰符 .lazy
后会在 @change
时触发。
添加 .number
修饰符可以自动转化为数字。
修饰符 .trim
会自动去除两端的空格。
生命周期
主要 onMounted
。
侦听器
可以监听一个值,在变化的时候进行一些处理。
watch(name, (newV, oldV) => {
[firstName, lastName] = newV.split(' ')
})
也可以在回调中执行异步操作、发送网络请求、修改 DOM 等。
不止侦听 ref
可以侦听 ref、计算属性、响应式对象、一个 getter 函数、或者是多者的数组。
深层侦听
当 watch
接收一个响应式对象时,会隐式地创建深层侦听器。
也可以显式定义一个深层侦听器。
watch(obj, (newV, oldV) => {
}, { deep: true })
立即执行
侦听器默认是懒执行的,仅有数据源变化时才会执行回调。我们可以让它创建时立即执行。
watch(obj, (newV, oldV) => {}, { immediate: true })
一次性侦听器
只会在数据源变化时触发一次。
watch(obj, (newV, oldV) => {}, { once: true })
watchEffect
使用 watchEffect
创建的侦听器不需要指定数据源,它会自动跟踪回调中的全部响应式数据。
watchEffect(() => {
[firstName, lastName] = name.value.split(' ')
})
停止侦听
侦听器使用同步语句创建时,会自动绑定到当前实例。侦听器会在当前实例销毁时自动停止。
如果使用异步创建侦听器,则不会绑定到当前实例,此时则需要主动停止侦听,否则会造成内存泄漏。
调用创建侦听器的返回值,会停止侦听。
const unwatch = watchEffect(() => {})
// 停止侦听
unwatch()
模板引用
在元素上使用 ref
html 属性来创建一个模板引用,同时需要定义一个和此 ref 属性同名的 ref 来接收模板引用。
<script setup>
const tableRef = ref(null)
</script>
<template>
<table ref="tableRef"></table>
</template>
组件
定义组件
使用 template
script
style
在一个 .vue
文件中创建一个单文件组件。
使用组件
在 script
中引入单文件组件,直接使用组件名当做标签名来使用组件。
<script setup>
import { ref } from 'vue'
const name = ref('Children')
</script>
<template>
<div>
这里是 {{ name }}
</div>
</template>
<script setup>
import { ref } from 'vue'
import Children from './Children.vue'
const name = ref('Parents')
</script>
<template>
<div>
<Children></Children>
这里是 {{ name }}
</div>
</template>
组件 props
使用 defintProps
来创建组件属性,在父组件调用时可以直接使用组件名传入值。
defineProps
是宏,不需要导入即可使用。
<script setup>
import { ref } from 'vue'
const props = defineProps({
name: '',
age: ''
})
</script>
<template>
<div>
<div>名字是:{{ props.name }}</div>
<div>年龄是:{{ props.age }}</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import Children from './Children.vue'
const childrens = ref([
{
name: 'xt',
age: 29
},
{
name: 'bigc',
age: 6
}
])
</script>
<template>
<div>
<Children
v-for="(v, k) in childrens"
:key="k"
:name="v.name"
:age="v.age">
</Children>
</div>
</template>