vue3.0
vite
和vue-cli一样,都是一个vue项目的脚手架,只不过更轻量
只在学习vue3.0使用,开发项目依然使用vue-cli
https://zhoushugang.gitee.io/erabbit-client-pc-document/
安装
npm init vite-app 项目名称
初始化
npm install
创建后,src下创建App.vue、main.js
main.js:
import {
createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
Mixin
实现组件复用、混入
<script>
import {demoMixin} from './mixins/demoMixin'
export default {
mixins:[demoMixin]
}
</script>
组合API
vue2.0使用选项api:
代码风格:data选项写数据,methods选项写函数…,一个功能逻辑的代码分散。
vue3.0使用组合API:
代码风格:一个功能逻辑的代码组织在一起,利于代码复用
注意:
- 以setup函数为起点,没有data、method等方法
- 在组件实例创建前执行,所以不能打印和使用this(这里官方解释其实有误,其实应该是创建实例后没有绑定this)
- 模板数据和函数,需要进行返回
setup
相当于以前的beforeCreated和created生命周期
< script>
export default {
name:'App',
setup () {
const msg = 'hhh'
return { msg }
}
}
</script>
最新写法:
< script setup>
const msg = 'hhh'
</script>
有两个参数
props
context
reactive
将对象转化为响应式数据
const obj = reactive({
name: 'ls',
age: 18
})
ref
将单个属性或变量变成响应式
import {
ref} from 'v'
setup(){
let counter = ref(100)
return {
counter}
}
toRef
转换响应式对象中某个属性为单独响应式数据
export default {
name: 'App',
setup () {
// 1. 响应式数据对象
const obj = reactive({
name: 'ls',
age: 10
})
// 2. 模板中只需要使用name数据
// 注意:从响应式数据对象中解构出的属性数据,不再是响应式数据
// let { name } = obj 不能直接解构,出来的是一个普通数据
const name = toRef(obj, 'name')
// console.log(name)
const updateName = () => {
// toRef转换响应式数据包装成对象,value存放值的位置
name.value = 'zs'
}
return {
name, updateName}
}
}
toRefs
转换响应式对象中所有属性为单独响应式数据,对象成为普通对象
export default {
name: 'App',
setup () {
// 1. 响应式数据对象
const obj = reactive({
name: 'ls',
age: 10
})
const obj3 = toRefs(obj)
const updateName = () => {
// obj3.name.value = 'zs'
obj.name = 'zs'
}
return {
...obj3, updateName}
}
}
computed
和原来的类似
通过计算属性能够将响应式数据进行计算并返回响应式数据
const fullName = computed({
get: () =>firstName.value+" "+lastName.value,
set(newValue) {
……
}
})
watchEffect
自动收集响应式依赖
ref引用结合
<template>
<div>
<h2 ref = "title">
</h2>
</div>
</template>
……
<script>
import {ref,watchEffect} from 'vue'
export default {
setup() {
const title = ref(null)
watchEffect(()=>{
console.log(titile.value)
},{
flush:"post"
})
return {title}
}
}
</script>
watch
和vue2watch函数相同
侦听多个数据源
const info = reactive({
name:"hah",age:18})
const name = ref("hah")
watch([() => ({
...info}),name],([newInfo,newName],[oldInfo,oldName])=>{
console.log(newInfo,newName,oldInfo,oldName)
})
深度侦听
watch(()=>({
...info}),(newInfo,oldInfo) => {
console.log()
},{
deep:true,
immediat
})
provide与inject
父子组件相互传值使用
父向子传值:
主组件使用子组件中的count
<script>
import { provide,ref,readonly} from 'vue'
import Home from './Home.vue'
export default {
components: {Home},
setup() {
let count = ref(100)
provide("count", readonly(count))
const increment = () => count.value++
return {count}
}
}
</script>
Home.vue
<script>
import { inject } from 'vue'
export default {
setup() {
const count = inject("count")
return {count}
}
}
</script>
生命周期钩子
setup
创建实例前onBeforeMount
挂载DOM前onMounted
挂载DOM后onBeforeUpdate
更新组件前onUpdated
更新组件后onBeforeUnmount
卸载销毁前onUnmounted
卸载销毁后
全部写在setup里
InstanceType
拿到构造函数实例的类型
const formRef = ref<InstanceType<type of Elfrom>>()
Hook技术
准确说也不叫技术,就是将公共类或者公共函数使用export封装在js文件中,文件夹为hooks
hooks文件夹下新建一个useScrollPosition
import {
ref } from 'vue';
export default function() {
const scrollX = ref(0);
const scrollY = ref(0);
document.addEventListener("scroll", () => {
scrollX.value = window.scrollX;
scrollY.value = window.scrollY;</