reactive用法
- 传入一个对象类型的参数
<script setup>
//导入函数
import { reactive } from 'vue';
const state = reactive({
count: 0
})
const addCount = () => {
state.count++
}
</script>
<template>
<div>{{ state.count }}</div>
<button @click="addCount"></button>
</template>
ref用法
- 传入简单类型或者对象类型的数据
- 实现依赖于reactive
<script setup>
import { ref } from 'vue';
//此处若是对象则需要 对象.value.属性
const count = ref(0)
const addCount = () => {
//修改需要通过 .value属性
count.value++
}
</script>
<template>
<div>{{ count }}</div>
<button @click="addCount">+1</button>
</template>
<style></style>
计算属性
<script setup>
import { computed } from 'vue';
import { ref } from 'vue';
const list = ref([1, 2, 3, 4, 5, 6, 7, 8])
const computedList = computed(() => {
return list.value.filter(item => item > 2)
})
</script>
<template>
<div>原始数组:{{ list }}</div>
<div>修改后数组:{{ computedList }}</div>
</template>
<style></style>
效果:
原始数组:[ 1, 2, 3, 4, 5, 6, 7, 8 ]
修改后数组:[ 3, 4, 5, 6, 7, 8 ]
wach
侦听单个数据
<script setup>
import { ref, watch } from 'vue';
const count = ref(0)
const setCount = () => {
count.value++
}
watch(count, (newValue, oldValue) => {
console.log(newValue, "变化了", oldValue)
})
</script>
<template>
<div>{{ count }}</div>
<button @click="setCount">+1</button>
</template>
侦听多个数据
<script setup>
import { ref, watch } from 'vue';
const count = ref(0)
const setCount = () => {
count.value++
}
const name = ref("zhangsan")
const setName = () => {
name.value = '李四'
}
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log(newCount, "原来是:", oldCount)
console.log(newName, "原来是:", oldName)
})
</script>
<template>
<div>{{ count }}</div>
<div>{{ name }}</div>
<button @click="setCount">+1</button>
<button @click="setName">改变名字</button>
</template>
immediate
<script setup>
import { ref, watch } from 'vue';
const count = ref(0)
const setCount = () => {
count.value++
}
watch(count, (newValue, oldValue) => {
console.log(newValue, "变化了", oldValue)
}, {
immediate: true
})
</script>
<template>
<div>{{ count }}</div>
<button @click="setCount">+1</button>
</template>
deep
默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项
<script setup>
import { ref, watch } from 'vue';
const state = ref({ name: '张三', age: 20 })
const changName = () => {
state.value.name = 'chaichai-teacher'
}
const changAge = () => {
state.value.age++
}
watch(state, () => {
console.log("state改变了")
}, {
//默认机制:通过watch监听的ref对象默认是浅层侦听的,直接修改嵌套的对象属性不会触发回调执行,需要开启deep选项
deep: true
})
// watch(
// () => state.value.age,
// () => {
// console.log("age改变了")
// }
// )
//deep有性能损耗,精确监听更好
//深度监听
</script>
<template>
<div>
<p>{{ state.name }}</p>
<p>{{ state.age }}</p>
<div>
<p> <button @click="changName">changName</button></p>
<p><button @click="changAge">changAge</button></p>
</div>
</div>
</template>
组件传值
父组件给子组件传值
- 父组件
<script setup>
import { ref } from 'vue';
import SunCom from "@/components/son-com.vue"
const count = ref(100)
setTimeout(function () {
count.value = 200
}, 3000)
</script>
<template>
<div class="father">
<h2>父组件App</h2>
<SunCom message="father message" :count="count"></SunCom>
</div>
</template>
- 子组件
<script setup>
defineProps({
message: String,
count: Number
})
</script>
<template>
<div class="son">
{{ count }}
<h3>子组件Sons</h3>
{{ message }}
</div>
</template>
<style scoped></style>
子组件给父组件传值
- 父组件
<script setup>
import { ref } from 'vue';
import SunCom from "@/components/son-com.vue"
const getMessage = (msg) => {
console.log(msg)
}
</script>
<template>
<div class="father">
<h2>父组件App</h2>
<SunCom @getMessage="getMessage"></SunCom>
</div>
</template>
- 子组件
<script setup>
const emit = defineEmits(["getMessage"])
const sendMsg = () => {
emit("getMessage", "this is son message")
}
</script>
<template>
<div class="son">
<h3>子组件Sons</h3>
<button @click="sendMsg">触发自定义事件</button>
</div>
</template>
<style scoped></style>
模板引用
事例1
<script setup>
import { ref } from 'vue';
const h1info = ref(null)
const showInfo = () => {
//输出结果 <h2>dom标签h2</h2>
console.log(h1info.value);
}
</script>
<template>
<div class="father">
<h2 ref="h1info">dom标签h2</h2>
<button @click="showInfo">输出对象</button>
</div>
</template>
事例2
<script setup>
import { ref } from 'vue';
import SunCom from "@/components/son-com.vue"
const suncom = ref(null)
const showInfo = () => {
//输出结果是一个对象可以自行尝试下
//取不到组件内部的属性和方法
//看下个知识点
console.log(suncom.value);
}
</script>
<template>
<div class="father">
<h2>父组件App</h2>
<SunCom @getMessage="getMessage" ref="suncom"></SunCom>
<button @click="showInfo">输出对象</button>
</div>
</template>
defineExpose
默认情况下在
//子组件
<script setup>
import { ref } from 'vue'
const name = ref("son name")
const setName = () => {
name.value = 'son new name'
}
//配置之后组件内部的属性和方法可以开放给父组件访问
defineExpose({
name,
setName
})
</script>
<template>
<div class="son">
<h3>子组件Sons</h3>
</div>
</template>
<style scoped></style>
provide,inject
跨层传递普通数据
- 顶层组件通过provide函数提供数据 provide(key,data)
- 底层组件通过inject函数获取数据 const message=inject(key)
- app.vue
<script setup>
import { ref, provide } from 'vue';
import RoomMsgComment from '@/components/room-msg-comment.vue'
provide("data-key", "this is a room-page data")
//传递响应式数据
const count = ref(0)
provide("count", count)
const setCount = () => {
count.value++
}
</script>
<template>
<div class="father">
顶层组件
<div>
<RoomMsgComment></RoomMsgComment>
</div>
<button @click="setCount">+1</button>
</div>
</template>
- room-msg-item.vue
<script setup>
import RoomMsgComment from '@/components/room-msg-comment.vue'
</script>
<template>
<div class="middle">
底层组件
` <RoomMsgComment></RoomMsgComment>`
</div>
</template>
<style></style>
3.room-msg-commment.vue
<script setup>
import { inject } from 'vue';
const roomData = inject("data-key")
const count = inject("count")
</script>
<template>
<div class="comment">
底层组件
<div>
来自顶层组件中的数据为:{{ roomData }}
</div>
<div>
来自顶层组件的响应式数据:{{ count }}
</div>
</div>
</template>
<style></style>
4.界面显示
顶层组件
底层组件
来自顶层组件中的数据为:this is a room-page data
来自顶层组件的响应式数据:0
+1(button)