基本数据类型
对象(或数组)类型数据
对象(或数组)类型数据
,它内部会自动通过reactive
转为代理对象
Object.defineProperty()
的get
和set
来实现响应式(数据劫持)proxy
来实现响应式(数据劫持),并通过Reflect
操作源对象内部的数据.value
,读取数据时模板中直接读取,不需要.value
.value
undefined
this.$attrs
this.$slots
this.$emit
代码示例
<template>
<demo msg="hello" word="花花" @testEmit="sayHello">
<template v-slot:testSlot>
<h2>花花</h2>
</template>
</demo>
</template>
<script>
import Demo from "@/components/Demo";
export default {
name: 'App',
components: {Demo},
setup(){
function sayHello(value) {
alert(`我是emit的响应,我收到了${value}`)
}
return{sayHello
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
<template>
<h1>我是setup测试</h1>
<h1>个人信息</h1>
<h2>{{ person.name }}</h2>
<h2>{{ person.age }}</h2>
<button @click="sayHello">sayHello</button>
<h2>职业:{{ person.job.jobs }}</h2>
<h2>薪水:{{ person.job.salary }}</h2>
<h2>爱好{{ person.hobby }}</h2>
</template>
<script>
import {reactive} from "vue";
export default {
name: "Demo",
props: {
msg:String,
word:String
},
emits:['testEmit'],
setup(props, context) {
console.log(`this是${this}`)
console.log(props)//这里是接收到的属性
console.log(context.attrs)//这里是未声明接收的属性
console.log(context.slots) //这里是插槽
let person = reactive({
name: "花花",
age: 18,
job: {
jobs: "前端开发工程师",
salary: '3k'
},
hobby: ['游戏', '篮球', '花花']
});
function sayHello() {
context.emit('testEmit','666')
}
return {
person, sayHello
}
}
}
</script>
<style scoped>
</style>
<template>
<h1>个人信息</h1>
<input v-model="person.firstName"/>
<br>
<input v-model="person.lastName"/>
<h2>全名{{fullName}}</h2>
<input v-model="fullName"/>
</template>
<script>
import {reactive} from "vue";
export default {
name: "Demo",
//这里是vue2的计算属性
computed:{
fullName:{
get(){
return this.person.firstName + '_' + this.person.lastName
},
set(value){
const fullNameArr = value.split('_');
this.person.firstName = fullNameArr[0];
this.person.lastName = fullNameArr[1];
}
}
},
setup(props, context) {
console.log(`this是${this}`)
// console.log(props, context)
console.log(props)//这里是接收到的属性
console.log(context.attrs)//这里是未声明接收的属性
console.log(context.slots) //这里是插槽
let person = reactive({
firstName: "爱",
lastName:'花花',
age: 18
});
return {
person
}
}
}
</script>
<style scoped>
</style>
<template>
<h1>个人信息</h1>
<input v-model="person.firstName"/>
<br>
<input v-model="person.lastName"/>
<h2>全名{{ person.fullName }}</h2>
<input v-model="person.fullName"/>
</template>
<script>
import {computed, reactive} from "vue";
export default {
name: "Demo",
setup(props, context) {
console.log(`this是${this}`)
// console.log(props, context)
console.log(props)//这里是接收到的属性
console.log(context.attrs)//这里是未声明接收的属性
console.log(context.slots) //这里是插槽
let person = reactive({
firstName: "爱",
lastName: '花花',
age: 18
});
//简写
person.fullName = computed(()=>{
return person.firstName + '_' + person.lastName
})
//完整写法
person.fullName = computed({
get(){
return person.firstName + '_' + person.lastName
},
set(value){
const fullNameArr = value.split('_')
person.firstName = fullNameArr[0]
person.lastName = fullNameArr[1]
}
})
return {
person
}
}
}
</script>
<style scoped>
</style>
<template>
<h1>求和结果是{{ sum }}</h1>
<button @click="sum++">计算+1</button>
</template>
<script>
import {ref} from "vue";
export default {
name: "Demo",
watch: {
//两种写法 1,完全写法
sum: {
immediate: true,
handler(newValue, oldValue) {
console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
}
}
//写法二 简略写法
/* sum(newValue, oldValue){
console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
}*/
},
setup() {
let sum = ref(0);
return {
sum
}
}
}
</script>
<style scoped>
</style>
<template>
<h1>求和结果是{{ sum }}</h1>
<button @click="sum++">计算+1</button>
<br>
<h3>msg为{{msg}}</h3>
<button @click="msg+='!'">修改msg</button>
</template>
<script>
import {ref, watch} from "vue";
export default {
name: "Demo",
setup() {
let sum = ref(0);
let msg = ref("我是msg");
/*写法一 监听ref定义的单个数据*/
// watch(sum, (newValue, oldValue) => {
// console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
// }, {
// immediate:true
// })
/*写法二 监听ref定影的多个数据,newValue和oldValue是数组*/
watch([sum,msg], (newValue, oldValue) => {
console.log(newValue)
console.log("sum/msg修改了,之前是",newValue,"修改后是",oldValue)
}, {
immediate:true
})
return {
sum,msg
}
}
}
</script>
<style scoped>
</style>
watch的总结
<template>
<h1>求和结果是{{ sum }}</h1>
<button @click="sum++">计算+1</button>
<br>
<h3>msg为{{ msg }}</h3>
<button @click="msg+='!'">修改msg</button>
<br>
<h2>姓名:{{ person.name }}</h2>
<h2>年龄:{{ person.age }}</h2>
<h2>薪资:{{ person.job.j1.salary }}</h2>
<button @click="person.age++">增加年龄</button>
<button @click="person.name+='~'">增加姓名</button>
<button @click="person.job.j1.salary++">涨薪</button>
<button @click="person.job.j1.aaa[0] = 10 ">测试监听reactive中的数组</button>
</template>
<script>
import {reactive, ref, watch} from "vue";
export default {
name: "Demo",
setup() {
let sum = ref(0);
let msg = ref("我是msg");
let person = reactive({
name: '花花',
age: 20,
job: {
j1: {
salary: 20,
aaa:[1,2,3,4]
}
}
})
/*情况一 监听单个数据*/
// watch(sum, (newValue, oldValue) => {
// console.log(`sum修改了,之前是${newValue},修改后是${oldValue}`)
// }, {
// immediate:true
// })
/*情况二 监听多个数据,newValue和oldValue是数组*/
/* watch([sum,msg], (newValue, oldValue) => {
console.log(newValue)
console.log("sum/msg修改了,之前是",newValue,"修改后是",oldValue)
}, {
immediate:true
})*/
/*
* 情况三 检测reactive数据
* 问题:
* 1.无法获取到oldValue
* 2.强制开启了deep:true,并且不能关闭
* */
/* watch(person, (newValue, oldValue) => {
console.log("person修改了,之前是",newValue,"修改后是",oldValue)
}, {
immediate:true
})*/
/*情况四 想要监听reactive中的,某一个属性*/
/* watch(()=>person.age, (newValue, oldValue) => {
console.log("person修改了,之前是",newValue,"修改后是",oldValue)
}, {
immediate:true
})*/
/*情况5 想要监听reactive中的,某一个对象属性,需要开启deep*/
watch(() => person.job, (newValue, oldValue) => {
console.log("person修改了,之前是", newValue, "修改后是", oldValue)
}, {
immediate: true,
deep: true
})
return {
sum, msg, person
}
}
}
</script>
<style scoped>
</style>