vue3.0新特性

这些是setup函数,生命周期,reactive函数,toRef函数,toRefs函数,ref函数的基本用法

还有vue3.0的计算属性,监听器,ref属性变化

除此之外还有一个案例来使用上面的新特性

demo目录如下 

App.vue

<template>
    <div class="countainer" style="display: flex">
        <div style="flex: 1">
            <div>{{ msg }}</div>
            <button @click="func()">点我获取setup里的函数方法</button>
            <div>
                我是被解构的数据name: {{ name }}
                <br />
                我是被toRef的数据name2: {{ name2 }}
            </div>
            <button @click="func3()">点我改变被解构的和toRef的数据</button>
            <div>
                obj.name:{{ obj.name }}
                <br />
                obj.age:{{ obj.age }}
                <br />
                obj2.name:{{ obj2.name }}
                <br />
                obj2.age:{{ obj2.age }}
                <br />
            </div>
            <button @click="func2()">点我改变数据</button>
            <div>
                我是用...的被toRefs的obj3数据name: {{ obj3Name }}
                <br />
                我是用...的被toRefs的obj3数据age: {{ obj3Age }}
                <br />
                我是用...的被toRefs的obj3数据active: {{ obj3Active }}
                <br />
            </div>
            <button @click="func4()">点我改变toRefs的数据</button>
            <div>
                我是被ref定义的refName数据: {{ refName }}
                <br />
                我是被ref定义的refAge数据: {{ refAge }}
                <br />
            </div>
            <button @click="func5()">点我修改被ref定义的数据</button>
            <demo1 />
            <demo2 />
            <demo3 />
        </div>
        <div style="flex: 1">
            <demo4 />
        </div>
    </div>
</template>
<script>
import { onBeforeMount, onMounted, reactive, toRef, toRefs, ref } from 'vue'
import demo1 from './components/demo1.vue'
import demo2 from './components/demo2.vue'
import demo3 from './components/demo3.vue'
import demo4 from './components/demo4.vue'
export default {
    name: 'App',
    components: {
        demo1,
        demo2,
        demo3,
        demo4,
    },
    /**
     * 模板中需要的数据和函数,都从setuo里返回
     */
    setup() {
        console.log('setup', this); // 先执行,this是underfined,将来组合API的代码全部都在这里
        let msg = '我是setup返回的数据'
        const func = () => {
            console.log('我是setup返回的函数方法', 'func');
            console.log(msg, 'msg'); // 不需要this就可以访问
        }

        console.log('-------------------------');

        console.log('下面是vue3.0和vue2.0的生命周期, 在setup里面的生命周期函数不用return出去');
        onBeforeMount(() => {
            console.log('onBeforeMount挂载DOM前', 'vue3.0', document.querySelector('.countainer'));
        }),
            onMounted(() => {
                console.log('onMounted挂载DOM后', 'vue3.0', document.querySelector('.countainer'));
            })

        console.log('-------------------------');

        // 普通数据无法被响应式修改
        const obj = {
            name: 'pasco152',
            age: 24,
            active: 'play'
        }
        // 但是reactive可以,有一点就是这里如果普通数据和reactive一起用,普通数据也会被改变
        // 注意reactive是用来定义复杂数据类型的 
        const obj2 = reactive({
            name: 'reactive的pasco152',
            age: 'reactive的24',
            active: 'reactive的play'
        })
        const func2 = () => {
            obj.name = 'pasco152被改变了';
            obj.age = '24被改变了';
            obj2.name = 'reactive的pasco152被改变了'
            obj2.age = 'reactive的24被改变了'
        }
        // 用解构的方式,此时name变为无法被响应式修改的数据,但是obj2仍旧是响应式数据
        let { name } = obj2;
        // 用toRef的方式
        // toRef的使用场景是: 有一个响应式数据,但是模板只需要使用其中一项数据,并且这两个数据是相互关联的
        const name2 = toRef(obj2, 'name'); // 在这里用const也没关系,因为toRef已经把它变为一个对象
        const func3 = () => {
            console.log('修改被解构数据的方法触发了');
            name = '我是被解构的数据name'
            name2.value = '我是被toRef的数据name2' // 注意这里要用value去修改
        }
        // 用toRefs的方式,可以用...obj3的方式直接在template上面使用参数
        // 同样如果使用解构的方式去修改的话,数据就不再是响应式的了,这里不做赘述
        const obj3 = reactive({
            obj3Name: 'obj3的reactive的pasco152',
            obj3Age: 'obj3的reactive的24',
            obj3Active: 'obj3的reactive的play'
        })
        // toRefs的使用场景: 剥离响应式对象,想使用响应式对象中的多个或者所有属性作为响应式数据
        const obj3Ref = toRefs(obj3);
        const func4 = () => {
            obj3.obj3Name = '我是被toRefs的数据obj3Name', // 这里为啥不用obj3Ref.obj3Name.value呢,这是因为obj3和obj3Ref是互通的
                obj3.obj3Age = '我是被toRefs的数据obj3Age',
                obj3.obj3Active = '我是被toRefs的数据obj3Active'
        }

        // 接下来使用ref来定义简单数据类型
        // 注意ref也可以定义复杂数据类型,reactive只能用来定义复杂数据类型
        // ref的使用场景: 当你明确知道这个数据是复杂数据类型就用reactive,不确定就使用ref
        const refName = ref('我是ref定义的name')
        const refAge = ref('我是ref定义的age')
        const func5 = () => {
            refName.value = '我是ref定义的name被修改了' // 在获取、修改值的时候需要使用.value
            refAge.value = '我是ref定义的age被修改了' // 但是在tamplate上使用的时候不需要使用.value
        }

        return { msg, obj, obj2, name, name2, ...obj3Ref, refName, refAge, func, func2, func3, func4, func5 }; // 这里返回的是一个对象
    },
    /**
     * vue3.0也支持vue2.0的生命周期,他们可以和谐的在一起使用
     */
    beforeCreate() { // vue2.0的生命周期
        console.log('beforeCreate', 'vue2.0', document.querySelector('.countainer')); // 后执行
    },
}
</script>

demo1.vue

<template>
    <div class="demo1">
        <div>---------------------子组件demo1------------------------</div>
        鼠标坐标<br>
        我是被toRefs定义的数据X: {{ x }}<br>
        我是被toRefs定义的数据Y: {{ y }}
    </div>
</template>


<script>
import { onMounted, onUnmounted, reactive, toRefs } from 'vue'
export default {
    name: 'demo1',
    setup() {
        // 鼠标坐标
        const mouse = reactive({
            x: 0,
            y: 0
        })

        const move = (e) => {
            mouse.x = e.pageX
            mouse.y = e.pageY
        }
        onMounted(() => {
            document.addEventListener('mousemove', move)
        }),
        onUnmounted(() => {
            document.removeEventListener('mousemove', move)
        })

        return { ...toRefs(mouse) }
    }
}

</script>

demo2.vue

<template>
    <div class="demo2">
        <div>-------------------子组件demo2--------------------------</div>
        数字: {{ count }}
        <button @click="addFunc()">点我+1</button>
        <button @click="reduceFunc()">点我-1</button>
        <button @click="zeroFunc()">点我归零</button>
    </div>
</template>

<script>
import { onMounted, reactive, ref } from 'vue'
    export default {
        name: 'demo2',
        setup() {
            const count = ref(0);
            const addFunc = () => {
                count.value++;
            }
            const reduceFunc = () => {
                count.value--;
            }
            const zeroFunc = () => {
                count.value = 0;
            }

            return { count, addFunc, reduceFunc, zeroFunc }
        }
    }
</script>

demo3.vue

<template>
    <div class="demo3">
        <div>-----------计算属性------------</div>
        <div>
            没被修改前name: {{ name }}<br>
            修改后name: {{ newName }}
        </div>
        <div>------------计算属性高级运用,get set函数</div>
        <div>
            没被修改前name2: {{ name2 }}<br>
            修改后name2: {{ newName2 }}<br>
            <input type="text" v-model="newName2">
        </div>
    </div>
</template>

<script>
import { ref, computed } from 'vue'
export default {
    name: 'demo3',
    setup() {
        let name = ref('一号pasco152');
        // 依赖现有的响应式数据,经过一定逻辑处理获得的一个新数据
        // 里面做过缓存
        // 计算属性不能更改
        let newName = computed(()=> {
            return name.value + '被computed改变了'
        })
        let name2 = ref('二号pasco152')
        let newName2 = computed( { // 注意这里computed的值也被改变了
            get() {
                // 这里获取计算属性的值
                return name2.value + '也被computed改变了'
            },
            set(value) {
                // value就是通过computed改变的值,也就是get返回的值,并不是name2本身的值
                name2.value = value + '被set改变了';
            }
        })
        return { name, newName, name2, newName2 }
    }
}
</script>

demo4.vue

<template>
    <div class="demo4">
        <div>---------watch侦听器--------------</div>
        <div>
            count: {{ count }}
            <button @click="addFunc()">点我count+1</button>
        </div>
        <div>
            obj1.name: {{ obj1.name }}<br>
            obj1.age: {{ obj1.age }}<br>
            <button @click="updateObj1">点我修改obj1</button>
        </div>
    </div>
</template>
<script>
import { reactive, ref, watch } from 'vue'
    export default {
        name: 'demo4',
        setup() {
            let count = ref(0);
            let obj1 = reactive({
                name: 'pasco152',
                age: 24
            })
            let addFunc = () => {
                count.value++;
            }
            let updateObj1 = () => {
                obj1.name = 'pasco152被修改了'
            }
            // 接下来监听count
            watch(count,(oldVal, newVal) => {
                console.log(oldVal); // 需要监听的目标
                console.log(newVal); // 改变后的值
            })
            // 接下来监听obj1
            watch(obj1, (oldVal, newVal) => {
                // 这里的新旧数据都是新数据,原因是因为响应式数据的关系
                console.log(oldVal);
                console.log(newVal);
            })
            // 再接下来监听多个数据
            watch([count, obj1], () => {
                console.log('监听多个数据被触发了');
            })
            // 再再接下来监听复杂数据中的某一项
            watch(()=>obj1.name, ()=>{ // 监听某一项需要用函数返回的形式
                console.log('监听obj1中的name被触发了');
            })
            return { count, obj1, addFunc, updateObj1 }
        }
    }
</script>

demo5.vue

<template>
    <div class="demo5">
        <div>-----------ref属性---------</div>
        <!-- 通过ref绑定元素 -->
        <!-- 通过this.$refs.box获取元素 -->
        <div ref="box">我是ref定义的box</div>
        <!-- 通过this.$refs.li获取所有遍历的元素 -->
        <ul>
            <li v-for="i in 5" :key="i" ref="li">{{ i }}</li>
        </ul>
        <!-- 单个 -->
        <div ref="dom">使用setup绑定的ref</div>
        <!-- 多个 -->
        <ul>
            <li v-for="i in 5" :key="i" :ref="setDom">{{ i }}</li>
        </ul>
        <button @click="count++">{{ count }}</button>
        <button @click="logList">打印domList的值</button>
    </div>
</template>
<script>
import { onBeforeUpdate, ref, onMounted } from 'vue'
export default {
    name: 'demo5',
    setup() {
        // 定义一个空的dom,return出去,在想绑定的元素上用ref绑定即可
        const dom = ref(null);
        onMounted(() => {
            console.log(dom.value);
            console.log(domList);
        })
        // 定义v-for遍历的元素
        let domList = [];
        const setDom = (el) => {
            // 该函数会被打印5次
            // 同时会传入值
            domList.push(el);
        }
        // 通过setDom设置的值虽然是可以的,但是会有一个问题,就是在每次onMounted的时候都会push进去
        // 所以需要在onBeforeUpdate里面还原domList
        onBeforeUpdate(() => {
            domList = [];
        })
        const count = ref(0);
        const logList = () => {
            console.log(domList);
        }
        return { dom, setDom, count, logList }
    }
}
</script>

中间换了个主题........这不重要,后续会有更新其他vue3.0的新特性以及完整的项目建立流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值