阅读 108

Vue3新体验

前段时间,尤大牛将Vue3正式发布,至此,我们的前端的三大框架都进入了新的时代,那么Vue3的发布带来了哪些新的变化和语法呢,作为一名前端开发者,我也想结合自己的实际应用,做一个分享,下面请看目录和示例:

目录

  • Vue3项目创建
  • 实例化
  • Composition Api
  • 组件通信
  • 生命周期

一. vue3项目创建

安装vue3脚手架,打开命令行窗口,执行命令:

    npm install -g @vue/cli@next
    npm update -g @vue/cli	    // 如果你已经安装过vue的cli,用此命令更新到最新版本
复制代码

查看安装结果,在命令行窗口,继续运行:

	vue -V
    
复制代码

创建项目

	vue create study-vue3-demo
复制代码

这里是选择项目配置项,有vue2的,有vue3的,我们选择最后一个自定义的 Manually select features 在这里使用空格键选择你需要的模块,Router,Vuex,这两个不用说,必要的,其它啥单元格测试,EsLinter,看你个习惯去安装,选择完成之后回车,后面还有一系列Yes or No的选择,就是根据你的需要选择就OK了: 上面的选项选择完后,就是安装依赖了,至此,我们的vue3项目,使用vue3的官方脚手架,创建项目成功。整个项目创建过程,和vue2最明显的不同就是,vue2选择完配置项后是不会安装依赖包的,需要在进入到项目文件里去npm install,而vue3是默认安装。这个时候我们可以进入项目文件夹里,打开cmd,运行: npm run serve,我们的项目就启动起来了。

二. 实例化

打开我们项目main.js文件,我们可以看到vue3一些变化:

  1. 使用createApp函数创建vue实例,
  2. 使用createRouter函数创建vue路由实例,
  3. 使用``
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import './assets/reset.css'
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')
复制代码

三. Composition Api

Composition Api是整个vue3核心。在vue2.x的版本,采用的是options的设计,在vue3 composition的里,所有的代码逻辑都放在了setup函数里,所需要的模块也都是按需引入,并且setup函数里也不在有this;

  1. reactive & ref,定义响应式数据,这两者的区别在于reactive是用来定义对象型数据的响应式,ref是用来定义基础数据的响应式。
	import {reactive, ref, toRefs} from 'vue'
    export default{
    	setup(){
        	const state = reactive({	// 定义对象响应式数据
            	obj: {id: 1, name: 'tom', hooby: 'sing'},
                arr: ['red', 'yellow', 'blue', 'green']
            })
            const num = ref(99)		// 定义基础类型响应式数据
            
        	return{
            	...toRefs(state),
                num
            }
        }
    }
    
复制代码
  1. computed计算属性,和2.x语法基本一致,同样支持get,set的对象语法;
import {reactive, computed, toRefs} from 'vue'
export default {
	setup(){
    const state = reactive({
    	totalNum: computed(() => {	// 默认get语法
        	return 2 + 2
        }),
        color: computed({	// 对象语法
        	get(){
            	return 'red'
            },
            set(newVal){
            	if (newVal !== 'red') {
                	return 'red'
                } else {
                	return 'bule'
                }
            }
        })
    })
    	return {
        	...toRefs(state)
        }
    }
}
复制代码
  1. watch & watchEffect监听属性,watch的变化,一是不支持'obj.key.key'的写法了,二是支持监听多个对象,同时新增了个watchEffect这个属性,watchEffect这个属性监听时不需要指定的监听对象,加载属性所在页面,该监听属性就立即执行;
import {reactive, watch, watchEffect, toRefs} from 'vue'
export default {
    setup() {
        const state = reactive({
            pageName: 'watch study',
            num2: 0,
            num1: 0,
        })
        
        watch(() => state.color, (newVal, oldVal) => {  // 监听单个数据
            console.log('newVal', newVal)
            console.log('oldVal', oldVal)
        } )
        const stopWatch = watchEffect(() => {   // 监听单个属性,不需要指定监听属性
            console.log('newVal', state.num2)
            console.log('oldVal', state.num2)
        })

        watch([() => state.num1, () => state.num2], ([newNum1, newNum2], [oldNum1, oldNum2]) => { // 监听多个数据
            console.log('new num1', newNum1, 'old num1', oldNum1)
            console.log('new num2', newNum2, 'old num2', oldNum2)
        })
        
        return {
        	...toRefs(state)
        }
    }
复制代码
  1. 生命周期 onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onErrorCaptured,vue2的beforeCreate和created替换成了setup;

	onBeforeMount(() => {
            console.log('component is onBeforeMount')
        })
        onMounted(() => {
            console.log('component is onMounted')
        })
        onBeforeUpdate(() => {
            console.log('component is onBeforeUpdate')
        })
        onUpdated(() => {
            console.log('component is onUpdated')
        })
        onBeforeUnmount(() => {
            console.log('component is onBeforeUnmount')
        })
        onUnmounted(() => {
            console.log('component is onUnmounted')
        })
        onErrorCaptured(() => {
            console.log('component is onErrorCaptured')
        })
复制代码
  1. getCurrentInstance, 返回自身实例,在vue3的setup函数里,this被取消了,定义成了undefined,但是提供了getCurrentInstance方法,该方法可以返回当前模块实例。
	import {getCurrentInstance} from 'vue'
    export default{
    	setup(){
        	const $this = getCurrentInstance()	// 获取当前实例
        	return {}
        }
    }
复制代码

在控制台输出,打开ctx这个属性,就能看见你定义的数据和方法,包括inject注入和mixin混入的数据和方法了

  1. readonly只读属性,通过字面意思的理解,就是readonly返回的数据就是只读,不可以操作。
import {readonly} from 'vue'
export default {
	setup() {
    	const pageName = readonly('页面名称')
    	return {
        	pageName	// 模板里使用就可以了
        }
    }
}
复制代码
  1. provide/Inject注入;父辈组件向子辈组件,孙子辈组件传递数据的一种方式。该方法可以很好的用来封装我们的私有公共方法,通过provide注入传递给所有子组件使用。
// 父辈组件
import {provide} from 'vue'
export default {
	setup() {
    	provide({	// 注入数据
        	'testProvide': 'testProvide',
        })
    }
}
复制代码
// 子辈组件
import {inject} from 'vue'
export default {
	setup() {
    	let testProvide = inject('testProject')	// 获取父辈组件注入的数据
    }
}
复制代码

组件通信

vue3组件通信略有变化,主要是体现在应用上的改变。先说第一种最常用的传值方式,props传值:

` // 父组件使用子组件方式不变,传递值的方式同样还是使用 v-bind方式,重点是子组件获取props的变化 // 因为vue3里的this不在是像vue2里的组件实例对象,你要使用传入的props的值,就依靠setup的第一个参数

     props: {
         testParams: {
             type: Object,
             default: {}
         }
     },
     setup(props, context) {// 子组件setup函数的第一个参数,就是props传入的值
         let state = reactive({
             name: '子组件',
         })
         let methods = {
        // 子组件的方法里获取传入的props,原来的vue2就是this.testParams,现在采用setup的第一个参数
                 testFn() {
                 console.log(props.testParams)
             }
         }
     }
 
复制代码

`

父组件获取子组件实例的变化,在vue2当中,获取子组件实例直接this.$refs.child就搞定了,在vue3当中,略有变化:

`

 import {ref, reactive, toRefs} from 'vue'  // 必须引入ref
 
 setup() {
     // 注意 这个child变量,必须和子组件上的ref的值保持一致
      const child = ref()   //  这个就是获取到子组件的实例,child变量必须在setup返回的对象中注册
      
      function testFn(){
           console.log(child.value.name)// 使用,假设这个child子组件的data里有name这个数据,那么你就需要使用这个格式
      }
      
      return {
          child,
          testFn
      }
 }
 
复制代码

`

总结概述

vue3整体的核心变化在于compostiton Api的改变,所有的数据方法都集成在setup函数体里,其他一些细节的变化都是应用层使用的变化,后续在补充其他应用上的变化。

文章分类
前端
文章标签