美文网首页
Vue基础知识1 2025-05-20 周二

Vue基础知识1 2025-05-20 周二

作者: 松哥888 | 来源:发表于2025-05-19 20:50 被阅读0次

简介

  • 一开始,前端开发是原生的HTML+CSS+JS
  • 后来,出现了jQuery
  • 再后来,出现了三驾马车:React,Angular,Vue
  • 现在基本上是二选一:React或者Vue
  • 认识的一个前端,开始是React,并且是蚂蚁的dva框架;后来再次遇到他,已经在用Vue
  • 所以,既然不会选,那么就跟随,也开始学Vue

官网文档学习

模板语法

  • 文本插值:最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):
<span>Message: {{ msg }}</span>
  • 原始 HTML: 双大括号会将数据解释为纯文本,而不是 HTML。若想插入 HTML,你需要使用 v-html 指令:
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

/*
Using text interpolation: <span style="color: red">This should be red.</span>
Using v-html directive: This should be red.
*/
  • Attribute 绑定: 想要响应式地绑定一个 attribute,应该使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
  • 指令 Directives: 指令 attribute 的期望值为一个 JavaScript 表达式。一个指令的任务是在其表达式的值变化时响应式地更新 DOM。
<p v-if="seen">Now you see me</p>
// 这里,v-if 指令会基于表达式 seen 的值的真假来移除/插入该 <p> 元素。
  • 参数 Arguments: 某些指令会需要一个“参数”,在指令名后通过一个冒号隔开做标识。
<a v-bind:href="url"> ... </a>

<!-- 简写 -->
<a :href="url"> ... </a>
<a v-on:click="doSomething"> ... </a>

<!-- 简写 -->
<a @click="doSomething"> ... </a>
  • 修饰符 Modifiers:修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。
<form @submit.prevent="onSubmit">...</form>
// .prevent 修饰符会告知 v-on 指令对触发的事件调用 event.preventDefault()

响应式基础

  • 在组合式 API 中,推荐使用 ref() 函数来声明响应式状态
import { ref } from 'vue'

export default {
  // `setup` 是一个特殊的钩子,专门用于组合式 API。
  setup() {
    const count = ref(0)

    // 将 ref 暴露给模板
    return {
      count
    }
  }
}
<button @click="count++">
  {{ count }}
</button>
  • 我们可以使用 <script setup> 来大幅度地简化代码:
<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }}
  </button>
</template>

计算属性

  • 我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。
<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>
  • 可写计算属性可以通过同时提供 getter 和 setter 来创建:
<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(' ')
  }
})
</script>
  • 如果需要,可以通过访问计算属性的 getter 的第一个参数来获取计算属性返回的上一个值:
<script setup>
import { ref, computed } from 'vue'

const count = ref(2)

// 这个计算属性在 count 的值小于或等于 3 时,将返回 count 的值。
// 当 count 的值大于等于 4 时,将会返回满足我们条件的最后一个值
// 直到 count 的值再次小于或等于 3 为止。
const alwaysSmall = computed((previous) => {
  if (count.value <= 3) {
    return count.value
  }

  return previous
})
</script>

类与样式绑定

  • 可以直接绑定一个对象:
const classObject = reactive({
  active: true,
  'text-danger': false
})
<div :class="classObject"></div>
/// <div class="active"></div>
  • 我们也可以绑定一个返回对象的计算属性。这是一个常见且很有用的技巧:
const isActive = ref(true)
const error = ref(null)

const classObject = computed(() => ({
  active: isActive.value && !error.value,
  'text-danger': error.value && error.value.type === 'fatal'
}))
<div :class="classObject"></div>
/// <div class="active"></div>
  • 我们可以给 :class 绑定一个数组来渲染多个 CSS class:
const activeClass = ref('active')
const errorClass = ref('text-danger')
<div :class="[activeClass, errorClass]"></div>
/// <div class="active text-danger"></div>
  • 如果你的组件有多个根元素,你将需要指定哪个根元素来接收这个 class。你可以通过组件的 $attrs 属性来指定接收的元素:
<!-- MyComponent 模板使用 $attrs 时 -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
<MyComponent class="baz" />
/// 使用时添加的baz添加到了<p>标签上
<p class="baz">Hi!</p>
<span>This is a child component</span>
  • 直接绑定一个样式对象通常是一个好主意,这样可以使模板更加简洁:
const styleObject = reactive({
  color: 'red',
  fontSize: '30px'
})
<div :style="styleObject"></div>
  • 我们还可以给 :style 绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上:
<div :style="[baseStyles, overridingStyles]"></div>

条件渲染

  • 顾名思义,v-else-if 提供的是相应于 v-if 的“else if 区块”。它可以连续多次重复使用:
<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
  • 因为 v-if 是一个指令,他必须依附于某个元素。但如果我们想要切换不止一个元素呢?在这种情况下我们可以在一个 <template> 元素上使用 v-if,这只是一个不可见的包装器元素,最后渲染的结果并不会包含这个 <template> 元素。
<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
  • 另一个可以用来按条件显示一个元素的指令是 v-show。不同之处在于 v-show 会在 DOM 渲染中保留该元素;v-show 仅切换了该元素上名为 display 的 CSS 属性。v-show 不支持在 <template> 元素上使用,也不能和 v-else 搭配使用。
<h1 v-show="ok">Hello!</h1>

列表渲染

  • 我们可以使用 v-for 指令基于一个数组来渲染一个列表。v-for 指令的值需要使用 item in items 形式的特殊语法
const items = ref([{ message: 'Foo' }, { message: 'Bar' }])
<li v-for="item in items">
  {{ item.message }}
</li>
  • 你也可以使用 v-for 来遍历一个对象的所有属性
const myObject = reactive({
  title: 'How to do lists in Vue',
  author: 'Jane Doe',
  publishedAt: '2016-04-10'
})
<ul>
  <li v-for="value in myObject">
    {{ value }}
  </li>
</ul>
  • v-for 可以直接接受一个整数值。在这种用例中,会将该模板基于 1...n 的取值范围重复多次。
<span v-for="n in 10">{{ n }}</span>
/// 注意此处 n 的初值是从 1 开始而非 0。
  • 可以在 <template> 标签上使用 v-for 来渲染一个包含多个元素的块。
<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>
  • 需要为每个元素对应的块提供一个唯一的 key attribute:
<div v-for="item in items" :key="item.id">
  <!-- 内容 -->
</div>
  • 当你使用 <template v-for> 时,key 应该被放置在这个 <template> 容器上:
<template v-for="todo in todos" :key="todo.name">
  <li>{{ todo.name }}</li>
</template>
  • 有时,我们希望显示数组经过过滤或排序后的内容,而不实际变更或重置原始数据。在这种情况下,你可以创建返回已过滤或已排序数组的计算属性。
const numbers = ref([1, 2, 3, 4, 5])

const evenNumbers = computed(() => {
  return numbers.value.filter((n) => n % 2 === 0)
})
<li v-for="n in evenNumbers">{{ n }}</li>
  • 在计算属性中使用 reverse() 和 sort() 的时候务必小心!这两个方法将变更原始数组,计算函数中不应该这么做。请在调用这些方法之前创建一个原数组的副本:
- return numbers.reverse()
+ return [...numbers].reverse()

事件处理

  • 我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript。用法:v-on:click="handler" 或 @click="handler"。

  • 内联事件处理器通常用于简单场景,例如:

const count = ref(0)

<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>
  • 随着事件处理器的逻辑变得愈发复杂,内联代码方式变得不够灵活。因此 v-on 也可以接受一个方法名或对某个方法的调用。
const name = ref('Vue.js')

function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` 是 DOM 原生事件
  if (event) {
    alert(event.target.tagName)
  }
}

<!-- `greet` 是上面定义过的方法名 -->
<button @click="greet">Greet</button>
  • 除了直接绑定方法名,你还可以在内联事件处理器中调用方法。这允许我们向方法传入自定义参数以代替原生事件:
function say(message) {
  alert(message)
}

<button @click="say('hello')">Say hello</button>
<button @click="say('bye')">Say bye</button>
  • 在处理事件时调用 event.preventDefault() 或 event.stopPropagation() 是很常见的。尽管我们可以直接在方法内调用,但如果方法能更专注于数据逻辑而不用去处理 DOM 事件的细节会更好。
<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a>

<!-- 提交事件将不再重新加载页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 修饰语可以使用链式书写 -->
<a @click.stop.prevent="doThat"></a>

<!-- 也可以只有修饰符 -->
<form @submit.prevent></form>

<!-- 仅当 event.target 是元素本身时才会触发事件处理器 -->
<!-- 例如:事件处理器不来自子元素 -->
<div @click.self="doThat">...</div>

<!-- 添加事件监听器时,使用 `capture` 捕获模式 -->
<!-- 例如:指向内部元素的事件,在被内部元素处理前,先被外部处理 -->
<div @click.capture="doThis">...</div>

<!-- 点击事件最多被触发一次 -->
<a @click.once="doThis"></a>

<!-- 滚动事件的默认行为 (scrolling) 将立即发生而非等待 `onScroll` 完成 -->
<!-- 以防其中包含 `event.preventDefault()` -->
<div @scroll.passive="onScroll">...</div>

表单输入绑定

在前端处理表单时,我们常常需要将表单输入框的内容同步给 JavaScript 中相应的变量。v-model 可以用于各种不同类型的输入。

  • 文本
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
  • 多行文本
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
  • 单一的复选框,绑定布尔类型值:
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
  • 可以将多个复选框绑定到同一个数组或集合的值:
const checkedNames = ref([])
<div>Checked names: {{ checkedNames }}</div>

<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>

<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>

<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>
  • 单选按钮
<div>Picked: {{ picked }}</div>

<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>

<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
  • 单个选择器
<div>Selected: {{ selected }}</div>

<select v-model="selected">
  <option disabled value="">Please select one</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
  • 多选 (值绑定到一个数组):
<div>Selected: {{ selected }}</div>

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
  • 如果你想要默认自动去除用户输入内容中两端的空格,你可以在 v-model 后添加 .trim 修饰符:
<input v-model.trim="msg" />
  • 如果你想让用户输入自动转换为数字,你可以在 v-model 后添加 .number 修饰符来管理输入:
<input v-model.number="age" />

参考文章

Vue的官网

相关文章

网友评论

      本文标题:Vue基础知识1 2025-05-20 周二

      本文链接:https://www.haomeiwen.com/subject/klabijtx.html