santisify Site

Back

Vue学习笔记(一)Blur image

部分示例来源于vuejs中文官网

Vue3对Vue2向下兼容,但部分不兼容

语法#

文本插值:#

HTML中插入文本

html

HTML插值:#

上述操作只能插入纯文本,可以使用v-html插入html文本

<p>Using v-html directive: <span v-html="rawHtml"></span></p>    
html

Attribute 绑定#

对使用的元素属性进行绑定 想响应式绑定一个Attribute,但又不能使用{{ }}时,可使用v-bind指令:

<div v-bind:id="num"></div>    
html

v-bind指令指示 Vue 将元素的idattribute 与组件的num属性保持一致。如果绑定的值是null或者undefined,那么该 attribute 将会从渲染的元素上移除。 简写:

<div :id="num"></div>    
html

示例:

//点击方块后颜色切换,其中click和ref会在下面会讲到  
<template>  
    <div style="height: 100px; width: 100px;" @click="switchColor" :class="str"></div>  
</template>  
<script setup>  
    import {ref} from 'vue'  
  
    let str = ref("su");  
  
    function switchColor() {  
        str.value = "s";  
    }  
</script>  
<style scoped>  
    .su {  
        background-color: red;  
    }  
  
    .s {  
        background-color: green;  
    }  
</style>    
html

也可设为bool型数据

<button :disabled="isButtonDisabled">Button</button>    
html

isButtonDisabled真值或一个空字符串 (即
<button disabled="">) 时,元素会包含这个disabled attribute。而当其为其他假值时 attribute 将被忽略。

动态绑定多个值#

如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:

const objectOfAttrs = {  
    id: 'container',  
    class: 'wrapper',  
    style: 'background-color:green'  
}    
js

通过不带参数的v-bind,你可以将它们绑定到单个元素上:

<div v-bind="objectOfAttrs"></div>    
html

使用 JavaScript 表达式#

至此,我们仅在模板中绑定了一些简单的属性名。但是 Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式:

{{ number + 1 }}  
{{ ok ? 'YES' : 'NO' }}  
{{ message.split('').reverse().join('') }}  
<div :id="`list-${id}`"></div>    
html

这些表达式都会被作为 JavaScript ,以当前组件实例为作用域解析执行。 在 Vue 模板内,JavaScript 表达式可以被使用在如下场景上:

  • 在文本插值中 (双大括号)
  • 在任何 Vue 指令 (以v-开头的特殊 attribute) attribute 的值中

仅支持表达式#

每个绑定仅支持单一表达式,也就是一段能够被求值的 JavaScript 代码。一个简单的判断方法是是否可以合法地写在return后面。

因此,下面的例子都是无效的:

<!-- 这是一个语句,而非表达式 -->  
{  
    {  
        var a = 1  
    }  
}  
  
<!-- 条件控制也不支持,请使用三元表达式 -->  
{  
    {  
        if (ok) {  
            return message  
        }  
    }  
}    
js

调用函数#

可以在绑定的表达式中使用一个组件暴露的方法:

<time :title="toTitleDate(date)" :datetime="date">  
    {{ formatDate(date) }}  
</time>    
html

Tip: 绑定在表达式中的方法在组件每次更新时都会被重新调用,因此应该产生任何副作用,比如改变数据或触发异步操作。

受限的全局访问#

模板中的表达式将被沙盒化,仅能够访问到有限的全局对象列表。该列表中会暴露常用的内置全局对象,比如MathDate。 没有显式包含在列表中的全局对象将不能在模板内表达式中访问,例如用户附加在window上的属性。然而,你也可以自行在app.config.globalProperties上显式地添加它们,供所有的 Vue 表达式使用。

响应式基础#

ref()#

组合式API中,使用ref()函数声明响应式状态

import {ref} from 'vue'  
  
const num = ref(100);    
js

ref()接收参数,并将其包裹在一个带有.value属性的 ref 对象中返回 所以vue中的js需要使用组合式setup(),并且在使用时需要添加上.value

示例:

<template>  
    <button @click="increment">  
        {{ count }}  
    </button>  
</template>  
  
<script setup>  
    import {ref} from 'vue'  
  
    const count = ref(0)  
  
    function increment() {  
        count.value++  
    }  
</script>    
html

vue2中使用set()实现响应式,而在vue3中使用ref(),并且vue3不兼容set()函数

深层响应性#

Ref 可以持有任何类型的值,包括深层嵌套的对象、数组或者 JavaScript 内置的数据结构,比如Map

Ref 会使它的值具有深层响应性。这意味着即使改变嵌套对象或数组时,变化也会被检测到:

import {ref} from 'vue'  
  
const obj = ref({  
    nested: {count: 0},  
    arr: ['foo', 'bar']  
})  
  
function mutateDeeply() {  
    // 以下都会按照期望工作    
obj.value.nested.count++  
    obj.value.arr.push('baz')  
}    
js

reactive()#

reactive()是响应式的另一种APIreactive()可使对象本身具有响应性

import {reactive} from 'vue'  
  
const state = reactive({count: 0})  
js

template中以下方式使用:

<template>  
    <button @click="state.cnt ++">  
        {{ state.cnt }}  
    </button>  
</template>  
html

计算属性#

基础示例#

<template>  
    <span>{{ author.books.length > 0 ? "YES" : "NO" }}</span>  
</template>  
  
<script setup>  
    import {reactive} from "vue";  
  
    const author = reactive({  
        name: 'John Doe',  
        books: [  
            'Vue 2 - Advanced Guide',  
            'Vue 3 - Basic Guide',  
            'Vue 4 - The Mystery'  
        ]  
    })  
</script>  
html

在上述示例中,可以发现计算是依靠author.books的大小确定的,如果我在模板中多次使用这样的判断,是否显得过于臃肿。
对于这样的判断可以引入computed().

computed()#

<script setup>  
    import {reactive, computed} from 'vue'  
  
    const author = reactive({  
        name: 'John Doe',  
        books: [  
            'Vue 2 - Advanced Guide',  
            'Vue 3 - Basic Guide',  
            'Vue 4 - The Mystery'  
        ]  
    })  
  
    // 一个计算属性 ref  
    const publishedBooksMessage = computed(() => {  
        return author.books.length > 0 ? 'Yes' : 'No'  
    })  
</script>  
  
<template>  
    <p>Has published books:</p>  
    <span>{{ publishedBooksMessage }}</span>  
</template>  
html

我们在这里定义了一个计算属性publishedBooksMessagecomputed()
方法期望接收一个getter 函数
,返回值为一个计算属性 ref。和其他一般的 ref 类似,你可以通过publishedBooksMessage.value访问计算结果。计算属性 ref
也会在模板中自动解包,因此在模板表达式中引用时无需添加.value

Vue 的计算属性会自动追踪响应式依赖。它会检测到publishedBooksMessage依赖于author.books,所以当author.books改变时,任何依赖于
publishedBooksMessage的绑定都会同时更新。

可写计算属性#

计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性,你可以通过同时提供
getter 和 setter 来创建:

<template>  
    {{fullName}}  
</template>  
<script setup>  
    import {ref, computed} from 'vue'  
  
    const firstName = ref('John')  
    const lastName = ref('Doe')  
  
    const fullName = computed({  
    // getter    
    get() {  
    return firstName.value + ' ' + lastName.value  
},  
    // setter    
    set(newValue) {  
    // 注意:我们这里使用的是解构赋值语法    
    [firstName.value, lastName.value] = newValue.split(' ')  
}})  
  
    console.log(fullName.value, firstName.value, lastName.value);  
  
    fullName.value = "Jack Doe";  
  
    console.log(fullName.value, firstName.value, lastName.value);  
</script>  
js

在上述示例中,当运行fullName.value = "Jack Doe";时,firstNamelastName也会随之更新。

类与样式绑定#

绑定HTML class#

绑定对象#

绑定对象一般使用v-bind,比如绑定class一般写为v-bind:class 简写为:class,对其传递对象可动态切换class:

<div :class="{ active: isActive }"></div>  
html

其中class的active是否存在由isActive的真值来确定。
对象中可通过多个字段class对象
例如:

<template>  
    <div  
            class="static"  
            :class="{ active: isActive, 'text-danger': hasError }">  
        123  
    </div>  
</template>  
<script setup>  
    import {ref} from "vue";  
  
    const isActive = ref(true)  
    const hasError = ref(false)  
</script>  
  
<style scoped>  
    .text-danger {  
        color: red;  
    }  
</style>  
html

在上述示例中,字段active, hasError 的真值影响在class类中是否存在对应的类名。当hasError为真时,由于css中的text-danger
样式,会将字体123改变为红色。
上述示例渲染后的效果如下:

<div class="static active"> 123</div>  
html

通过以上,我们可以对:class传入一个对象

<template>  
    <div  
            class="static"  
            :class="obj">  
        123  
    </div>  
</template>  
<script setup>  
    import {reactive} from "vue";  
  
    const obj = reactive({  
        active: true,  
        'text-danger': false,  
    })  
</script>  
  
<style scoped>  
    .text-danger {  
        color: red;  
    }  
</style>  
html

传入对象方法渲染后的效果同上,个人较为喜欢多个字段操作

我们也可以绑定一个返回对象的[[#计算属性]]。这是一个常见且很有用的技巧:

const isActive = ref(true)  
const error = ref(null)  
  
const obj = computed(() => ({  
    active: isActive.value && !error.value,  
    'text-danger': error.value && error.value.type === 'fatal'  
}))  
js
  
<div :class="classObject"></div>  
html

绑定数组#

我们可以给:class绑定一个数组来渲染多个 CSS class:

const activeClass = ref('active')  
const errorClass = ref('text-danger')  
js
<div :class="[activeClass, errorClass]"></div>  
html

渲染的结果是:

<div class="active text-danger"></div>  
html

如果你也想在数组中有条件地渲染某个 class,你可以使用三元表达式:

<div :class="[isActive ? activeClass : '', errorClass]"></div>  
html

errorClass会一直存在,但activeClass只会在isActive为真时才存在。

然而,这可能在有多个依赖条件的 class 时会有些冗长。因此也可以在数组中嵌套对象:

<div :class="[{ [activeClass]: isActive }, errorClass]"></div>  
html

在组件上使用#

本节假设你已经有Vue 组件的知识基础。如果没有,你也可以暂时跳过,以后再阅读。

对于只有一个根元素的组件,当你使用了classattribute 时,这些 class 会被添加到根元素上并与该元素上已有的 class 合并。

举例来说,如果你声明了一个组件名叫MyComponent,模板如下:

<!-- 子组件模板 -->  
<p class="foo bar">Hi!</p>  
html

在使用时添加一些 class:

<!-- 在使用组件时 -->  
<MyComponent class="baz boo"/>  
html

渲染出的 HTML 为:

<p class="foo bar baz boo">Hi!</p>  
html

Class 的绑定也是同样的:

<MyComponent :class="{ active: isActive }"/>  
html

isActive为真时,被渲染的 HTML 会是:

<p class="foo bar active">Hi!</p>  
html

如果你的组件有多个根元素,你将需要指定哪个根元素来接收这个 class。你可以通过组件的$attrs属性来指定接收的元素:

<!-- MyComponent 模板使用 $attrs 时 -->  
<p :class="$attrs.class">Hi!</p>  
<span>This is a child component</span>  
html
<MyComponent class="baz"/>  
html

这将被渲染为:

<p class="baz">Hi!</p>  
<span>This is a child component</span>  
html

你可以在透传 Attribute一章中了解更多组件的 attribute 继承的细节。

绑定内联样式#

绑定对象#

:style支持绑定 JavaScript 对象值,对应的是HTML 元素的style属性:

const activeColor = ref('red')  
const fontSize = ref(30)  
js
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>  
html

尽管推荐使用 camelCase,但:style也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称),例如:

<div :style="{ 'font-size': fontSize + 'px' }"></div>  
html

直接绑定一个样式对象通常是一个好主意,这样可以使模板更加简洁:

const styleObject = reactive({  
    color: 'red',  
    fontSize: '30px'  
})  
js
<div :style="styleObject"></div>  
html

同样的,如果样式对象需要更复杂的逻辑,也可以使用返回样式对象的计算属性。

绑定数组#

我们还可以给:style绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上:

<div :style="[baseStyles, overridingStyles]"></div>  
html

自动前缀#

当你在:style中使用了需要浏览器特殊前缀的 CSS
属性时,Vue 会自动为他们加上相应的前缀。Vue 是在运行时检查该属性是否支持在当前浏览器中使用。如果浏览器不支持某个属性,那么将尝试加上各个浏览器特殊前缀,以找到哪一个是被支持的。

样式多值#

你可以对一个样式属性提供多个 (不同前缀的) 值,举例来说:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>  
html

数组仅会渲染浏览器支持的最后一个值。在这个示例中,在支持不需要特别前缀的浏览器中都会渲染为display: flex

Vue学习笔记(一)
https://santisify.top/blog/old/vue1
Author santisify
Published at March 10, 2025
Comment seems to stuck. Try to refresh?✨