一起来康康vue3.0的新特性

最近笔者的学习的课题是针对 vue3.0的新特性进行学习分享,本文先从vue3.0的新特性入手,介绍vue3.0相对vue2.0有所调整的部分,之后再补充vue3.0以及vue2.0响应式的原理的介绍,本文存在纰漏的地方,还请各位大牛多多指教ο(=•ω<=)ρ⌒☆

注意:vue3.0兼容vue2.0 vue版本升级之后不需要更改关于vue部分的代码,但是项目中使用的相关的插件就不一定了~

1. 创建vue3.0项目的方法

(1)使用vite

npm init vite-app 项目名
cd 项目名
npm run dev

使用这种方式的优缺点:
 ① 创建速度快,不通过webpack编译

 ② 还需要自己安装vue-routervuex (vue-router以及vuex都要相应的升级为4.0版本)

(2)利用vue-cli

npm install -g @vue/cli
vue create 项目名
cd 项目名
vue add vue-next //重点 执行这行,会把2.0代码改为3.0的, vue-router, vuex会变成4.0的
npm run serve

介绍完如果安装vue3.0,接下来,咱们就正式进入咱们今天的重点了~
2.相比于vue2.0vue3.0的新变化

1、main.js,新增createApp方法

// vue2.0
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './App.scss'

new Vue({
   el: '#app',
   router,
   store,
   template: '<App/>',
   components: { App }
 })




// vue3.0
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './App.scss'

const app = createApp(App)
app.use(router).use(store).mount('#app');

注意: 由于vue3.0 使用的是 import {createApp} from 'vue' 而不是像vue2.0import Vue from 'vue'。因此之前使用的ui框架以及第三方包可能会因为不支持vue3.0而报错。

2、template模板

vue2.0template只支持单一根节点,在vue3.0里可以使用多个根节点

<template>
	<!-- vue3.0组件的根节点可以有多个,或者使用<Fragment> 空标签 -->
	<div class="login"></div>
	<div class="main"></div>
	<div></div>
</template>

3、Composition API

vue2.0里我们都把.vue文件里的js部分叫做Options API, 而在3.0里变为Composition API

注:Composition API 里有vue3.0的新增的主要新特性:

(1)一个全新的属性 setup ,这是一个组件的入口,让我们可以运用 Vue3.0 暴露的新接口,它运行在组件被实例化时候,props 属性被定义之后,实际上等价于 Vue2.0 版本的 beforeCreateCreated 这两个生命周期,setup 返回的是一个对象,里面的所有被返回的属性值,都会被合并到 Vue2.0render 渲染函数里面,在单文件组件中,它将配合 模板的内容,完成ModelView之间的绑定,在未来版本中应该还会支持返回 JSX 代码片段。

(2)setup函数的第一个参数 props 是父组件传进来的值,在 Vue2.0 中我们可以使用 props 属性值完成父子通信,在这里我们需要定义 props 属性去定义接受值的类型,然后我们可以利用 setup 的第一个参数获取 props 使用。

(3) setup 函数的第二个参数context是一个上下文对象,这个上下文对象中包含了一些有用的属性,这些属性在 Vue2.0 中需要通过 this 才能访问到,在 vue3.0 中,访问他们变成以下形式:

context.parent--> this.$parent 

context.root--> this 

context.emit-->this.$emit 

context.refs-->this.$refs 

context.slots --> this.$slots

程序执行setup时,组件尚未被创建,因此能访问到的有用属性有: root、parent、refs、attrs、listeners、isServer、ssrContext、emit 于此同时 data、computed、methods等是访问不到的.

(4)setup()不单可以return 对象,还可以返回方法。

(5)利用watchEffect可以监听props。

// 父组件
<template>
	<Child val="测试"/>
</template>
<script>
	import {setup} from 'vue';
    import Child from './Child';
	export default {
        name: 'Parent',
        components: {
            Child
        },
		setup(props, ctx) {
            console.log(ctx); // 在setup()中无法访问到this
            console.log(this); // undefined
		}
	}
</script>

// 子组件 Child
<template></tempalte>
<script>
    import {setup, watchEffect} from 'vue';
    export default {
        name: 'Child',
        // props: ['val'], // 跟vue2.0相同 也可以采用对象形式
        props: {
            val: String
        },
        setup(props, context) {
            console.log(props); // 在这里可以获取父组件传过来的属性值 
            watchEffect(() => { // 利用watchEffect监听props 
                console.log(props.val); // 首次以及props改变才会执行这里的代码
            })
            return { // setup 返回的对象/方法  可以在模板中被访问得到
            }
        }
    }
    </script>

(6)vue2.0 里数据都是在data里定义, 而在vue3.0可以使用reactive, ref

① ref 一般用于定义单一基本数据类型,vue官网上也提到 在对象的内部包装可能看起来没有必要,但这是保持js中不同数据类型行为统一所必需的,因为number以及string等基本类型是通过值传递而不是引用传递的。

② reactive它主要是处理你的对象, 经过Proxy的加工后变为一个响应式的对象,类似于 Vue2.0 版本的 data 属性,需要注意的是加工后的对象跟原对象是不相等的,并且加工后的对象属于深度克隆的对象。

(7)toRefs() 可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据,配合 v-model 指令能完成数据的双向绑定,在开发中非常高效。

<template>
	<div @click="increament">count is {{count}}</div>
	<div>{{state.data}}</div>
</template>
<script>
	import {setup, reactive, toRefs} from 'vue';
	export default {
		setup(props, context) {
			let count = ref(0);
			consloe.log(count.value); // 0,内部获取时,需要用.value来获取
			console.log(isRef(count)); // true isRef()用来判断是否是ref对象
		const state = reactive({
			name: 'xhuawu'
		})
		function increament () {
			count += 1;
		}
		return { // 定义的变量,函数等都要return出来
			count, // 由ref返回的一个响应式对象
			increament,
             // ...state, // 直接返回state 数据是非响应式的,MV单向绑定
            // toRefs包装后返回state 数据是响应式的 MVVM双向绑定
            ...toRefs(state)
		};
		}
	}
</script>

(8)watch() 函数用来监视某些数据项的变化,从而触发某些特定的操作,使用之前还是需要按需导入,监听 searchValue的变化,然后触发回调函数里面的逻辑,也就是监听用户输入的检索值,然后触发回调函数的逻辑把 searchValue 值存进我们创建 store 对象里面,方面后面和 Panel.vue 列表组件进行数据通信:

  import { reactive, watch } from "vue";
    import store from "../stores";
    export default {
      setup() {
        const state = reactive({
          searchValue: '',
        });
        // 监听搜索框的值
        watch(
          () => {
            return state.searchValue;
          },
          () => {
            // 存储输入框到状态 store 中心,用于组件通信
            store.setSearchValue(state.searchValue);
          }
        );
        return {
          ...toRefs(state)
        };
      }
    };

(9)computed()Vue2.0 的使用方式很相近,同样需要按需导入该模块 , 计算属性分为两种,只读 以及可读可写

<tempalte>
	<div>{{addCount}}</div>
	<div>{{addCount2}}</div>
</tempalte>

<script>
	import {setup, reactive, computed} from 'vue';
	export default {
		setup(props, context) {
			const count = ref(0);
			const addCount = coomputed(() => count.value + 1); // 只读
			const addCount2 = computed(() => {
				get: () => count.value + 1,  // 取值函数
				set: (value) => count.value = value; // 赋值函数
			})
			return {
				count,
				addCount,
				addCount2
			}
		}
	}
</script>

(10)生命周期lifecycle hooks

① vue2.0的生命周期的钩子函数有: beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed

② vue3.0的生命周期在vue2.0的基础上做了些修改, 新版本的都是以onXxx()函数注册使用,其中 beforeCreatecreated 这两个函数可以由setup()代替

    import { onMounted, onUpdated, onUnmounted } from "@vue/composition-api";
    export default {
      setup(props, ctx) {
         // `props` 属性被定义之后,实际上等价于 `Vue2.0` 版本的 `beforeCreate` 和 `Created` 这两个生命周期
        const loadMore = () => {};
        onMounted(() => {
          loadMore();
        });
        onUpdated(() => {
          console.log('updated!')
        })
        onUnmounted(() => {
          console.log('unmounted!')
        })
        return {
          loadMore
        };
      }
    };

新旧版本生命周期对比 :

  • beforeCreate --> use setup()

  • created --> use setup()

  • beforeMount --> onBeforeMount

  • mounted --> onMounted

  • beforeUpdate --> onBeforeUpdate

  • updated --> onUpdated

  • beforeDestory --> onBeforeUnmount

  • `destoryed --> onUnmounted

  • errorCaptured --> onErrorCaptured

同时vue3.0 还提供了2个全新的生命周期帮助我们去调试代码:

  • onRenderTracked

  • onRenderTriggered

(11)vue-router

vue3.0中对应采用的vue-router以及vuex的版本都是4.0版本,vue-router4 添加了createRouter() 来创建router ,路由模式也有对应的函数 createWebHistory()<History模式> 和 createWebHashHitory()<hash模式>

/ <router-link> , <router-view>这两个标签没有变化
// 编程时导航有了些变化
    <script>
    	import {setup} from 'vue';
        import { useRouter, UseRoute} from 'vue-router';
        export default {
            setup() {
                const router = useRouter();
                router.push('/login')
            }
        }
    </script>

(12)vuex4

vuex4和之前的用法基本一致,有所不同的是创建时需要调用vuex.createStore()

 import Vuex from 'vuex';
    export default {
        state: {
            userInfo: {}
        },
        mutation: {
            setUserInfo(state, info) {
                state.userInfo = info;
            }
        },
        actions: {}
    }

获取数据 :
 

import { useStore } from 'vuex'
let store = useStore()
state.userInfo = store.state.userInfo

酱酱酱~目前vue3.0的新特性就这些,后期有更新的话,继续补充,嘻嘻(o゜▽゜)o☆

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值