Vue3(三)高阶

好看的网页千篇一律,有趣的代码万里挑一。
2022新年好!

关键字:

Vue3高阶\Hook函数\ 生命周期\toRef和toRefs \其他的组合式API

1. Hook函数

useCar

import {ref,computed} from 'vue'
//导出去一个函数
export default function(){
    //汽车数据
    let carName = ref('保时捷')
    let carPrice = ref(100)
    //汽车的计算属性
    let carPrice2 = computed(()=>{
        return (carPrice.value*0.8).toFixed(2)
    })
    //操作汽车的方法
    let updateCar = ()=>{
        carName.value = '宾利'
        carPrice.value = 300
    }
    //返回暴露给外界的内容
    return {
        carName,
        carPrice,
        carPrice2,
        updateCar
    }
}

usePhone

import {ref,computed} from 'vue'
export default function(){
    //手机数据
    let phoneName = ref('华为')
    let phonePrice = ref(5000)
    //手机的计算属性
    let phonePrice2 = computed(()=>{
        return (phonePrice.value*0.5).toFixed(2)
    })
    //操作手机的方法
    let updatePhone = ()=>{
        phoneName.value = '苹果'
        phonePrice.value = 9000
    }
    //返回暴露给外界的内容
    return {
        phoneName,
        phonePrice,
        phonePrice2,
        updatePhone
    }
}

组件

<h1>Hook函数</h1>
<div class="car">
    <h2>汽车信息</h2>
    <ul>
        <li>汽车名称:{{carName}}</li>
        <li>汽车价格:{{carPrice}}万</li>
        <li>优惠价格:{{carPrice2}}万</li>
        <li>
            <button @click="updateCar">修改汽车信息</button>
        </li>
    </ul>
</div>
<div class="phone">
    <h2>手机信息</h2>
    <ul>
        <li>手机名称:{{phoneName}}</li>
        <li>手机价格:{{phonePrice}}</li>
        <li>优惠价格:{{phonePrice2}}</li>
        <li>
            <button @click="updatePhone">修改手机信息</button>
        </li>
    </ul>
</div>
// 导入hook函数
import useCar from '../hooks/useCar'
import usePhone from '../hooks/usePhone'
export default {
    setup() {
        // 返回模板中需要使用的数据
        return {
            //返回汽车信息
            ...useCar(),
            //返回手机信息
            ...usePhone()
        }
    }
}

2. 生命周期

变化挺大的:

<h1>生命周期</h1>
<h3>
    数量:{{count}}
    <button @click="count++">数量++</button>    
</h3>
// 组合式API生命周期函数
import {onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
export default {
    // beforeCreate() {
    //     console.log('创建之前');
    // },
    // created() {
    //     console.log('创建完成');
    // },
    // beforeMount() {
    //     console.log('挂载之前1');
    // },
    // mounted() {
    //     console.log('挂载完成1');
    // },
    // beforeUpdate() {
    //     console.log('更新之前1');
    // },
    // updated() {
    //     console.log('更新完成1');
    // },
    //注意:在vue3中,对beforeDestroy和destroyed这两个生命周期函数,进行了重命名
    /* beforeDestroy() {
        console.log('销毁之前');
    },
    destroyed() {
        console.log('销毁完成');    
    }, */
    // 在vue3中,beforeUnmount 替换了 beforeDestroy;unmounted 替换了 destroyed
    // beforeUnmount() {
    //     console.log('卸载之前1');
    // },
    // unmounted() {
    //     console.log('卸载完成1');
    // },
    data() {
        return {
            count:1
        }
    },
    // setup()函数,可以替代beforeCreate 和 created 这两个生命周期函数
    setup() {
        console.log('setup');
        //组合式API生命周期函数,会先与传统的生命周期函数执行
        onBeforeMount(()=>{
            console.log('挂载之前2');
        })
        onMounted(()=>{
            console.log('挂载完成2');
        })
        onBeforeUpdate(()=>{
            console.log('修改之前2');
        })
        onUpdated(()=>{
            console.log('修改完成2');
        })
        onBeforeUnmount(()=>{
            console.log('卸载之前2');
        })
        onUnmounted(()=>{
            console.log('卸载完成2');
        })
    }
}

3. toRef和toRefs

<h1>toRef和toRefs</h1>
<div class="stu">
    <h2>学生信息</h2>
    <ul>
        <li>姓名:{{name}}</li>
        <li>姓名:{{age}}</li>
        <li>车名:{{car.name}}</li>
        <li>车价:{{car.price}}</li>
    </ul>
</div>
import { reactive,toRef,toRefs } from 'vue'
export default {
    setup() {
        // 定义数据
        let stuData = reactive({
            name:'张三',
            age:20,
            car:{
                name:'大众',
                price:'20W'
            }
        })
        return{
            // toRef()函数,可以用来为一个 reactive 对象的属性创建一个 ref
            // 这样做的好处是,简化了模板中的表达式。
            // toRef()函数,需要传两个参数:1.reactive 对象,2.具体的属性名
            // name:toRef(stuData,'name'),
            // age:toRef(stuData,'age'),
            // car:toRef(stuData,'car')
            // 假如 reactive 对象中,有100个属性,上面的操作要写100次,所以,一般都直接用toRefs函数
            // toRefs函数,把一个响应式对象转换成普通对象,该普通对象的每个 属性 都是一个 ref 
            ...toRefs(stuData)
        }
    }
}

4.其他的组合式API

<h1>其他的组合式API</h1>
<div>
    学生信息:{{stuData}}
    <br>
    <button @click="stuData.age++">修改年龄</button>
    <button @click="stuData.car.price++">修改车价</button>
</div>
<div>
    num3的值:{{num3}}
</div>
<div>
    汽车信息:{{car}}
    <button @click="updateCar">修改汽车</button>
</div>
<div>
    手机信息:{{phone}}
    <button @click="updatePhone">修改手机</button>
</div>
<div>
    年龄:{{age}}
    <button @click="age++">年龄++</button>
</div>
import {ref,reactive,readonly,isRef,unref, shallowRef, isReactive, shallowReactive,customRef,toRaw, markRaw} from 'vue'
export default {
    setup() {
        // 定义数据
        // readonly()函数,返回一份只读数据,这个只读是“深层的”,内部任何嵌套的属性也都是只读的
        let stuData = readonly({
            name:'张三',
            age:20,
            car:{
                name:'大众',
                price:20
            }
        })
        let num1 = ref(100)
        let num2 = 200
        // isRef()函数,检查一个值是否为一个 ref 对象
        // isProxy()函数,检查一个对象是否是由 reactive 或者 readonly 方法创建的代理
        // isReactive()函数,检查一个对象是否是由 reactive 创建的响应式代理
        // isReadonly()函数,检查一个对象是否是由 readonly 创建的只读代理
        // let num3 = (isRef(num1)?num1.value:num1) + (isRef(num2)?num2.value:num2)
        // unref()函数,如果参数是一个 ref 则返回它的 value,否则返回参数本身
        let num3 = unref(num1) + unref(num2)
        // ref() 返回的对象 value 属性值是 reactive对象(代理对象)
        // shallowRef() 返回的对象 value 属性值是 object对象(普通对象),不再具备任何响应式了
        let car = shallowRef({
            name:'大众',
            type:{
                typeName:'SUV'
            }
        })
        let updateCar = ()=>{
            // 由于value返回的是object对象,所以,这里不再具有响应式
            car.value.name = '奔驰'
            car.value.type.typeName = '跑车'
        }
        // shallowReactive() 返回一个浅层的响应式代理,只对对象的第一层属性创建响应式
        let phone = shallowReactive({
            name:'华为',
            type:{
                typeName:'滑盖手机'
            }
        })
        // toRaw() 将代理对象转为一个普通对象返回
        let phone2 = toRaw(phone)
        console.log(phone2);
        console.log('--------------------');
        //定义了一份数据
        // markRaw() 记一个对象为“永远不会转为响应式代理”
        let food = markRaw({
            name:'面包'
        })
        // 注意:food2就是一个普通对象
        let food2 = reactive(food)
        console.log(food2);
        let updatePhone = ()=>{
            //修改name,会触发页面更新
            // phone.name += "!"
            //修改type里面的属性,不会触发页面更新
            phone.type.typeName += "!"
        }
        //自定义一个ref
        function useDebouncedRef(value, delay = 200) {
            let timeout
            // customRef(),用于自定义一个 ref
            return customRef((track, trigger) => {
                return {
                    get() {
                        track()
                        return value
                    },
                    set(newValue) {
                        clearTimeout(timeout)
                            timeout = setTimeout(() => {
                            value = newValue
                            trigger()
                        }, delay)
                    },
                }
            })
        }
        let age = useDebouncedRef(20,2000)
        return {
            stuData,
            num3,
            car,
            updateCar,
            phone,
            updatePhone,
            age
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容