vue3笔记1 组件配置API
创建实例
入口文件
./src/main.js
// 引入工厂函数,而非Vue构造函数
import {createApp} from 'vue'
import App from './App.vue'
// 创建应用实例对象,比Vue实例轻
const app = createApp(App)
// 挂载
app.mount('#app')
setup组件选项
vue2中的数据,计算属性,方法,生命周期钩子等都可以在setup函数中构造
setup函数返回:
- 对象,包含模板中可以使用的属性,方法
<template>
<!-- 可以支持多个根标签 -->
<h1>{{ msg }}</h1>
<button @click="onClick">click</button>
</template>
<script>
export default {
name: 'HelloWorld',
setup() {
// 非响应式变量
let msg = props.props1 || 'hello world';
function onClick() {
alert(msg)
}
return {
msg,
onClick
}
}
}
</script>
注,默认setup返回对象中的变量是非响应式变量,使用ref/reactive创建响应式变量
2. 渲染函数
./component/HelloWorld.vue
<script>
// 引入渲染函数
import {h} from 'vue'
export default {
setup(){
return ()=> { return h('h1','hello') }
}
}
</script>
- data,methods,computed可以访问setup中的属性方法
- setup无法访问data,methods,computed
- 存在重名成员时,setup优先
setup执行时机
beforeCreate之前执行,this为undefined
setup参数
props: ['prop1'],
// vue3需要暴露可用事件,否则会报警告
emits: ['my-event'],
setup(props, context) {
// 取props属性
props.prop1
// 取props没定义的传入属性,传入props没有定义的属性会报警告,相当于vue2中的this.$attrs
context.attrs.prop2
// 触发事件,相当于vue2中的this.$emit
context.emit('my-event',{data:1})
// 取所有传入slots,相当于vue2中的this.$slots
context.slots
}
ref响应式变量
<template>
<!-- 插值不用写.value -->
<h2>{{ counter }}</h2>
<button @click="increase">increase</button>
</template>
<script>
import {ref} from "vue";
export default {
name: 'HelloWorld',
setup() {
// 响应式变量,创建引用对象RefImpl
let counter = ref(0)
function increase() {
// 操作引用对象值
counter.value++
}
return {
counter,
increase
}
}
}
</script>
reactive响应式对象
注,基本数据类型不要使用reactive
import {ref,reactive} from "vue";
...
setup() {
...
// 创建代理对象Proxy
const person = reactive({name:'psr',age:18}),
person1 = reactive({name:'zdd',age:18}
// 可以直接添加删除响应式属性,区别于vue2中的vc.$set vc.$delete方法
person.sex='男'
// 创建响应式数组
const persons = reactive([]);
persons.push(person)
// 索引修改也能支持响应式
persons[0]=person1
...
}
ref vs reactive
- ref一般用于定义基本类型数据(通过defineProperty实现响应式)
- reactive一般用于定义对象或数组类型数据(通过Proxy,Reflect实现响应式)
- 使用ref定义对象或数组类型数据,value会自动使用reactive转为代理对象
- 脚本操作ref数据需要.value
computed计算属性
import {reactive, computed} from "vue"
...
setup() {
...
let person = reactive({
name: 'psr',
firstName: 'zhou',
lastName: 'dd',
// 简写
fullName: computed(() => {
return person.firstName + ' - ' + person.lastName
}),
age: '18'
})
// 完整
let fullName = computed({
get() {
return person.firstName + ' - ' + person.lastName
},
set(value) {
const nameArr = value.split(' - ')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
...
return {
...
person,
fullName,
...
}
}
watch数据监视
import {watch} from 'vue'
- 监视ref
注,如果ref包装的是对象,需要监视.value属性(实际监视了value中的reactive代理对象)或者开启deep:true
watch(msg, (newValue, oldValue) => {
console.log(`msg changed: ${newValue} < ${oldValue}`)
}, { // 传递配置
immediate: true
})
- 监视多个ref
watch([msg1, msg2], (newValue, oldValue) => {
// 不管哪个发生变化都会触发
console.log(`something changed, msg1: ${newValue[0]} < ${oldValue[0]}`)
console.log(`something changed, msg2: ${newValue[1]} < ${oldValue[1]}`)
})
- 监视reactive,
注1,此处无法正确获得oldValue
注2,强制开启深度监视,deep:false配置无效
```js
watch(person, (newValue, oldValue) => {
console.log(newValue, oldValue)
})
- 监视reactive中某个属性
注,需要用函数指定属性
watch(() => person.age, (newValue, oldValue) => {
console.log(`age changed: ${newValue} < ${oldValue}`)
})
- 监视reactive中多个属性
watch([() => person.firstName, () => person.lastName], (newValue, oldValue) => {
console.log(`something changed, firstName: ${newValue[0]} < ${oldValue[0]}`)
console.log(`something changed, lastName: ${newValue[1]} < ${oldValue[1]}`)
})
- 监视reactive中的js对象属性
注,需开启deep:true,否则无法监视到深层变更(例如person.job.salary变更)
watch(() => person.job, (newValue, oldValue) => {
console.log(newValue, oldValue)
}, {deep: true})
watchEffect 智能监视
监视函数中依赖的属性发生变更时触发
// person.age或person.job.salary变化时就会调用此函数
watchEffect(()=>{
console.log("年龄:"+person.age)
console.log("薪资:"+person.job.salary)
})
浙公网安备 33010602011771号