本页内容基于VUE3.2版本,且以组合式API模式编写
<script setup>
推荐的 IDE 配置是 Visual Studio Code + Volar 扩展
中文文档:https://staging-cn.vuejs.org/
使用Vite安装Vue
npm init vite@latest <project-name> -- --template vue
# 或者
npm create vite@latest <project-name> -- --template vue
cd <project-name>
npm install
npm run dev
模板语法
// 显示文本
<span>Message: {{ msg }}</span>
// 显示原始HTML
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
// 绑定HTML属性
<div v-bind:id="dynamicId"></div>
// 绑定多个HTML属性
<div v-bind="objectOfAttrs"></div>
// 调用函数
<span :title="toTitleDate(date)">
{{ formatDate(date) }}
</span>
// 绑定动态参数
<a v-bind:[attributeName]="url"> ... </a>
<a v-on:[eventName]="doSomething"> ... </a>
// 如果需要操作['foo' + bar],建议使用计算属性
// 修饰符
<form @submit.prevent="onSubmit">...</form>
// 绑定多个HTML属性
const objectOfAttrs = {
id: 'container',
class: 'wrapper'
}
简写:
v-bind
简写为:
v-on
简写为@
响应式
<script setup>
import { ref,reactive } from 'vue';
const count = ref(0);
console.log(count.value) // 0
// ref声明的对象,在程序内使用需要加.value
const count1 = $ref(0);
console.log(count1) // 0
// 使用$ref声明响应式对象,使用时无需.value
const state = reactive({
num:0
});
console.log(state.num) // 0
function increment() {
state.num++
}
</script>
<template>
<button @click="increment">
{{ state.num }}
</button>
<p>{{count}}</p>
</template>
计算属性
与方法的区别:计算属性值会基于响应式依赖关系被缓存,只在响应式依赖更新时才会重新计算,重新渲染时不会被更新
计算属性格式:
import { ref,reactive,computed } from 'vue'
const state = reactive({
num:0
});
//计算属性
const count = computed(()=>{
return state.num > 0 ? 'Yes' : 'No';
});
// 模板中使用:{{ count }}
//对应方法
function count(){
return state.num > 0 ? 'Yes' : 'No';
}
// 模板中使用:{{ count() }}
计算属性被是为“临时快照”,返回的值是派生状态,默认使用get方法,也可以使用set方法来更新更新派生值,不要在计算属性中通过异步请求修改原始值
条件渲染
<p v-if=""></p>
<p v-else-if=""></p>
<p v-else></p>
<p v-show></p>
// v-show只修改元素的display,依然会保留元素,但v-if不会保留
列表渲染
v-for
是用来将数据渲染到列表
<li v-for="item in items">
{{ item.message }}
</li>
<li v-for="(item, index) in items">
//item 单项别名
// index 单项索引
</li>
对应JavaScript代码
const items = [];
items.forEach((item.index)=>{
//...
});
循环整数
<span v-for="n in 10">{{ n }}</span>
v-for
也可以遍历对象
<ul>
<li v-for="value in myObject">
{{ value }}
</li>
</ul>
<li v-for="(value, key) in myObject">
{{ key }}: {{ value }}
</li>
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
template上使用v-for
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
通过key管理状态
如果是简单的列表,vue会自动将index作为key,如果复杂的列表需要单独设置一个唯一key,唯一key可以保证每次更新只更新单个元素而非整个列表
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
组件上使用v-for
<my-component
v-for="(item, index) in items"
:item="item"
:index="index"
:key="item.id"
></my-component>
必须将item以prop形式传给子组件,子组件才可以使用
过滤或排序
使用计算属性预先处理原始数据即可 JavaScript常见变更数组方法:push()、pop()、shift()、unshift()、splice()、sort()、reverse() 不变更数据方法:filter(),concat() 和 slice()
事件处理
事件监听: v-on:click="methodName"
或 @click="handler"
内联事件
const count = ref(0)
<button @click="count++">Add 1</button>
方式事件
function say(message) {
alert(message)
}
<button @click="say('hello')">Say hello</button
事件修饰符
- .stop
- .prevent
- .self
- .capture
- .once
- .passive
<!-- 单击事件将停止传递 -->
<a @click.stop="doThis"></a>
按键修饰符
- .enter
- .tab
- .delete (捕获“Delete”和“Backspace”两个按键)
- .esc
- .space
- .up
- .down
- .left
- .right
<!-- 仅在 `key` 为 `Enter` 时调用 `vm.submit()` -->
<input @keyup.enter="submit" />
系统按键修饰符
- .ctrl
- .alt
- .shift
- .meta
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
<!-- Ctrl + 点击 -->
<div @click.ctrl="doSomething">Do something</div>
鼠标按键修饰符
- .left
- .right
- .middle
表单输入绑定
基本用法
// 文本
<input v-model="message" />
// 多行文本
<textarea v-model="message"></textarea>
// 复选框 const checked = ref(true)
<input type="checkbox" id="checkbox" v-model="checked" />
// 如果将checked设置为数组,且多个input绑定了checked,则选中的结果或存放在checked数组中,const checkedNames = ref([])
// 单选框 const picked = ref('One')
<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>
// 下拉框单选 const selected = ref('')
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
// 下拉多选 const selected = ref([])
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Vue组件
使用组件
// 子组件 Bar.vue
<script setup>
<template>
<h1>这是子组件</h1>
</template>
// 父组件 Foo.vue
<script setup>
import Bar from './Bar.vue' //引入子组件
</script>
<template>
<h1>这是父组件</h1>
<Bar /> // 使用子组件
</template>
传递props
用于父组件给子组件传递值
<!-- 子组件:BlogPost.vue -->
<script setup>
defineProps(['title']) //生命参数
// const props = defineProps(['title'])
// console.log(props.title)
// 限制格式
// defineProps({
// title: String,
// likes: Number
//}})
</script>
<template>
<h4>{{ title }}</h4> <!-- 使用参数 -->
</template>
<!-- 父组件:Blog.vue,将值传给参数title -->
<BlogPost title="My journey with Vue" />
监听事件
父组件监听子组件事件(将子组件事件传给父组件)
方法1:使用$emit
方法监听事件
使用$emit
声明一个事件,然后在父组件中监听这个事件,当事件触发后父组件执行相应的其它事件
// 父组件
<BlogPost
...
@do="doSomething"
/>
// 子组件
<button @click="$emit('do')">Do Something</button>
//<button @click="$emit('do','传给父组件的内容','...')">Do Something</button>
方法2:使用defineEmits
监听子组件事件,并获取回传的参数值
// 父组件
function doSomething(data){
alert(data) //data:回传的值
}
<BlogPost
...
@do="doSomething"
/>
// 子组件
const emit = defineEmits(['do'])
const do = ()=>{
emit('do','回传的值')
}
<button @click="do">Do Something</button>
方法3:组件上使用v-model
来实现子父组件之间内容传递
插槽
插槽<slot>
是占位符,用来在子组件中对应位置显示父组件传递的内容(也可以通过传值的方式来替代插槽)
// 父组件
<Bar>
这是父组件传递的内容
</Bar>
// 子组件
<p>这是子组件的一部分内容</p>
<slot /> <!--这儿会显示父组件传递的内容-->
<p>这是子组件的另一部分内容</p>