快速搭建Vue3.0项目
1,使用vite(推荐使用,比webpack更快)
npm i -g create-vite-app
create-vite-app my-project
cd demo
npm i
npm run dev
2,使用vue-cli
npm install -g @vue/cli // 安装cli
之前已经安装过vue-cli的话,可以升级到最新版
npm update -g @vue/cli // 升级vue-cli到最新版
vue -V // 查看vue-cli版本
vue create vue3-test
选择预设配置,这里我们选择人工选择(Manually select features)
选择功能配置,根据自己需要选择,不熟悉TypeScript的同学可以不选TypeScript,Unit Testing也可根据需求选择
下一步,选择 3.x (Preview)
下面这些自己根据需求选择即可,这里不再介绍
vue2.x -> vue3.x
1,mian.ts
- 2.x使用构造函数new Vue(…)创建实例,3.x使用createApp函数创建实例;
- 2.x所有属性方法和设置都绑定到全局Vue对象上,3.x改为绑定到vue实例下,收紧了scope;
- 3.x移除了 Vue.config.productionTip 和 Vue.config.keyCodes 配置属性;
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
createApp(App).use(Antd).use(store).use(router).mount('#app')
2,template模板部分
vue2.0里 template模板里只能有一个根标签, 而3.0可以使用多个根标签
3,Composition API
在vue2.0里我们都把.vue文件里的js部分叫做Function API, 而在3.0里变为Composition API 这里是变化最大的地方
1)setup函数
setup 函数是一个新的Vue组件, 是Composition API 入口
<template>
</template>
<script lang="ts">
import { defineComponent, setup } from 'vue'
export default defineComponent({
setup(props, context) {
//这里的props大家应该知道是啥吧,父组件传的值
// context是什么?
//在setup()里我们不能用this
//所以vue2.0里的 this.$emit, this.$psrent, this.$refs在这里都不能用了。
//context就是对这些参数的集合
//context.attrs
//context.slots
//context.parent 相当于2.0里 this.$psrent
//context.root 相当于2.0里 this
//context.emit 相当于2.0里 this.$emit
//context.refs 相当于2.0里 this.$refs
...
}
})
</script>
<style>
</style>
2)数据声明
vue2.0 里数据都是在data()里声明, 而在3.0里也取消了data(), 引用了Reactive()
:声明单一对象时使用, ref()
:声明单一基础数据类型时使用
注意: 定义的变量,函数都要 return 出来
// vue3.x
<template>
<div class="page-wrapper">
<div>
<span>count 点击次数: </span>
<span>{{ count }}</span>
<button @click="addCount">点击增加</button>
</div>
<div>
<span>num 点击次数: </span>
<span>{{ num }}</span>
<button @click="addNum">点击增加</button>
</div>
</div>
</template>
<script>
import { reactive, ref, toRefs } from 'vue'
export default {
name: 'Test',
setup () {
const state = reactive({
count: 0
})
const num = ref(0)
const addCount = function () {
state.count++
}
const addNum = function () {
num.value++ // 在模板中可以直接写为{{num}},在js内部获取时需要用.value来获取
}
return {
...toRefs(state), // 把state转为响应式的ref,不然template里获取不到
num,
addCount,
addNum
}
}
}
</script>
3)计算属性computed
2.x和3.x中的computed都支持getter和setter,写法一样,只是3.x中是组合函数式
// vue3.x
import { reactive, ref, toRefs, computed } from 'vue'
export default {
name: 'Test',
setup () {
const state = reactive({
count: 0,
double: computed(() => {
return state.count * 2
})
})
const num = ref(0)
const addCount = function () {
state.count++
}
const addNum = function () {
num.value++
}
// only getter
const totalCount = computed(() => state.count + num.value)
// getter & setter
const doubleCount = computed({
get () {
return state.count * 2
},
set (newVal) {
state.count = newVal / 2
}
})
// doubleCount.value = 10 //赋值方法
return {
...toRefs(state),
num,
totalCount,
doubleCount,
addCount,
addNum
}
}
}
4)监听属性watch & watchEffect
- 3.x和2.x的
watch
一样,支持immediate
和deep
选项,但3.x不再支持'obj.key1.key2'
的"点分隔"写法; - 3.x中
watch
支持监听单个属性,也支持监听多个属性,相比2.x的watch
更灵活; - 3.x中
watchEffect
方法会返回一个方法,用于停止监听; watch
跟watchEffect
不同的地方在于,watchEffect
注册后会立即调用,而watch
默认不会,除非显示指定immediate=true
,并且watchEffect
可以停止监听
<template>
<div>{{count}}</div>
</template>
<script>
import { Reactive } from 'vue'
export default {
setup(props, context) {
let count1 = ref(0)
let state = reactive({
count2: 0,
midObj: {
innerObj: {
size: 0
}
}
)
//监听reactive类型
watch(
() => state.count2, //这里是你要监听的数据
(count, preCount) => { //count新值, preCount旧值
console.log('') //这里是监听数据变化后执行的函数
}, {lazy: false}//在第一次创建不监听)
//监听ref类型
watch(count1, (count, preCount) => { //count新值, preCount旧值
console.log('') //这里是监听数据变化后执行的函数
})
// immediate deep
watch(
() => state.midObj,
(count, preCount) => {
console.log('')
}, {
immediate: true, // 注册后会立即调用
deep: true // 深度监听
}
return {
count
...toRefs(state)
}
}
}
</script>
<style>
</style>
5)生命周期钩子
Vue2.0的里我们常见的生命周期函数有8个,分别为
beforCreate, created, beforMount, mounted,
beforUpdate, updated, beforDestroy,desroyed
Vue3.0的生命周期函数在2.0的基础上有了些修改
beforCreate, created,这两个函数由setup()来代替
beforMount => onBeforMount
mounted => onMounted
beforUpdate => onBeforUpdate
updated => onUpdate
beforDestroy => onBeforUnmount
desroyed => onUnmounted
<script>
import { setup, onBeforMount, onMounted, onBeforUpdate, onUpdate, onBeforUnmount, onUnmounted} from 'vue'
export default {
setup(props, context) {
onBeforMount(() => {
//
});
onMounted(() => {
//
});
onBeforUpdate(() => {
//
});
onUpdate(() => {
//
});
onBeforUnmount(() => {
//
});
onUnmounted(() => {
//
});
}
}
</script>
vue-router@4.x & vuex@4.x
vue2.x使用的是vue-router@3.x
和vuex@3.x
,vue3.x使用的是vue-router@4.x
和vuex@4.x
1,vue-router4 与 vue-router3的区别
1)先看创建上的区别
vue-router 4 添加了 createRouter
方法来创建router,路由的模式也是有对应的函数:createWebHistory()
为History模式, createWebHashHistory
()为Hash模式
2)路由跳转
vue2.x使用路由选项redirect
设置路由重定向,vue3.x中移除了这个选项,将在子路由中添加一个空路径路由来匹配跳转
// vue2.x router
[
{
path: '/',
component: Layout,
name: 'WebHome',
meta: { title: '平台首页' },
redirect: '/dashboard', // 这里写跳转
children: [
{
path: 'dashboard',
name: 'Dashboard',
meta: { title: '工作台' },
component: () => import('../views/dashboard/index.vue')
}
]
}
]
// vue3.x router
[
{
path: '/',
component: Layout,
name: 'WebHome',
meta: { title: '平台首页' },
children: [
{ path: '', redirect: 'dashboard' }, // 这里写跳转
{
path: 'dashboard',
name: 'Dashboard',
meta: { title: '工作台' },
component: () => import('../views/dashboard/index.vue')
}
]
}
]
<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>
2,vuex4 与 vuex3的区别
1)创建实例
vuex4和之前用法基本一样,就是创建的时候有写不通,需要调用Vuex.createStore()
这个api
// vue2.x vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
getters: {},
modules: {}
}
// vue3.x vuex
import Vuex from 'vuex'
export default Vuex.createStore({
state: {},
mutations: {},
actions: {},
getters: {},
modules: {}
})
2)获取store
// vue2.x vuex
import { mapState, mapGetters } from 'vuex'
export default {
computed: {
...mapState(['common']),
...mapGetters(['app']),
userId() {
return this.app.userId
}
}
}
// vue3.x vuex
import { setup, computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup () {
const store = userStore()
const userId = computed(() => store.state.app.userId)
return {
userId
}
}
}