创建项目语句:npm init vue@latest
目录:没太大区别~,重要的我标注一下:
- src/assets:放置图片、logo
- src/index.css:全局样式文件
- src/App.vue:项目入口文件,可以直接将组件写这里,全局都可以用
- src/main.js:项目核心文件
- package.json:项目配置文件
setup(执行顺序在beforeCreate还早)
vue3中新的配置项,值为一个函数,vue2中不使用data,methods,全部采用setup函数,钩子函数啥的都放这里。
注意点:vue2和vue3不要混用,vue2的data等内容可以访问setup,但是在setup中不能访问到vue2的配置
setup的参数:
- setup的参数
- props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性
- context:上下文对象
- attrs:值为对象,包含组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs
- slots:收到的插槽内容
- emit:分发自定义时间的函数,相当于this.$emit
下面是学习的代码示例:
ref函数(变成响应式数据)
- 需要引入import {ref} from 'vue'
- 数据:let id= ref(32)
- 方法:id.value=1 需要.value一下,对象的话需要job.value.salary='30k'
reactive函数(响应式对象)处理对象是深层次的,同样也可以处理数组
- 同样需要引入import {reactive} from 'vue'
- let job = reactive({id:1,name:'你好'})
- 方法中就不用.value了
小总结:vue2中会有不是响应式的情况,需要用vue的方法$set来解决,而vue3只要写在reactive里面直接对数据增删改查,模板里都可以展示。
vue3中的计算属性怎么写?(computed)
import {computed} from 'vue' //同样需要引入
setup(){
//计算属性读和写
let fullName = computed({
get(){
return person.firstName + person.lastName //读
}
set(value){
person.fullName= value
}
})
}
watch函数
注意:
- 监视reactive定义的响应式数据时,oldValue无法正确获取,deep失效,因为是强制开启了深度监视
- 监视reactive定义的响应式数据中的某个属性时,deep配置有效
<script>
import {watch,ref,reactive} from 'vue'
export default {
setup() {
let sum = ref(0)
let msg = ref('hello啊!')
let person = reactive({
name:'刘洋',
age:'18'
})
// 情况1:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum变化了',newValue,oldValue)
},{immediate:true,deep:true})
// 情况2:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum变化了',newValue,oldValue)
},{immediate:true})
// 情况3:监视reactive定义的对象,其中deep一直是TRUE,无法获取到oldValue
watch([person],(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{immediate:true})
// 情况4:监视person中的某个属性
watch(()=>person.name,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{immediate:true})
// 情况5:监视person中的多个属性
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{immediate:true})
//特殊情况
watch(()=>person.name,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{deep:true}) //此处监视的是reactive定义的对象中的某个属性,所以deep配置有效
},
};
</script>
watchEffect函数
watchEffect有点像computed,但是computed注重的是计算出来的值,需要写返回值,但是watchEffect注重过程,中间可以写对监听到变更的数据进行业务逻辑的操作
<script>
import {watchEffect} from 'vue'
watchEffect(()=>{
const a = sum.value
console.log('watchEffect执行了')
})
</script>
生命周期的变化(更智能)
自定义hook函数
类似于vue2中的mixin,在hooks文件新建js方法,里面写函数,然后setup中直接调用
写法为:const point = useChange()
toRef
- 作用:创建一个ref对象,其value值只想另一个对象中的某个属性
- 语法:const name = toRef('person','name')
- 应用:要将响应式对象中的某个属性单独提供给外部使用时
- toRefs,可以批量创建多个ref对象
toRaw与markRaw
- toRaw
- 作用:讲一个由reactive生成的响应式对象转为普通对象
- markRaw
- 作用:标记一个对象,让他永远不再成为响应式对象
- 场景:复杂的第三方类库、渲染不可变数据源的大列表
- 写法:person.job = markRow(job)
customRef
*可以实现防抖效果
<template>
<input type="text" v-model="word" />
<h3>{{ word }}</h3>
</template>
<script>
import { ref, customRef } from "vue";
export default {
setup() {
function myRef(value) {
let timer;
return customRef((track, trigger) => {
return {
get() {
console.log(`有人从myRef这个容器中读取数据了,把${value}给他了`);
track(); //追踪
return value;
},
set(newValue) {
console.log(`有人把myRef容器中的数据改为了:${newValue}`);
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
trigger(); //通知vue去重新解析模板
}, 1000);
},
};
});
}
let word = myRef("hello");
return {
word,
};
},
};
</script>
provide与inject
- 作用:实现祖孙组件间的通信
- 使用:父组件有一个provide选项来提供数据,后代组件有一个inject选项来使用这些数据
- 写法
- 父组件
-
setup(){ let car = reavtive({name:'奔驰',价格:'50w'}) provide('car' , car) }
-
- 孙组件
-
setup(props,context){ const car = inject('car') return {car} }
-
- 父组件
vue3中新的内置组件
- teleport(不影响其他组件的样式)
- suspense(异步引入时候用)
-
import {defineAsyncComponent} from 'vue' const Child = defineAsyncComponent(()=>{import('./components/Child.vue')})
- 并使用 suspense包裹组件,配置v-solt:default和fallback,这俩写在suspense标签的下一层
-
vue3中对API做出的调整
Vue.xxx调整为app.