Vue3快速入门
文章目录
1、使用create-vue创建项目
-
前提环境条件
已安装18.0或更高版本的Node.js:node -v
-
创建一个Vue应用
npm init vue@latest
这一指令将会安装并执行create-vue:
依次执行命令:
cd vue-project npm install npm run dev
访问页面:
2、组合式API-常见函数
2.1、组合式API入口-setup
数据和函数,需要在 setup最后return,才能模板中应用
2.2、reactive()
作用:接受对象类型数据的参数传入并返回一个响应式的对象
-
从 vue 包中导入 reactive函数
-
在
<script setup>
中执行 reactive 函数并传入类型为对象的初始值,并使用变量接收返回值<script setup> import { reactive } from 'vue' const state = reactive({ count: 0 }) const setConunt = () => { state.count++ } </script> <template> <div> <button @click="setConunt">{{ state.count }}</button> </div> </template>
2.3、ref()
作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
-
从 vue 包中导入 ref 函数
-
在
<script setup>
中执行 ref 函数并传入初始值,使用变量接收ref 函数的返回值<script setup> import { ref } from 'vue' const count = ref(0) const setConunt = () => { count.value++ } </script> <template> <div> <button @click="setConunt">{{ count }}</button> </div> </template>
ref函数的内部实现依赖于reactive函数。
2.4、computed计算属性函数
计算属性基本思想和Vue2的完全一致,组合式API下的计算属性只是修改了写法
-
导入computed函数
-
执行函数 在回调参数中return基于响应式数据做计算的值,用变量接收
<script setup> import { ref } from 'vue' import { computed } from 'vue' const list = ref([0, 1, 2, 3, 4, 5, 6, 7, 9]) const computedList = computed(() => { return list.value.filter(item => item > 3) }) </script> <template> <div> 原始响应数组-{{ list }} </div> <div> 计算之后响应数组-{{ computedList }} </div> </template>
2.5、watch
作用: 侦听一个或者多个数据的变化,数据变化时执行回调函数
两个额外参数:1. immediate(立即执行) 2. deep(深度侦听)
侦听单个数据
- 导入watch函数
- 执行watch函数传入要侦听的响应式数据(ref对象)和回调函数
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const setCount = () => {
count.value++
}
watch(count, (newValue, oldValue) => {
console.log(`变化前的值:${oldValue},变化后的值:${newValue}`);
})
</script>
<template>
<div>
<button @click="setCount">{{ count }}</button>
</div>
</template>
侦听多个数据
同时侦听多个响应式数据的变化,不管哪个数据变化都需要执行回调
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const setCount = () => {
count.value++
}
const name = ref('张三')
const setName = () => {
if (name.value === '张三')
name.value = '李四'
else
name.value = '张三'
}
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log(`变化前的值:${oldCount}, ${oldName},变化后的值:${newCount}, ${newName}`);
})
</script>
<template>
<div>
<button @click="setCount">{{ count }}</button>
</div>
<div>
<button @click="setName">{{ name }}</button>
</div>
</template>
immediate
说明:在侦听器创建时立即触发回调, 响应式数据变化之后继续执行回调
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const setCount = () => {
count.value++
}
watch([count], ([newCount,], [oldCount,]) => {
console.log(`变化前的值:${oldCount},变化后的值:${newCount}`);
}, {
immediate: true, // 是否在监听开始后立即调用
})
</script>
<template>
<div>
<button @click="setCount">{{ count }}</button>
</div>
</template>
有点类似于do…while语法
deep
默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项
<script setup>
import { ref, watch } from 'vue'
const state = ref({ count: 0 })
const setCount = () => {
state.value.count++
}
//浅层监听
// watch(state, () => {
// console.log(count变化了);
// })
//深层监听
watch(state, () => {
console.log('count变化了');
}, {
deep: true
})
</script>
<template>
<div>
<button @click="setCount">{{ state.count } }</button>
</div>
</template>
但是对象具有多个属性的时候,假如我想监听state里面的两个属性count和age中的age,这时候就要使用下面的精确侦听对象的某个属性。
注意:deep属性是采用递归的方法实现的,所以会有性能的损耗,所以绝大多数情况下是不推荐使用deep方法的开启。
精确侦听对象的某个属性
需求:在不开启deep的前提下,侦听age的变化,只有age变化时才执行回调
<script setup>
import { ref, watch } from 'vue'
const state = ref({ name: 'zhangsan', age: 18 })
const setAge = () => {
//修改age
state.value.age++
}
const setName = () => {
//修改age
state.value.name += '~'
}
//监听单个属性
watch(
() => state.value.name,
() => {
console.log('name变化了');
}
)
</script>
<template>
<div>
<span>name:{{ state.name }}</span>
<br>
<span>age:{{ state.age }}</span>
<br>
<button @click="setName">修改name</button>
<button @click="setAge">修改age</button>
</div>
</template>
3、组合式API-生命周期
(选项式 VS 组合式)
选项式API | 组合式API |
---|---|
beforeCreate/created | setup |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
生命周期函数基本使用
- 导入生命周期函数
- 执行生命周期函数 传入回调
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
console.log("组件挂载完毕,onMounted被调用");
})
</script>
多次执行
生命周期函数是可以执行多次的,多次执行时传入的回调会在时机成熟时依次执行
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
console.log("组件挂载完毕,onMounted1");
})
onMounted(() => {
console.log("组件挂载完毕,onMounted2");
})
</script>
<template>
<div>
</div>
</template>
结果:
4、组合式API-父子通信
4.1、子传父
- 父组件中给子组件标签通过@绑定事件
- 子组件内部通过 emit 方法触发事件
运行:
4.2、父传子
- 父组件中给子组件绑定属性
- 子组件内部通过props选项接收
静态数据:
响应式数据:
扩展:defineProps:编译器宏函数,这是一个标识,当编译器编译之后就会变成右边这个熟悉的vue2语法的代码,如下图。
5、组合式API-模版引用
通过ref标识获取真实的dom对象或者组件实例对象
<script setup>
import sonVue from './components/sonVue.vue'
import { ref, onMounted } from 'vue';
const domRef = ref(null)
const comRef = ref(null)
onMounted(() => {
console.log(domRef.value)
console.log(comRef.value)
})
</script>
<template>
<div>
<h2>父组件</h2>
<!-- 绑定事件 -->
<h1 ref="domRef"></h1>
<sonVue ref="comRef"></sonVue>
</div>
</template>
会发现一个问题:子组件里面的元素是不公开的:
这里就要讲到defineExpose函数了。
5.1、defineExpose()
默认情况下在语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性和方法允许访问。
在子组件中编写:
<script setup>
import { ref } from 'vue'
const name = ref('111')
const age = ref('111')
defineExpose({ name, age })
</script>
<template>
<div>
test组件
</div>
</template>
修改后:
6、组合式API-provide和inject
顶层组件向任意的底层组件传递数据和方法,实现跨层组件通信
6.1、跨层传递普通数据
-
顶层组件通过provide函数提供数据
-
底层组件通过inject函数获取数据
注:响应式的数据也是如此,直接替换即可,不再赘述。
6.2、跨层传递方法
顶层组件可以向底层组件传递方法,底层组件调用方法修改顶层组件中的数据