Files
home/docs/vue/basic.md
2026-05-13 16:24:00 +08:00

4.0 KiB

Vue3基础

创建应用

使用Vite创建项目

npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install
npm run dev

应用实例

<script setup>
import { ref } from 'vue'

const message = ref('Hello Vue 3!')
</script>

<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<style scoped>
h1 {
  color: #42b883;
}
</style>

模板语法

文本插值

<template>
  <p>{{ message }}</p>
  <p>{{ number + 1 }}</p>
  <p>{{ ok ? 'YES' : 'NO' }}</p>
</template>

<script setup>
import { ref } from 'vue'

const message = ref('Hello')
const number = ref(10)
const ok = ref(true)
</script>

属性绑定

<template>
  <div v-bind:id="dynamicId"></div>
  <div :class="activeClass"></div>
  <button :disabled="isDisabled">按钮</button>
</template>

<script setup>
import { ref } from 'vue'

const dynamicId = ref('my-id')
const activeClass = ref('active')
const isDisabled = ref(false)
</script>

条件渲染

<template>
  <div v-if="type === 'A'">类型A</div>
  <div v-else-if="type === 'B'">类型B</div>
  <div v-else>其他类型</div>
  
  <div v-show="isVisible">显示/隐藏</div>
</template>

<script setup>
import { ref } from 'vue'

const type = ref('A')
const isVisible = ref(true)
</script>

列表渲染

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
    </li>
  </ul>
  
  <ul>
    <li v-for="(item, index) in items" :key="item.id">
      {{ index }}: {{ item.name }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([
  { id: 1, name: 'Vue' },
  { id: 2, name: 'React' },
  { id: 3, name: 'Angular' }
])
</script>

事件处理

<template>
  <button v-on:click="count++">点击次数: {{ count }}</button>
  <button @click="handleClick">点击</button>
  <button @click="handleClick($event, '参数')">传参</button>
  
  <form @submit.prevent="onSubmit">
    <button type="submit">提交</button>
  </form>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)

function handleClick(event) {
  console.log('点击事件', event)
}

function onSubmit() {
  console.log('表单提交')
}
</script>

双向绑定

<template>
  <input v-model="text" placeholder="输入文本">
  <p>输入的内容: {{ text }}</p>
  
  <textarea v-model="content"></textarea>
  
  <select v-model="selected">
    <option value="">请选择</option>
    <option value="a">选项A</option>
    <option value="b">选项B</option>
  </select>
  
  <input type="checkbox" v-model="checked">
  <input type="radio" v-model="picked" value="one">
</template>

<script setup>
import { ref } from 'vue'

const text = ref('')
const content = ref('')
const selected = ref('')
const checked = ref(false)
const picked = ref('')
</script>

计算属性

<template>
  <p>原始: {{ message }}</p>
  <p>反转: {{ reversedMessage }}</p>
  <p>全名: {{ fullName }}</p>
</template>

<script setup>
import { ref, computed } from 'vue'

const message = ref('Hello Vue')
const firstName = ref('张')
const lastName = ref('三')

const reversedMessage = computed(() => {
  return message.value.split('').reverse().join('')
})

const fullName = computed({
  get() {
    return firstName.value + lastName.value
  },
  set(newValue) {
    firstName.value = newValue[0]
    lastName.value = newValue.slice(1)
  }
})
</script>

侦听器

<template>
  <input v-model="question">
  <p>{{ answer }}</p>
</template>

<script setup>
import { ref, watch } from 'vue'

const question = ref('')
const answer = ref('请输入问题')

watch(question, async (newQuestion) => {
  if (newQuestion.includes('?')) {
    answer.value = '思考中...'
    // 模拟API调用
    setTimeout(() => {
      answer.value = '这是一个好问题!'
    }, 1000)
  }
})

// 监听多个源
watch([question, answer], ([newQuestion, newAnswer], [oldQuestion, oldAnswer]) => {
  console.log('问题或答案改变了')
})
</script>