Skip to content

Vue3

指令

文本插值

vue
<template>
    {{ msg }}
</template>

<script lang="ts">
import {defineComponent} from 'vue'

export default defineComponent({
    setup() {
        const msg = "this is a message";
        return {
            msg
        }
    }
})
</script>

属性绑定

vue
<div v-bind:id="dynamicId"></div>

简写(省略 v-bind,直接用 :)

vue
<div :id="dynamicId"></div>

事件绑定

vue
<a v-on:click="doSomething"> ... </a>

简写(省略 v-on:,直接使用 @)

vue
<a @click="doSomething"> ... </a>

双向数据绑定

bash
仅限:
	- input
	- select
	- textarea
	- components
修饰符:
	- .lazy   监听 change 事件,而不是 input
	- .number 将输入的合法字符串转换为数字
	- .trim   移除两端的空格

input

vue
<template>
    <input v-model="text">
    <p>Message is: {{ text }} </p>
</template>

<script lang="ts" setup>
const text = "hello";
</script>

textarea

vue
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

checkbox

vue
<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>

radio

vue
<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>

select

vue
<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>

组件传值

父传子

父组件向子组件传值时,在父组件中使用子组件时,只需要在子组件标签上进行属性绑定,同时在子组件中使用 defineProps 接收父组件传入的属性。

父组件

vue
<script setup>
const username = 'vue'
</script>

<template>
  <children :username="username" />
</template>

子组件

vue
<script setup>
import { defineProps } from 'vue';

// 这里可以将 `username` 解构出来,
// 但是一旦解构出来再使用,就不具备响应式能力
defineProps({
  username: String
})
</script>

<template>
  <p>username: {{ username }}</p>
</template>

子传父

difineEmits

子组件 在子组件中定义 emit 函数

vue
<template>
  <input v-model="keyword" />
  <button @click="onSearch">search</button>
</template>

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

const emit = defineEmits(['search'])

const keyword = ref('')
const onSearch = function() {
  emit('search', keyword.value)
}
</script>

父组件 在父组件中通过绑定子组件中定义的事件函数来操作子组件的属性

vue
<template>
  <children @search="onSearch" />
</template>

<script setup>
const onSearch = function(keyword){
  console.log(keyword)
}
</script>

defineExpose

子组件

在子组件中,通过 defineExpose 将定义的事件暴露出去

vue
<template>
  <input v-model="keyword" />
</template>

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

const keyword = ref('')
const onSearch = function() {
  console.log(keyword.value)
}

defineExpose({ onSearch })
</script>

父组件

在父组件中通过 ref=childrenRef 来调用子组件暴露出来的事件

vue
<template>
  <children ref='childrenRef' />
  <button @click="onSearch">search</button>
</template>

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

const childrenRef = ref(null)
const onSearch = function() {
  childrenRef.value.onSearch()
}
</script>

兄弟组件间传值

兄弟组件之间传值使用 provide/inject

ts
// src/types/pi.ts
import type { InjectionKey, Ref } from 'vue'

export const ProvideKey = Symbol() as InjectionKey<Ref<string>>

provide

数据提供方

vue
<template>
  <input v-model="text" />
</template>

<script setup lang="ts">
import { provide, ref } from 'vue'
import { ProvideKey } from '@/types/pi'

const text = ref<string>('123')
provide(ProvideKey, text)
</script>

inject

数据接收方

vue
<template>
  <h4>{{value}}</h4>
</template>

<script setup lang="ts">
import { inject } from 'vue'
import { ProvideKey } from '@/types/pi'

const value = inject(ProvideKey)
</script>