1.ref函数调用的方式生成响应式数据,可以传复杂和简单数据类型
<script setup>
// reactive接收一个对象类型的数据
import { reactive } from 'vue';
// ref用函数调用的方式生成响应式数据,可以传复杂和简单数据类型
import { ref } from 'vue'
// 简单数据类型
const count = ref(0)
// 复杂数据类型
const user = ref({
name: '小夏',
age: 18
})
const subCount = () => {
count.value--
}
function addCount() {
count.value++
}
</script>
<style></style>
<template>
<!-- ref -->
<div>
{{ count }}
</div><br>
<button @click="subCount">-1</button>
<button @click="addCount">+1</button>
<div>{{ user.name + user.age }}</div><br>
</template>
2.computed计算属性(依赖的数据发生变化时实时更新)
<script setup>
import { ref } from 'vue'
const list = ref([1, 2, 3, 4, 5, 6])
//计算属性
import { computed } from 'vue';
const computedList = computed(() => {
return list.value.filter(item => item > 2)
})
const addFn = () => {
list.value.push(4)
}
console.log(list.value)
</script>
<style></style>
<template>
<div>{{ computedList }}</div>
<button @click="addFn">添加</button>
</template>
3.watch监视单个数据的变化(相当于操作日志)
<script setup>
import { ref, watch } from 'vue'
const num = ref(1)
const name = ref('李四')
const changeNum = () => {
num.value++
}
const changeName = () => {
name.value = name.value + 1
}
const obj = ref({
name:'老夏',
age:18
})
const changeObjName = ()=>{
obj.value.name = '小夏'
}
//监视单个数据的变化
// 1.watch默认浅层监视,不会监视对象里的属性的值的改变
watch(obj,(newValue,laoValue)=>{
console.log('监视单个数据的变化')
console.log(newValue,laoValue)
},{
// 2.深层监视,可以监视对象里的属性的值的改变
deep:true
}
)
//监视多个数据的变化
watch([num,name], (newArr, oldArr) => {
console.log('监视多个数据的变化')
console.log('新数据:' + newArr, '老数据:' + oldArr)
},
// 3.immediate一进页面就立即刷新一次
{
immediate: true,
}
)
//监视单个对象属性的变化
watch(()=>obj.value.name,(newValue,oldValue)=>{
console.log('监视单个对象属性的变化')
console.log(newValue,oldValue)
})
</script>
<style></style>
<template>
<div>{{ num }}</div>
<button @click="changeNum">+++</button>
<div>{{ name }}</div>
<button @click="changeName">改名字</button>
<div>{{ obj.name }}</div>
<button @click="changeObjName">改对象里面属性的值</button>
</template>
4.Props-Emits组件相互传数据
父组件
<script setup>
import son from '@/components/04-son.vue'
import { ref } from 'vue'
const money = ref(1000)
// ele就是子组件传来的属性值
const changeMoney = (attributeValue) => {
console.log('子组件花了' +attributeValue)
}
</script>
<style></style>
<template>
<div>
<!-- car,money里面的属性值直接传给了子组件 -->
<!-- layOut是子组件向父组件传的值 -->
<son car="车车" :money="money" @layOut="changeMoney"></son>
</div>
</template>
子组件
<script setup>
//子组件
// defineProps是固定的写法,定义接收数据的属性名,和属性值类型
const props = defineProps({
car: String,
money: Number
})
//defineEmits([自定义一个属性名])
const emit = defineEmits(['layOut'])
// 通过emit向父组件发送数据
const buy = () => {
emit('layOut', 100)
}
console.log(props.car)
console.log(props.money)
</script>
<style scoped>
.son {
width: 100px;
height: 100px;
border: 1px solid;
}
</style>
<template>
<div class="son">
子组件
</div>
<div>父组件给了{{ props.money }}</div>
<button @click="buy">花钱</button>
</template>
5.defineExpose开放属性和方法
父组件
<script setup>
import { ref,onMounted } from 'vue'
import son05 from '@/components/05-son.vue'
const input = ref()
// 生命周期钩子 onMounted ,一进页面输入框就聚焦
onMounted(() =>{
// input.value.focus()
})
//绑定事件聚焦
const onClick = ()=>{
input.value.focus()
}
const getSonData = ref()
const putSonData = ()=>{
const fatherName = getSonData.value.name
console.log(getSonData.value.greeting())
console.log(fatherName)
}
</script>
<style></style>
<template>
<input type="text" ref="input">
<button @click="onClick">聚焦</button>
<son05 ref="getSonData"></son05>
<button @click="putSonData">获取儿子组件中的数据</button>
</template>
子组件
<script setup>
const name = "儿子的数据"
const greeting = () => {
console.log('hello儿子的数据')
return '默认rturn未定义'
}
// setup语法糖下的组件内部的属性和方法不供外部组件访问
// 可以通过defineExpose编译宏指定哪些属性和方法允许访问
defineExpose({
name,
greeting
})
</script>
<template></template>
6.provide-inject提供和注入数据
父组件
<script setup>
import inject from '@/components/06-inject.vue'
import { provide,ref } from 'vue';
//1.提供普通数据给其他组件
provide('commonData',"这是我提供的普通数据哦")
//2.提供响应数据给其他组件
const responseData = ref({
msg:'这是我提供的响应数据哦',
})
provide('responseData',responseData)
//3.提供给数据调用者修改数据的权力
provide('setResponseData',(newResponseData)=>{
responseData.value.msg = newResponseData
})
</script>
<style></style>
<template>
<inject></inject>
</template>
子组件
<script setup>
import {inject,ref} from 'vue'
//注入数据
const getResponseData = inject('responseData')
const getCommonData = inject('commonData')
//注入修改数据的set方法
const setData = inject('setResponseData')
const changeData = ()=>{
setData('这是调用者修改后的数据')
}
</script>
<template>
<div> {{getResponseData.msg}}</div>
<div>{{getCommonData}}</div>
<button @click="changeData">点击按钮修改数据</button>
</template>
7.defineModel数据双向绑定 ,其他组件使用v-model就可以获取此属性数据
父组件
<script setup>
import sonDefineMOdel from '@/components/07-defineModel.vue'
import { ref } from 'vue';
// 其他组件传来的数据也可以修改
const getSonData = ref('')
</script>
<style></style>
<template>
<sonDefineMOdel v-model="getSonData"></sonDefineMOdel>
<div>
{{ getSonData }}
</div>
</template>
子组件
<script setup>
import { defineModel } from 'vue';
// 数据双向绑定 ,其他组件使用v-model就可以获取此属性数据
const modelValue = defineModel()
</script>
<template>
<!-- @input事件用于实时监控输入框的变化,每次用户输入都会触发该事件。 -->
<input type="text" :value="modelValue"
@input="e => modelValue = e.target.value">
<!-- 箭头函数 e => modelValue 的意思是:
当事件触发时,将事件对象 e 作为参数传递给箭头函数,
并将输入框的新值(即 e.target.value)赋给 modelValue。 -->
</template>
8.pinia管理自己创建的store.js仓库
自己创建的仓库
// store的作用类似于Java的父类,被子类继承数据和方法
import {
defineStore
} from 'pinia'
import {
ref,computed
} from 'vue'
// 声明一个store
export const useStore = defineStore('myStore', {
state: () => {
const name = ref('小夏')
// 声明数据 state
let age = ref(17)
// 声明操作数据的方法 action(普通函数)
const func = () => {
console.log('我是方法')
}
const addAge = () => {
age.value++
}
// 声明基于数据派生的计算属性
const judge = computed(
()=>{
if (age.value>=18){
return "已成年"
}else{
return "未成年"
}
}
)
return {
name,
age,
func,
addAge,
judge
}
}
})
在组件中引入自己创建的仓库
<script setup>
import Pinia08 from '@/components/08-pinia.vue'
// 引入自己创建的store
import { useStore } from '@/store/myStore'
const getStoreData = useStore()
</script>
<template>
<div>{{ getStoreData.name }}</div>
<Pinia08></Pinia08>
<div>{{ getStoreData.func() }}</div>
<div>{{ getStoreData.judge}}</div>
<button @click="getStoreData.addAge">加年龄</button>
</template>
<style scoped></style>