Ref语法
import { ref } from 'vue'
export default {
name: 'App',
setup() {
const count = ref(0)
//count与ref进行绑定,变成响应对象
const double = computed(()=>{
return count.value * 2
//ref对象可以直接把value的值展现出来
})
const increase = ()=> {
count.value++
}
return {
count,
increase
}
}
};
template
<h1>{{count}}</h1>
<h1>{{double}}</h1>
<button @click='increase'>+1</button>
Reactives函数
import { ref, computed, reactive, toRefs } from 'vue'
// reactive 是一种object,可以放入一系列响应式数据
// 特别注意模板中是否用了引用类的数据类型,如果是,return的时候要保证它的类型
interface DataProps {
count: number;
double: number;
increase: () => void;
numbers:number[];
person:{name?:string}
}
//定义data,确保它return时的数据类型,需要结合toRefs
setup() {
const data: DataProps = reactive({
//DataProps定义了data里面的属性
count: 0,
increase: () => { data.count++},
double: computed(() => data.count * 2)
})
data.numbers[0]=5;
data.person.name='viking';
//vue2.0通过defineProperty的getter和setter来双向绑定数据,但弊端在于这无法检测到数据的新增和改动
//vue3.0用Proxy模式,对每一个元素属性都可以检测到
const refData = toRefs(data)
//使用 toRefs 保证 reactive 对象属性保持响应性
return {
...refData
}
}
Vue 3.0 生命周期
setup() {
onMounted(() => {
console.log('mounted')
})
//一刷新page就会log
onUpdated(() => {
console.log('updated')
})
//一更新页面数据就会log
onRenderTriggered((event) => {
console.log(event)
})
//记录了重新rerender的时候哪些值发生了变化
}
侦测变化 -watch
import { ref, computed,reactive, toRefs, watch } from 'vue'
interface DataProps {
count:number;
increase:()=> void;
}
export default {
name: 'App',
setup() {
const data:DataProps = reactive({
count:0,
increase:()=>{data.count++}
})
const greetings = ref('')
const updateGreeting = () => {
greetings.value += 'hello!'
}
//监听 watch
watch([greetings,()=>data.count],(newValue,oldValue) => {
//用一个函数包裹data.count,防止data.count失去响应式数据的特性
console.log('old', oldValue)
//old (2) ["hello!hello!hello!", 0]
console.log('new', newValue)
//new (2) ["hello!hello!hello!hello!", 0]
document.title='updated' + greetings.value
//这里会update到Bom页面上的标签名噢
})
const refData = toRefs(data)
return{
...refData,//三个点是es6表达式,表示refData里面的所有内容
greetings,
updateGreeting
}
//下面千万记得导出来!!!!!愚蠢如我debug了半天
<template>
<div>
<img alt="Vue logo" src="./assets/logo.png">
<h1>{{count}}</h1>
<h1>{{greetings}}</h1>
<!-- ref对象可以直接把value的值展现出来 -->
<button @click='increase'>+1</button>
<button @click='updateGreeting'>update Title</button>
</div>
</template>
模块化:鼠标追踪器
在hooks文件夹下创建一个useMousePosition.ts
可以reactive也可以ref
import { reactive, onMounted, onUnmounted, toRefs } from 'vue'
//raective一定会用到toRefs
interface positionProps {
x:number;
y:number;
}
function useMousePosition(){
const position:positionProps = reactive({
x:0,
y:0
})//reactive出现的地方
const updateMouse = (e:MouseEvent) => {
position.x=e.pageX
position.y=e.pageY
}//直接更改position内部的函数
onMounted(()=>{
document.addEventListener('click',updateMouse)
})
onUnmounted(()=>{
document.removeEventListener('click',updateMouse)
})
const refPosition = toRefs(position)
//toRefs保护position在return时不会丧失响应
return {
...refPosition
}
}
export default useMousePosition
//记得要导出噢!
在App.vue文件夹中
import useMousePosition from '@/hooks/useMousePosition'
export default {
name: 'App',
setup() {
const{x , y} = useMousePosition()
//引用外部composition的时候记得加括号在后面
return{
...refData,
x,
y
}
},
}
模块化:加载页面缓存
在hooks里面新建一个useURLLoder的功能
import { ref } from 'vue'
import axios from 'axios'
function useURLLoader (url:string) {
const result = ref(null)
const loading = ref(true)
const loaded = ref(false)
const error = ref(null)
axios(url).then((rawData)=>{
loading.value = false
loaded.value = true
result.value = rawData.data
}).catch((e)=>{//如果出错,则loading结束,loaded也保持未完成
error.value=e
loading.value = false
})
return {
result,
loading,
loaded,
error
}
}
export default useURLLoader
在App.vue页面引用
<h1 v-if='loading'>Loading......</h1>
<img v-if='loaded' :src="result.message" alt="dog picture">
<!--下面是script !-->
const {result, loading ,loaded} = useURLLoader('https://dog.ceo/api/breeds/image/random')
用狗狗网站的API接口可以返回一个{具有属性message:狗狗图片地址}的对象