学习资料
-
Vue3中文官网
https://cn.vuejs.org/
-
vue3改了几个生命周期函数-前端问答-PHP中文网
https://www.php.cn/website-design-ask-500066.html
使用vite构建vue3
npm init vue@latest
构建之后,进入项目目录,然后安装依赖:
npm install
基本实例
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app"></div>
<script>
// 方法一(选项式)
const App = {
//配置对象
data() {
num: 0
}
}
Vue.createApp(App).mount('#app')
// 方法二(组合式)
const App = {
//配置对象
setup() {
let num = Vue.ref(0)
return {
num
}
}
}
Vue.createApp(App).mount('#app')
</script>
vue2与vue3生命周期的区别
vue2 | vue3 |
---|---|
beforeCreate | setup() 开始创建组件之前,创建的是data和method |
created | setup() |
beforeMount | onBeforeMounted 组件挂载到节点之前执行的函数。 |
mounted | onMounted 组件挂载完成后执行的函数。 |
beforeUpdate | onBeforeUpdate 组件更新之前执行的函数。 |
updated | onUpdated 组件更新完成之后执行的函数。 |
beforeDestroy | onBeforeUnmount 组件卸载之前执行的函数。 |
destroyed | onMounted 组件卸载完成之后执行的函数。 |
总结:
- vue3 组合式 api 取消了
beforeCreate
和created
钩子函数,采用setup
钩子代替,且里面不能使用this
。 - vue3 里面的组件销毁的钩子函数换成了
beforeUnmount
和unmounted
,之前是destroyed
和beforeDestroy
,但是要注意,如果 vue3 使用 vue2 的选择式写法,之前的钩子函数还是可以使用。 - vue3 的组合式 api 生命周期函数要比 vue2 选择式 api 的生命周期多个前缀
on
,而且要import
单独引入。
指令
v-html 解析html标签 v-html="<h1>Welcome!</h1>"
v-bind 动态绑定属性 v-bind:id="index"
等价于 :id="index"
v-on 绑定监听事件 v-on:click="showMsg"
等价于 @click="showMsg"
v-model 双向数据绑定 v-model="inputValue"
- 修饰符
.lazy
在 “change” 事件后同步更新而不是 “input” - 修饰符
.number
让用户输入自动转换为数字 - 修饰符
.trim
自动去除用户输入内容中两端的空格
v-if v-else v-else-if 条件渲染 组件上使用时要注意
v-show 控制显示和隐藏
v-for 列表渲染 组件上使用时要注意
// v-for遍历数组
<li v-for="(val, key) in arr"> {
{
val, key }} <li>
// v-for遍历对象
<li v-for="(val, key, index) in objs"> {
{
val, key, index }} <li>
v-for
可以直接接受一个整数值。在这种用例中,会将该模板基于 1...n
的取值范围重复多次。注意此处 n
的初值是从 1
开始而非 0
。
<span v-for="n in 10">{
{
n }}</span>
在组件上使用时,不会直接将数据传递给子组件,因为子组件有自己独立的作用域。为了将迭代后的数据传递到子组件中,我们还需要传递props。
<MyComponent
v-for="(item, index) in items"
:item="item"
:index="index"
:key="item.id"
/>
在模板中只能书写JavaScript表达式,判断是否是表达式的方法是:是否可以合法地写在 return 后面。
事件配合v-model
注意下面的情况都是建立在 v-model 使用在组件的基础上的。
默认情况下,v-model
在组件上使用都是使用 modelValue
作为prop,并以update:modelValue
作为对应的事件。但我们也可以自定义一些参数来更改这些名字。
-
父组件传递参数和数据
// 父组件 <MyComponent v-model:title="bookTitle" />
-
子组件声明属性和触发事件更新父组件(达到数据双向绑定)
// 子组件 defineProps(['title']) defineEmits(['update:title']) <input type="text" :value="title" @input="$emit('update:title', $event.target.value)" />
这样的话,v-model
就能多个值绑定了:
// 父组件
<UserName
v-model:first-name="first"
v-model:last-name="last"
/>
// 子组件
defineProps({
firstName: String,
lastName: String
})
defineEmits(['update:firstName', 'update:lastName'])
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
自定义v-model修饰符
-
父组件定义修饰符
//父组件 <MyComponent v-model.capitalize="bookTitle" />
-
子组件声明属性和触发事件、自定义功能触发函数
//子组件 const props = defineProps({ modelValue: String, modelModifiers: { default: () => ({ }) } }) defineEmits(['update:modelValue']) <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
如果是自定义v-model参数,代码如下:
//父组件
<MyComponent v-model:title.capitalize="bookTitle" />
//子组件
const props = defineProps({
title: String,
titleModifiers: {
default: () => {
} }
})
defineEmits(['update:title'])
function emitTitle(event) {
let value = event.target.value
if (props.welModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
emit('update:title', value)
}
<input type="text" :value="title" @input="emitTitle" />
DOM 更新时机
当你更改响应式状态后,DOM 会自动更新。然而,你得注意 DOM 的更新并不是同步的。相反,Vue 将缓冲它们直到更新周期的 “下个时机” 以确保无论你进行了多少次状态更改,每个组件都只更新一次。简单理解就是DOM更新只有一次,如果想要获取或者操作DOM更新后的状态,就需要使用nextTick。
若要等待一个状态改变后的 DOM 更新完成,你可以使用 nextTick() 这个全局 API:
import {
nextTick } from 'vue'
function increment() {
state.count++
nextTick(() => {
// 访问更新后的 DOM
})
}
vue3更新
setup
ref
ref 声明响应式状态,对string、number、boolen类型有效。
import {
ref } from 'vue'
let count = ref(0)
function increment() {
count.value++
}
reavtive
reactive 声明响应式状态,对对象类型有效(对象、数组和 Map、Set 这样的集合类型)
import {
reactive } from 'vue'
const state = reactive({
count: 0 })
function increment() {
state.count++
}
computed 计算属性
import {
computed } from 'vue'
const isShow = computed(() => {
return flag ? Yes : No
})
父组件给子组件传递数据
//父组件
import HelloWorld from './components/HelloWorld.vue'
<HelloWorld msg="Vite + Vue3" />
//子组件
defineProps({
//有返回值,如: const props = defineProps(['msg'])
msg: String
})
<template>
<h3>{
{
msg }}</h3>
</template>
子组件修改父组件状态(数据)
//父组件
import HelloWorld from './components/HelloWorld.vue'
import {
ref } from 'vue'
let msg = ref('Vite + Vue3')
function changeMsg() {
msg.value = 'Vite_Vue3_project'
}
<HelloWorld :msg=msg @change-msg="changeMsg" />
//子组件
defineEmits(['changeMsg']) // const emit = defineEmits(['changeMsg']) 有返回值
<button type="button" @click="$emit('changeMsg')">点击修改msg内容</button>
如果需要传参数和访问原生 DOM 事件:
//父组件
function changeMsg(val, event) {
msg.value = val
console.log