选项式API和组合式API
1、使用选项式 API,用包含多个选项的对象来描述组件的逻辑,例如 data、methods 和 mounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例。
2、组合式 API,我们可以使用导入的 API 函数来描述组件逻辑
创建 vue3 项目
node本版:node 16.x.x,
脚手架:create-vue 脚手架工具,底层vite
创建vue3项目:npm init vue@latest
vue3 单文件组件
1、vite.config.js配置文件基于vite的配置
2、template模板不再要求唯一根元素
3、script和template调整顺序(模板和样式在一起更容易维护)
vue3 根
1、以app作为参数生产一个应用实例对象
2、挂载到id为app的节点上
组合式API
setup函数
1、return 数据和方法
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
const message='我在学习vue3!'
return {
message
}
},
})
</script>
<template>
<div>{{message}}</div>
</template>
os
<script setup>
const message='我在学习vue3!'
</script>
<template>
<div>{{message}}</div>
</template>
2、setup选择在beforecreate函数之前 自动执行
3、<script setup>
语法糖(经过一系列的封装,将复杂的写法简单化),在线编译工具
4、this是undefined
组合式API- reactive函数作用:接受对象类型数据的参数传入并返回一个响应式的对象
<script setup>
// 1、导入函数
import { reactive} from 'vue'
// 2、执行函数 传入一个对象类型的参数 变量接收
const state = reactive({
count:0
})
const setCount = ()=>{
state.count++
}
</script>
<template>
<div>
<button @click="setCount">{{state.count}}</button>
</div>
</template>
组合式API-ref函数作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
<script setup>
// 1、导入函数
import { ref} from 'vue'
// 2、执行函数 作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象
const count = ref(0)
console.log(count)
const setCount2 = ()=>{
// 脚本区域修改ref产生的响应是对象数据 必须通过.value属性
count.value++
}
</script>
<template>
<div>
<button @click="setCount2">{{count}}</button>
</div>
</template>
使用$ref()语法糖
//具体使用
let msg = ref('hello')
console.log(msg.value) // hello
let msg = $ref('hello')
console.log(msg) // hello
使用方式
//安装
npm i @vue-macros/reactivity-transform
//vite.config.js中配置
import ReactivityTransform from '@vue-macros/reactivity-transform/vite';
export default defineConfig({
plugins: [vue({ refTransform: true }), ReactivityTransform()]
})
组合式API-computed计算属性函数
<script setup>
import {ref} from 'vue'
// 1、导入computed
import {computed} from 'vue'
const list = ref([1,2,3,4,5,6,7,8])
// 2、执行函数 return 计算之后的值 变量接收
const computedList = computed(()=>{
return list.value.filter(item=>item>2)
})
// setTimeout(() => {
// list.value.push(9,10)
// }, 3000);
</script>
<template>
<div>
原始响应式数据 - {{list}}
</div>
<div>
计算属性数组 - {{computedList}}
</div>
</template>
小结:
1、计算属性不应该有副作用:比如异步请求/修改dom
2、避免直接修改计算属性的值:计算属性应该是只读的
组合式API-watch计算属性函数
//监听单个属性
<script setup>
// 1、导入watch
import {ref,watch} from 'vue'
const count = ref(0)
const setCount = ()=>{
count.value++
}
// 2、调用watch
watch(count,(newValue,oldValue)=>{
console.log(newValue,oldValue)
},{
immediate:true
})
</script>
<template>
<div>
<button @click="setCount">{{count}}</button>
</div>
</template>
//监听多个属性
<script setup>
// 1、导入watch
import {ref,watch} from 'vue'
const count = ref(0)
const setCount = ()=>{
count.value++
}
const name=ref('pc')
const changeName=()=>{
name.value='cp'
}
// 2、调用watch
watch(
[count,name],
(
[newCount,newName],
[oldCount,oldName]
)=>{
console.log('count',newCount,oldCount)
console.log('name',newName,oldName)
})
</script>
<template>
<div>
<button @click="setCount">修改count--{{count}}</button>
</div>
<div>
<button @click="changeName">修改name--{{name}}</button>
</div>
</template>
//精确监听
<script setup>
import {ref,watch} from 'vue'
const info=ref({
name:'cp',
age:18
})
const changeName=()=>{
info.value.name='chunchunzhang'
}
watch(
()=>info.value.name,
()=>console.log('name改变了')
)
</script>
<template>
<div>{{info.name}}</div>
<button @click="changeName">button</button>
</template>
小结:
1、作为watch函数的第一个参数,ref对象需要添加.value吗
不需要,watch会自动读取
2、watch只能侦听单个数据吗
单个或者多个
3、不开启deep,直接修改嵌套的属性能触发监听回调吗
不能,默认是浅层侦听
4、不开启deep,想在某个层次比较深的属性变化时执行回调怎么做
可以把第一个参数写成函数的写法,返回要监听的具体属性
组合式API-生命周期函数
1、vue2 beforeDestroy 和 destroyed生命周期函数。在2、2、 vue3的生命周期中没有了销毁之前(beforeDestroy )以及销毁完毕(destroyed )这两个生命周期。
取而代之的是卸载,卸载之前(beforeUnmount )以及卸载完毕(unmounted )
基本使用规则:
1、引入函数
2、执行函数 传入回调
3、执行多次,按顺序依次执行
例子:其他用法类似
<script setup>
import { onMounted } from 'vue'
onMounted(()=>{
console.log('组件执行挂载完毕1')
})
onMounted(()=>{
console.log('组件执行挂载完毕2')
})
</script>
组合API-父子组件通信
a、父传子
1、父传子过程中通过什么方式接收props?
defineProps({属性名:类型})
2、setup语法糖中如果使用父组件传过来的数据?
const props=defineProps({属性名:类型})
子传父
1、子传父的过程中通过什么方式得到emit方法
defineEmits(['事件名称'])
组合API-模板引用
通过ref标识获取真实的dom对象或者组件
例子:
<script setup>
import { ref,onMounted } from "vue";
//子组件
import SonCom from './SonCom2.vue'
// 1、调用ref函数->ref对象
const h1Ref = ref(null)
const sonCom = ref(null)
onMounted(()=>{
console.log(h1Ref.value)
console.log(sonCom.value)
})
</script>
<template>
<!-- 2、通过ref标识来绑定ref对象 -->
<h1 ref="h1Ref">标签h1</h1>
<SonCom ref="sonCom"></SonCom>
</template>
小结:
1、获取模板引用的时机是什么?
组件挂载完毕
2、defineExpose编译宏的作用是什么?
显示暴露组件内部的属性和方法
vue3中父子组件双向绑定
直接使用v-model