Vue3.0 beta也出来一段时间了,最近一直在看react,对于vue3.0倒是没怎么关注,想着等正式版出来再说,不过最近事情不多,还是抽出了一点时间,试了一下新版的Vue3.0,不得不说,改动还是有的,对于初上手的人可能没有之前友好
vue3.0亮点
尤大官方的直播也有一些介绍
但是毕竟还是beta版,配套的支持还不多,生产环境暂时还是不要使用为好

安装

使用vue-cli创建项目,我用的是4.4.6版本,不是最新版的建议更新一下

vue create vue-next-test

这是我个人创建项目启用的一些配置,这个随个人喜好变更,把vuex和router启用了就行
在这里插入图片描述
创建完成后这时项目还是2.x版本的,需要通过插件升级的方式来升级至3.0

cd vue-next-test
vue add vue-next

该插件会完成以下操作
安装 Vue 3.0 依赖
更新 Vue 3.0 webpack loader 配置,使其能够支持 .vue 文件构建
创建 Vue 3.0 的模板代码
自动将代码中的 Vue Router 和 Vuex 升级到 4.0 版本,如果未安装则不会升级
自动生成 Vue Router 和 Vuex 模板代码

安装完成之后,项目就升级至3.0 beta版本了
项目整体的结构并没有太大的变化
在这里插入图片描述

路由

路由的声明方式发生了一些改变,但是基本的使用和配置是没有变的

import { createRouter, createWebHashHistory } from 'vue-router';
import Home from "../views/Home.vue";

const routes = {
      {
    path: "/",
    name: "Home",
    component: Home,
  },
  {
    path: "/about",
    name: "About",
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/About.vue"),
  }
}
const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

vuex

vuex和路由类似,也是声明的方式发生了一些变化,但是使用的方式基本是没有变的

  import Vuex from 'vuex'

  export default Vuex.createStore({
    state: {
    },
    mutations: {
    },
    actions: {
    },
    modules: {
    }
  });

ref和reative

在页面的script内部的变化就比较大了,熟悉的data和methods都没有了,取而代之的是ref和reactive

// script标签内部基本结构
import { ref, reactive } from "vue";
export default {
  setup() {
	...
    return {
		...
    };
  }
};

所有的数据和方法写在setup内部,通过ref和reactive创建响应式的属性
要注意vue3.0不再使用this,直接使用声明时候的变量名来访问
ref
通过ref方法传入数据的初始值,然后通过value属性来获取或改变数据的值
方法也直接写在setup内
要记得将生命的数据和方法return

<template>
  <div>{{helloWorld}}</div>
</template>
<script>
import { ref } from "vue";
export default {
  setup() {
	const helloWorld = ref('Hello World')
    const sayHello = ()=>{
    	console.log(helloWorld.value)
    	// 'Hello World'
    }
    return {
		helloWorld,
        sayHello
    };
  }
};
</script>

reactive

<template>
  <div>{{data.helloWorld}}</div>
</template>
<script>
import { reactive } from "vue";
export default {
  setup() {
	const data = reactive({
      	helloWorld: "Hello World",
   	});
    const sayHello = ()=>{
    	console.log(data.helloWorld)
    	// 'Hello World'
    }
    return {
		data,
        sayHello
    };
  }
};
</script>

两种方法达到的效果是一样的,如果习惯使用多个变量,就用ref,如果习惯将多个变量封装至一个对象的属性中,就使用reactive,不过一定要记得把声明所有变量和方法return
不过这个地方如果把data换成state,就有了那么点react的味道了不是么…

计算属性computed

计算属性现在通过computed方法来实现,使用和之前的区别不大

import { ref,computed } from "vue";
export default {
  setup() {
	const person = ref({
        name:'xz',
        gender:'man'
    })
    const sayHello = computed(()=>{
      if (person.value.gender == "man") {
        return `你好${person.value.name}先生`
      }
      else{
        return `你好${person.value.name}女士`
      }
    })
    return {
		state,
        sayHello
    };
  }
};

watch侦听器

侦听器和计算属性类似,通过watch方法来实现
watch方法提供两个方法作为参数,第一个返回要监听的数据,第二个是回调

import { ref,watch } from "vue";
export default {
  setup() {
	const num = ref(1)
	const add = ()=>{
        num.value++
    }
    watch(()=>num.value,val=>{if(val>10){
      alert('太大了')
      num.value = 1
    }})
    return {
		num,
        add
    };
  }
};

filters过滤器

根据官方的报错提示,似乎可以确定,filters应该是凉了
在这里插入图片描述
只能用computed了

上下文ctx

vue3.0中不再使用this,所以获取路由和store需要通过getCurrentInstance获取上下文来获取

import { ref,getCurrentInstance  } from "vue";
export default {
  setup() {
	const { ctx } = getCurrentInstance()
    return {
		ctx
    };
  }
};

这个ctx可以用来获取当前页面的router和store
vuex

// store
import Vuex from 'vuex'

export default Vuex.createStore({
  state: {
    data:'data in store'
  },
  mutations: {
    changeData(state,newData){
      state.data=newData
    }
  },
  actions: {
  },
  modules: {
  }
});
// 页面script
import { ref,getCurrentInstance  } from "vue";
export default {
  setup() {
	const { ctx } = getCurrentInstance()
    console.log(ctx.$store.state.data)
    // 'data in store'
 	ctx.$store.commit('changeData','data commit to store')
    return {
		ctx
    };
  }
};

获取还是$store.state,操作还是commit,不过不能直接用this,需要使用ctx

路由

// router
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from '../views/Home.vue'

const routes = [
{
  path: '/',
  name: 'Home',
  component: Home
},
{
  path: '/about/:id',
  name: 'About',
  // route level code-splitting
  // this generates a separate chunk (about.[hash].js) for this route
  // which is lazy-loaded when the route is visited.
  component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router
// 页面 /about/000001
<template>
  <div>
    <h1 @click="ctx.$router.push('/')">This is an about page</h1>
  </div>
</template>

<script>
import { ref, getCurrentInstance } from "vue";
export default {
  setup() {
    const { ctx } = getCurrentInstance();
    console.log(ctx.$router.currentRoute.value.params.id);
    // '000001'
    return {
      ctx
    };
  }
};
</script>

还是通过$router来获取和操作路由,不过也是需要通过ctx来获取

生命周期

生命周期不再像之前可以直接写,需要引入,有点类似自助餐,要哪个拿哪个

<template>
  <div>
    <p>{{data}}</p>
    <input type="text" v-model="data" />
  </div>
</template>

<script>
import {
  ref,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted,
  onErrorCaptured
} from "vue";
export default {
  setup() {
    const data = ref("");
    // beforeCreate和created没有了,如果需要的话内部的方法可以直接放在setup内
    console.log('------setup------')
    onBeforeMount(() => {
      console.log("------onBeforeMount------");
    });
    onMounted(() => {
      console.log("------onMounted------");
    });
    onBeforeUpdate(() => {
      console.log("------onBeforeUpdate------");
    });
    onUpdated(() => {
      console.log("------onUpdated------");
    });
    onBeforeUnmount(() => {
      console.log("------onBeforeUnmount------");
    });
    onUnmounted(() => {
      console.log("------onUnmounted------");
    });
    onErrorCaptured(() => {
      console.log("------onErrorCaptured------");
    });
    return {
      data
    };
  }
};
</script>

进入该页面,在输入框输入一些文字,然后退出该页面,生命周期执行如下
在这里插入图片描述

未发生改变的部分

vue3.0对于vue的一些指令,如v-model,v-if,v-for这些并没有做出改变,依旧可以很方便的进行数据绑定,列表渲染,条件渲染,样式部分也没有变化,依旧可以用lang属性来指定使用的预编译语言,scoped属性来使样式文件局部有效

总结

从data和methods到setup,对习惯2.x版本的人来说确实是有一些不习惯,不过存在即合理嘛,目前还是测试版,不确定后续的正式版会不会有改变,还是要保持关注,等一手官方的正式文档吧

Logo

前往低代码交流专区

更多推荐