Vue3.0
# Vue3.0基础
# vite基本使用
- 是一个更加轻量的
vue
项目脚手架工具
基本使用
- 创建
yarn create vite-app 项目名称
- 安装依赖
yarn
- 启动项目
yarn dev
# vue3.0基本使用
# main.js
创建vue实例
//1.导入 createApp 函数从vue中
import {createApp} from 'vue'
//2.创建一个根组件 App.vue 导入main
import App from './App.vue'
//3.使用 createApp 创建应用实例
const app = createApp(App)
//4.应用实例挂载到 #app 容器中
app.mount('#app')
2
3
4
5
6
7
8
# 组合API
代码风格: 一个功能逻辑的代码组织在一起
- 优点:功能逻辑复杂繁多情况下,各个功能逻辑代码组织再一起,便于阅读和维护
- 缺点:需要有良好的代码组织能力和拆分逻辑能力
# setup()
- 组合API 的起点,将来的 组合API 的代码,基本在这里
- 可以理解为:
beforeCreate
钩子执行,组件实例创建前 - 函数中不能使用
this
- 模板中需要使用的数据和函数,需要在
setup
中返回
# 生命周期
setup
创建实例前onBeforeMount
挂载 DOM 前onMounted
挂载DOM 后onBeforeUpdata
更新组件前onUpdated
更新组件后onBeforeUnmount
卸载销毁前onUnmounted
卸载销毁后
# reactive()
创建响应式数据
reactive
是一个函数,可以定义一个复杂数据类型,称为响应式数据因为 vue 的热更新只针对引用数据类型的如数组,而这个函数可以创建出响应式数据
通常是用来定义响应式对象数据
<template>
<div class="container">
<div>{{obj.name}}</div>
<div>{{obj.age}}</div>
<button @click="updateName">修改数据</button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
name: 'App',
setup () {
// 普通数据
// const obj = {
// name: 'ls',
// age: 18
// }
const obj = reactive({
name: 'ls',
age: 18
})
// 修改名字
const updateName = () => {
console.log('updateName')
obj.name = 'zs'
}
return { obj ,updateName}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# toRef()
- toRef是函数,转换响应式对象中某个属性为单独响应式数据,并且值是关联的。
<template>
<div class="container">
{{name}} <button @click="updateName">修改数据</button>
</div>
</template>
<script>
import { reactive, toRef } from 'vue'
export default {
name: 'App',
setup () {
// 1. 响应式数据对象
const obj = reactive({
name: 'ls',
age: 10
})
console.log(obj)
// 2. 模板中只需要使用name数据
// 注意:从响应式数据对象中解构出的属性数据,不再是响应式数据
// let { name } = obj 不能直接解构,出来的是一个普通数据
const name = toRef(obj, 'name')
// console.log(name)
const updateName = () => {
console.log('updateName')
// toRef转换响应式数据包装成对象,value存放值的位置
name.value = 'zs'
}
return {name, updateName}
}
}
</script>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
toRef
转换的响应式数据包装成对象,其值在 value
属性中
# toRefs()
- toRefs是函数,转换响应式对象中所有属性为单独响应式数据,对象成为普通对象,并且值是关联的
<template>
<div class="container">
<div>{{name}}</div>
<div>{{age}}</div>
<button @click="updateName">修改数据</button>
</div>
</template>
<script>
import { reactive, toRef, toRefs } from 'vue'
export default {
name: 'App',
setup () {
// 1. 响应式数据对象
const obj = reactive({
name: 'ls',
age: 10
})
console.log(obj)
// 2. 解构或者展开响应式数据对象
// const {name,age} = obj
// console.log(name,age)
// const obj2 = {...obj}
// console.log(obj2)
// 以上方式导致数据就不是响应式数据了
const obj3 = toRefs(obj)
console.log(obj3)
const updateName = () => {
// obj3.name.value = 'zs'
obj.name = 'zs'
}
return {...obj3, updateName}
}
}
</script>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# ref()
toRef
和 toRefs
是辅助 reactive
函数的创建响应式数据类型的使用
此类创建的响应式数据类型 在修改其值时需要 .value
属性改变
在模板中使用
ref()
声明的响应式数据const name = ref('10')
可以定义简单数据类型的响应式数据
也可以定义复杂数据类型的响应式数据
ref函数,常用于简单数据类型定义为响应式数据
- 再修改值,获取值的时候,需要.value
- 在模板中使用ref申明的响应式数据,可以省略.value
<template>
<div class="container">
<div>{{name}}</div>
<div>{{age}}</div>
<button @click="updateName">修改数据</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: 'App',
setup () {
// 1. name数据
const name = ref('ls')
console.log(name)
const updateName = () => {
name.value = 'zs'
}
// 2. age数据
const age = ref(10)
// ref常用定义简单数据类型的响应式数据
// 其实也可以定义复杂数据类型的响应式数据
// 对于数据未之的情况下 ref 是最适用的
// const data = ref(null)
// setTimeout(()=>{
// data.value = res.data
// },1000)
return {name, age, updateName}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 组合API
# computed()
- 计算属性:当你需要依赖现有的响应式数据,根据响应式数据得到新数据
基本使用
<template>
<div class="container">
<div>今年:{{age}}岁</div>
<div>后年:{{newAge}}岁</div>
</div>
</template>
<script>
import { computed, ref } from 'vue'
export default {
name: 'App',
setup () {
// 1. 计算属性:当你需要依赖现有的响应式数据,根据一定逻辑得到一个新的数据。
const age = ref(16)
// 得到后年的年龄
const newAge = computed(()=>{
// 该函数的返回值就是计算属性的值
return age.value + 2
})
return {age, newAge}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
高级使用
<template>
<div class="container">
<div>今年:{{age}}岁</div>
<div>后年:{{newAge}}岁</div>
<!-- 使用v-model绑定计算属性 -->
<input type="text" v-model="newAge">
</div>
</template>
<script>
import { computed, ref } from 'vue'
export default {
name: 'App',
setup () {
// 1. 计算属性:当你需要依赖现有的响应式数据,根据一定逻辑得到一个新的数据。
const age = ref(16)
// 得到后年的年龄
// const newAge = computed(()=>{
// // 该函数的返回值就是计算属性的值
// return age.value + 2
// })
// 计算属性高级用法,传人对象
const newAge = computed({
// get函数,获取计算属性的值
get(){
return age.value + 2
},
// set函数,当你给计算属性设置值的时候触发
set (value) {//监听计算属性值的改变
age.value = value - 2
}
})
return {age, newAge}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
目的: 计算属性支持双向数据绑定
# watch()
- 需要监听数据的变化
示例:
监听 ref
数据,一个参数为需要监听的数据,第二个参数为事件处理函数
watch(count,(newVal,oldVal)=>{})
监听多个数据的变化
watch([count,age],()=>{})
监听对象中某一属性的变化
watch(()=>return obj.name,()=>{})
深度监听
watch(()=>{},()=>{},{deep:true,immedite:true})
对数据的深度监听,以及在数据监听时立即执行
此类监听是在某数据对象里面的属性对象进行监听可能会监听不到的情况
watch(obj.obj,()=>{})
# ref属性
获取 DOM
vue2的方法
<template>
<div ref="box">
</div>
</template>
<script>
this.$refs.box //获取单个dom
this.$refs.li //获取多个dom
</script>
2
3
4
5
6
7
8
9
vue3
//通过数据来绑定 dom
<template>
<div ref = "dom">获取单个dom</div>
<ul>
<li v-for="i in 4" :ref="setDom"></li>
</>
</template>
<script>
export default{
name:'',
setup(){
const dom = ref(null)
const domList = []
const setDom = (el)=>{
domList.push(el)
}
return {dom,setDom}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 组件通信
# 父传子通信
可以使用 vue2
中组件通信的方式
<template>
<div class="container">
<h1>父组件</h1>
<p>{{money}}</p>
<hr>
<Son :money="money" />
</div>
</template>
<script>
import { ref } from 'vue'
import Son from './Son.vue'
export default {
name: 'App',
components: {
Son
},
// 父组件的数据传递给子组件
setup () {
const money = ref(100)
return { money }
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div class="container">
<h1>子组件</h1>
<p>{{money}}</p>
</div>
</template>
<script>
import { onMounted } from 'vue'
export default {
name: 'Son',
// 子组件接收父组件数据使用props即可
props: {
money: {
type: Number,
default: 0
}
},
setup (props) {
// 获取父组件数据money
console.log(props.money)
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 子传父通信
emit()
: 触发父组件自定义事件
<template>
<div class="container">
<h1>父组件</h1>
<p>{{money}}</p>
<hr>
+ <Son :money="money" @change-money="updateMoney" />
</div>
</template>
<script>
import { ref } from 'vue'
import Son from './Son.vue'
export default {
name: 'App',
components: {
Son
},
// 父组件的数据传递给子组件
setup () {
const money = ref(100)
+ const updateMoney = (newMoney) => {
+ money.value = newMoney
+ }
+ return { money , updateMoney}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<div class="container">
<h1>子组件</h1>
<p>{{money}}</p>
+ <button @click="changeMoney">花50元</button>
</div>
</template>
<script>
import { onMounted } from 'vue'
export default {
name: 'Son',
// 子组件接收父组件数据使用props即可
props: {
money: {
type: Number,
default: 0
}
},
// props 父组件数据
// emit 触发自定义事件的函数
+ setup (props, {emit}) {
// 获取父组件数据money
console.log(props.money)
// 向父组件传值
+ const changeMoney = () => {
// 消费50元
// 通知父组件,money需要变成50
+ emit('change-money', 50)
+ }
+ return {changeMoney}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 扩展
在 vue2
中 .sync
属性可以实现同 v-model
的双向数据绑定
<Son :key= "key" @update:key = "fn"></Son>
简写
<Son :key.sync = "key" ></Son>
vue3
<Son :key="key" @update:key = "updataKey"/>
简写
<Son v-model:key = "key"/>
在子组件中
emit('updata:key',50)
# 依赖注入
provide
和 inject
<template>
<div class="container">
<h1>父组件 {{money}} <button @click="money=1000">发钱</button></h1>
<hr>
<Son />
</div>
</template>
<script>
import { provide, ref } from 'vue'
import Son from './Son.vue'
export default {
name: 'App',
components: {
Son
},
setup () {
const money = ref(100)
const changeMoney = (saleMoney) => {
console.log('changeMoney',saleMoney)
money.value = money.value - saleMoney
}
// 将数据提供给后代组件 provide
provide('money', money)
// 将函数提供给后代组件 provide
provide('changeMoney', changeMoney)
return { money }
}
}
</script>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
子组件
<template>
<div class="container">
<h2>子组件 {{money}}</h2>
<hr>
<GrandSon />
</div>
</template>
<script>
import { inject } from 'vue'
import GrandSon from './GrandSon.vue'
export default {
name: 'Son',
components: {
GrandSon
},
setup () {
// 接收祖先组件提供的数据
const money = inject('money')
return { money }
}
}
</script>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
孙组件
<template>
<div class="container">
<h3>孙组件 {{money}} <button @click="fn">消费20</button></h3>
</div>
</template>
<script>
import { inject } from 'vue'
export default {
name: 'GrandSon',
setup () {
const money = inject('money')
// 孙组件,消费50,通知父组件App.vue组件,进行修改
// 不能自己修改数据,遵循单选数据流原则,大白话:数据谁定义谁修改
const changeMoney = inject('changeMoney')
const fn = () => {
changeMoney(20)
}
return {money, fn}
}
}
</script>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
使用依赖注入之间的组件通信
provide()
函数除了可以传递数据外还可以传递函数
在子组件需要修改父组件的数据是可以使用 依赖注入 得到的函数通过父组件修改
# mixins语法
混入(mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能,一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入进入该组件本身的选项
全局混入
app.mixin({
mounted(){
console.log('该组件')
}
})
2
3
4
5
局部混入
可以使用独立模块文件
// 配置对象
export const followMixin = {
data () {
return {
loading: false
}
},
methods: {
followFn () {
this.loading = true
// 模拟请求
setTimeout(()=>{
// 省略请求代码
this.loading = false
},2000)
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div class="container1">
<h1> 作者:周杰伦 <a href="javascript:;" @click="followFn">{{loading?'请求中...':'关注'}}</a> </h1>
<hr>
<Son />
</div>
</template>
<script>
import Son from './Son.vue'
import {followMixin} from './mixins'
export default {
name: 'App',
components: {
Son
},
mixins: [followMixin]
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div class="container2">
<h2> 作者:周杰伦 <button @click="followFn">{{loading?'loading...':'关注'}}</button> </h2>
</div>
</template>
<script>
import {followMixin} from './mixins'
export default {
name: 'Son',
mixins: [followMixin]
}
</script>
<style scoped lang="less"></style>
2
3
4
5
6
7
8
9
10
11
12
13
# v-model补充
在 vue2 中 v-model
其实是以下代码的简写
<div :value = "msg" @input="msg=$event"/>
在 vue3 中
<div :modelValue="msg" @updata:modelValue="msg=$event"