Vue3
vue3.0.0-alpha.0至今天已经发布近两年了,从当时各大开发人员请求支持TypeScript,到现在script已经全面支持Ts语法。再从去年的setup语法糖试用到现在setup语法已经提正式版本,vue越来越深得开发人员的亲赖
这边文章将讲述vue3的基本使用以及ts语法
我这里的版本
"vue": "^3.0.5",
"vue-router": "^4.0.10",
"vite": "^2.4.3",
"vuex": "^4.0.2"
基本语法
1.响应式变量ref
这里简单实现一个active功能
<!-- template -->
<div :class="active === 1 ? 'active-color' : ''"></div>
**注意:**所有在setup函数里面定义的且在template里面需要使用到的,都需要return返回,包括变量,函数
// script
setup() {
import { ref } from 'vue'
// js语法
const active = ref(0)
// ts语法
const active = ref<number>(0)
// 修改active的值
active.value = 1
// 暴露active在tamplate才能使用
return { active }
}
2.响应式变量reactive
<!-- template -->
<div>{{ user.name }}</div>
<div>{{ user.age }}</div>
强调:reactive里面的元素需要响应式时,要进行toRefs()转换,下面会有详细用法
// script
import { reactive } from 'vue'
// reactive和ref一样,作用为定义变量,不过区别为reactive是一个对象且这个对象的属性并不是响应式的
// 当变量多的时候,我们定义ref就相当麻烦,这时我们需要使用reactive
// 注意:reactive的属性并不是响应式的,即name和age并不是响应式的
// js用法
setup() {
const user = reactive({
name: 'Alice',
age: 12,
})
// ts用法
interface User{
name:string;
age:number;
}
const user = reactive<User>({
name: 'Alice',
age: 12,
})
// 修改值
user.name = 'Marry'
user.age = 16
return { user }
}
由于上面name和age并不是响应式的,我们要把它改为ref对象,才是响应式,官方提供了方法toRefs()
// script
setup() {
import { toRefs } from 'vue'
const userRefs = toRefs(user)
// 这时user.name和user.age才是响应式
// 修改值时应写为
userRefs.name.value = 'Marry'
userRefs.age.value = 16
return { userRefs }
}
优化reactive
但是我们一般在代码都不会这样写。简略写法如下
// script
setup() {
import { toRefs } from 'vue'
// 提示...为ES6解构语法
return { ...toRefs(user) }
}
这时template中可直接使用,也不用加前缀user
<!-- template -->
<div>{{ name }}</div>
<div>{{ age }}</div>
3.获取dom元素
<!-- template -->
<div class="chart" ref="myChartEle"></div>
// script
setup() {
// js语法
const myChartEle = ref(null)
// ts语法
const myChartEle = ref<HTMLElement | null>(null)
onMounted(() => {
console.log(myChartEle.value)
// 输出为<div class="chart"></div>
})
return { myChartEle }
}
注意:myChartEle和dom元素中的ref必须相同
4.事件
我们简单实现一个点击元素数字自加的功能
<!-- template -->
<div @click="handleCountClick">{{ count }}</div>
// script
setup() {
// js语法
const conut = ref(0)
// ts语法
const count = ref<number>(0)
const handleCountClick =() => {
count++
}
return { count, handleCountClick }
}
vue-router
基础配置
// src/router/index
// createRouter创建一个路由,传入一个对象,对象里面两个属性({history: 路由模式<hash|history>, routes[路由配置项]})
// createWebHashHistory 这里选择hash路由
// RouteRecordRaw ts语法支持
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
// js语法
const constantRoutes = [
{
path: '/',
component: () => import('../layout/index.vue'),
children: [
{ path: '/', component: () => import('../views/home/home.vue') },
{ path: '/login', component: () => import('../views/login/login.vue') }
]
}
]
// ts语法
const constantRoutes: Array<RouteRecordRaw> = [
// ...
]
const router = createRouter({
history: createWebHashHistory(),
routes: constantRoutes
})
export default router
// src/main.ts
import router from './router/index'
const app = createApp(App)
app.use(router).mount('#app')
基本使用
这里我们简单实现一个获取当前路径在路由中属于第几个(导航栏active中经常用到)
import { useRouter } from 'vue-router'
setup: () => {
const router = useRouter()
const active = router.getRoutes().map((item, index) => {
if(item.path === router.currentRoute.value.path){
return index
}
})
}
vuex
基础配置
// src/store/index
import { createStore } from 'vuex'
// js写法
const store = createStore({
state(){
return {
userIsLogin: flase
}
},
mutations: {
CHANGE_USER_LIGIN(state, payload){
state.userIsLogin = payload
}
},
actions: {
sendChangeUserLogin({ commit }, payload){
commit('CHANGE_USER_LIGIN', payload)
}
}
})
// ts写法
interface State {
userIsLogin: boolean
}
const store = createStore<State>({
state(){
return {
userIsLogin: flase
}
}
// ...写法同上
})
export default store
// src/main.ts
import store from './store/index'
const app = createApp(App)
app.use(store).mount('#app')
基本使用
import { useStore } from 'vuex'
setup(){
const store = useStore()
store.dispatch('sendChangeUserLogin', true)
console.log(store.state.userIsLogin)
}
setup语法糖
正常我们写一个script是这样的
<template>
<div @click="handleCountClick">{{ count }}</div>
</template>
<script lang="ts">
// defineComponent为语法提示
import { defineComponent, ref } from 'vue'
setup() {
const count = ref<number>(0)
const handleCountClick = () => {
count++
}
return { count, handleCountClick }
}
</script>
如果我们使用setup是这样的
<template>
<div @click="handleCountClick">{{ count }}</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const count = ref<number>(0)
const handleCountClick = () => {
count++
}
</script>
当我们就使用了一个函数,我们代码量减少了5行,当代码多起来了,优化可想而知
当然,要实现一个项目的话,仅仅这些还不够,比如watchEffect,生命周期等等,这些就需要小伙伴们自己探索