even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、vue3与vue2的区别

  •   源码采用monorepo方式进行管理,将模块拆分到package目录中(是管理项目代码的一个方式,指在一个项目仓库(repo)中管理多个模块/包package,调用方便,但是体积大)
  •   vue3采用了ts开发,增强类型检测,vue2则采用了flow
  •   vue3的性能优化,支持tree-shaking,不使用则不打包
  •   vue2后期引入RFC,使每个版本改动可控rfcs

2、vue3.0的安装

npm install -g @vue/cli@next
//对原有项目的升级
vue upgrade --next

升级后可以用vue ui进行vue3项目的创建

3、vue创建实例的区别

vue3与vue2的区别大致会编写在gitbub上的vuejs/rcfs

<script>
    // let app = new Vue({
    //     template: '<div>{{content}}</div>',
    //     data: {
    //         content: 'abc'
    //     }

    // })
    // let vm = app.$mount('#root')
    // console.log(app, vm)  //两者都返回vue实例


    let app = Vue.createApp({
        template: '<div>{{content}}</div>',
        data() {  //注意:这里用的是一个函数,与版本2是有区别的
            return {
                content: 'abc'
            }
        },
        setup() {
            const test = () => {
                console.log('yes')
            }
            return {
                test
            }
        }
    })
    let vm = app.mount('#root')
        console.log(app, vm) //前者返回实例后者返回代码的数据对象
</script>

注意:前者的app与vm返回的都是vue实例,而后者进行的区别,app返回的是vue的实例,而vm返回的是数据的代理

4、vue3的生命周期函数的变量

vue3相对于vue2生命周期函数作了一些调号,把原来的beforeDestroy, destroyed替换成了beforeUnmount与unmounted两个函数,功能不变,同时在vue的实例中,把destroy方法改成了 unmount方法,实现不挂载

    let app = Vue.createApp({
        template: '<div @click="test">{{content}}</div>',
        data() {
            return {
                content: 'abc'
            }
        },
        setup(proxy) {
            const test = () => {
                console.log(app, vm)
            }

            return {
                test
            }
        },
        beforeUnmount() {  //表示当Vue失效前,自动执行的函数
            console.log('beforeUnmount')
        },
        unmounted() { //表示当Vue应用失效时,且dom完全销毁之后,自动执行的函数
            console.log('unmounted')

        }
    })
    let vm = app.mount('#root')

5、数据响应的调整

在vue2时数据值的变化不能通过key值的形式直接赋值,但是vue3底层用proxy的原理来实现,可以使用key值的形式更改

let app = Vue.createApp({
    template: '<div @click="test">{{content}} <span v-for="(val, ind) of list" :key="ind">{{val}}</span></div>',
    data() {
        return {
            content: 'abc',
            list: ['aa', 'bb']
        }
    },
    methods: {
        test() {
            this.list[0] = 'cc'
        }
    }
})
let vm = app.mount('#root')

注意: 在vue的新版本里面,可以直接添加对象,通过key的方式添加,而在vue2里面,只能通过$set才能实现,在vue3中,v-if的优先级要低于v-for这点要区别于vue2

6、事件响应

通常来讲vue的事件中,在没有传参的情况下,第一个参数默认是event,但是如果遇到传参又想获取event对象,那么这个时候就需要手动传一个参数$event

let app = Vue.createApp({
    template: `<div @click="test('yes', $event)">{{content}}</div>`,
    data() {
        return {
            content: 'abc'
        }
    },
    methods: {
        test() {
            console.log(arguments)
        }
    }
})
let vm = app.mount('#root')

 如果一个事件需要绑定两个及以上的事件,那么可以按以下的写法

let app = Vue.createApp({
    template: `<div @click="test('yes', $event), test2()">{{content}}</div>`, //注意这里的函数需要采用调用模式
    data() {
        return {
            content: 'abc'
        }
    },
    methods: {
        test() {
            console.log(arguments)
        },
        test2() {
            console.log('test2', arguments)
        }
    }
})
let vm = app.mount('#root')

 .native 修饰符在 Vue 3.x 已经移除掉了。取而代之的是,在新增的 emits 选项中定义当前组件真正触发的事件(即,组件事件)。此外,Vue 现在将所有未在组件emits 选项中定义的事件作为原生事件添加到子组件的根元素中(除非子组件选项中设置了 inheritAttrs: false

<template>
    <div>
        <button v-on:click="$emit('click')">click</button>
        <button v-on:click="$emit('close')">close</button>
    </div>
</template>
<script>
  export default {
    emits: ['close']
  }
</script>

上面代码的执行结果是:click事件会被自动添加到<div>中,所以当子组件被点击时,就会触发click事件。

<template>
    <div>
        <button v-on:click="$emit('click')">click</button>
        <button v-on:click="$emit('close')">close</button>
    </div>
</template>
<script>
  export default {
    emits: ['close', 'click']
  }
</script>

click事件不会被添加给<div>强烈建议组件中使用的所有通过emit触发的event都在emits中声明。

7、组件.sync的调整

通常来讲在vue2.0版本,如果需要在子集中修改父级的值,那么在传入的时候用修饰值.sync,并且在方法内部调用this.$emit('update:key值', value)可以实现修改,但是vue3作了一些修改,用v-model替代。sync语法

let Check = {
    props: ['message'],
    template: `<div>this is check --- {{message}}</div><button @click='change'>点击</button>`,
    methods: {
        change() {
            this.$emit('update:message', 'haha')
        }
    }
}

let app = Vue.createApp({
    template: `<div><div @click="test('yes', $event)">{{content}}</div> <Check v-model:message='content' /></div>`,
    components: {
        Check
    },
    data() {
        return {
            content: 'abc'
        }
    },
    methods: {
        test() {
            console.log(arguments)
        }
    }
})

let vm = app.mount('#root')

注意:在使用v-model的时候有几个注意点,在处理表单的时候v-model后面可以加修饰符,如.lazy .number .trim但是在组件中使用v-model的时候也可以使用类似的修饰符,并且这些修饰符可以自定义,但是如果指定字段就不可以使用修饰符了:如v-model:msg='msg'就不能使用修饰符了

let Check = {
    template: `<div><div>{{modelValue}}</div><button @click='clickEvent'>点击</button></div>`,
    props: {
        modelValue: {  // 默认v-model的值的接收要用到modelValue
            type: String
        },
        modelModifiers: { //接收v-model的修饰符的,以便后面做逻辑处理
            default: () => ({})
        }
    },
    methods: {
        clickEvent() {
            console.log(this.modelModifiers)
            this.$emit('update:modelValue', '        yes   ')
        }
    }
}

let app = Vue.createApp({
    template: `<div class='container'>
        <h1>this is app</h1>
        <Check v-model.check='msg' />
    </div>`,
    components: {
        Check
    },
    data() {
        return {
            msg: 'are you ok???'
        }
    }
})

let vm = app.mount('#root')

8、ref的用法提升

在vue2版本中,ref不仅可以获得常规的dom元素,同时也可以获取所对应的组件,但是在vue3中作了一些调整,不仅可以挂载单个元素,同时也可以挂载多个元素集,具体如下

let Check = {
    template: `<div>this is check</div>`,
}

let app = Vue.createApp({
    template: `<div><div @click="test('yes', $event)">{{content}}</div> <div :ref='setRefs'>haha</div></div>`,
    components: {
        Check
    },
    data() {
        return {
            content: 'abc',
            // elem: [],
            elem: ''
        }
    },
    methods: {
        setRefs(el) {
            // this.elem.push(el)
            this.elem = el
        },
        test() {
            console.log(arguments)
            console.log(this.elem)
        }
    }
})

let vm = app.mount('#root')

注意:以上可以是字符,数组,还可以是对象

9、slot的写法的调整

let Test = {
    template: `<div class='testContainer'>
        <slot name='header'>header</slot>
        <div>this is content</div>
        <slot name='footer'>footer</slot>
    </div>`
}

let app = Vue.createApp({
    template: `<div class='container'>
        <Test>
            <template v-slot:header><div>1111</div></template>
            <template #footer><div>2222</div></template></Test>
    </div>`,
    components: {
        Test
    }
})

let vm = app.mount('#root')

注意:在编写slot的时候,外面调用需要套一层template,并且里面的具名需要用v-slot:*** 简写  #***

slot值的回传

let Test = {
    template: `<div class='testContainer'>
        <slot name='header' :list='list'></slot>
    </div>`,
    data() {
        return {
            list: ['aa', 'bb', 'cc']
        }
    }
}

let app = Vue.createApp({
    template: `<div class='container'>
        <div id='abc'></div>
        <Test>
            <template v-slot:header='{list}'><div>{{list}}</div></template>
        </Test>
    </div>`,
    components: {
        Test
    }
})

let vm = app.mount('#root')

 

posted on 2021-05-07 06:58  even_blogs  阅读(155)  评论(0编辑  收藏  举报