Vue3出来也一段时间了,最近公司有个项目须要重构,用Vue3重构了一遍,开发体验上来说我的以为改变其实不是特别大,可是必须吹一下vite是真的快,在开发过程当中遇到的问题也很多,特别是部署的时候,没仔细看文档就要GG了,废话很少说,直接上正题。javascript
本文主要讲Vue2转到Vue3的一些相关对比,关于好比ref,reactive这些基础知识的文档有不少,能够看下其余大佬的相关文档大概十分钟就能够上手了。html
<template>
<panel class="size-wrapper"> 这是主页 <template #footer class="dialog-footer"> <el-button type="primary" @click="onConfirmClick()">知道了</el-button> </template> </panel>
</template>
<script setup> import { ref, reactive, watch } from 'vue' import Panel from '@/components/Panel.vue' </srcipt>
复制代码
// vue2
data() {
return {
loading: false,
tableData: []
}
},
methods:{
getList(){
this.loading = true
this.tableData = []
this.loading = false
}
}
复制代码
// vue3
<script setup>
import { ref, reactive } from 'vue'
let state = reactive({
loading: false,
tableData: []
})
function getList(){
state.loading = true
state.tableData = []
state.loading = false
}
</srcipt>
复制代码
// vue2
watch: {
tableData (val) {
this.tableData2 = []
}
},
computed: {
price () {
return this.price1 * 20
}
}
复制代码
// vue3
<script setup>
import { ref, reactive,watch,computed,watchEffect } from 'vue'
let price = ref(10)
let price1 = ref(20)
let state = reactive({
price1: 10,
price2: 20,
price3: 0
})
// 监听ref属性
watch(price1, (newVal,oldVal) => {
console.log(newVal,oldVal)
})
// 监听多个ref属性
watch([price, price1], ([newPrice, newPrice1], [prevPrice, prevPrice1]) => {
console.log(newPrice, newPrice1)
})
// 监听reactive属性
watch(() => state.price1, (newVal,oldVal) => {
console.log(newVal,oldVal)
})
watch(() => state, (newVal,oldVal) => {
console.log(newVal,oldVal)
})
const price = computed(() => price1 * 20)
const price2 = computed(() => state.price2 * 20)
// watchEffect
// 官方描述:在响应式地跟踪其依赖项时当即运行一个函数,并在更改依赖项时从新运行它
watchEffect(() => {
const {price1,price2} = state
state.price3 = price1 + price2
})
</srcipt>
复制代码
// vue2
<script>
beforeCreate(){}
create(){}
mounted(){}
destory(){}
updated(){}
...
</srcipt>
复制代码
// vue3
<script setup>
import { onMounted,onUpdated,onUnmounted } from 'vue'
onMounted(() => {
console.log('onMounted')
})
onUpdated(() => {
console.log('onUpdated')
})
console.log(created)
</srcipt>
输出 created、onMounted
复制代码
// vue2
<template>
<panel class="size-wrapper" ref="panel"> 这是主页 </panel>
</template>
<script>
mounted(){
console.log(this.refs.panel)
}
</srcipt>
复制代码
// vue3 单个ref
<template>
<panel class="size-wrapper" ref="panel"> 这是主页 </panel>
</template>
<script setup> import { ref, reactive, onMounted } from 'vue' import Panel from '@/components/Panel.vue' // ref传null自动绑定 let panel = ref(null) onMounted(() => { // 因为是ref,须要.value获取 const panelRef = panel.value console.log(panelRef) }) </srcipt>
复制代码
// vue3 多个ref
<template>
<panel1 class="size-wrapper" :ref="el => setRefs(el, 'panel1')"> 这是主页 </panel1>
<panel2 class="size-wrapper" :ref="el => setRefs(el, 'panel2')"> 这是主页 </panel2>
<panel3 class="size-wrapper" :ref="el => setRefs(el, 'panel3')"> 这是主页 </panel3>
</template>
<script setup> import { ref, reactive, onMounted } from 'vue' import Panel from '@/components/Panel.vue' import Pane2 from '@/components/Pane2.vue' import Pane3 from '@/components/Pane3.vue' // 相似react传回调函数 let refs = ref({}) let setRefs = (el, name) => (refs.value[name] = el) onMounted(() => { // 因为是ref,须要.value获取 const panel1Ref = refs.value.panel1 const panel2Ref = refs.value.panel2 const panel3Ref = refs.value.panel3 console.log(panel1Ref,panel2Ref,panel3Ref) }) </srcipt>
复制代码
// 父组件
<template>
<panel class="size-wrapper" ref="panel"> 这是主页 <DescDialog v-model:visible="state.visible" :data="state.data"> </DescDialog> </panel>
</template>
<script setup> import { reactive, onMounted } from 'vue' import Panel from '@/components/Panel.vue' let state = reactive({ visible: false, data: [] }) </srcipt>
复制代码
// 子组件
<template>
<div> <el-dialog title="描述详情" v-model="visible" :show-close="false"> <div v-html="sizeData"></div> <template #footer class="dialog-footer"> <el-button type="primary" @click="onConfirmClick()">知道了</el-button> </template> </el-dialog> </div>
</template>
<script setup> import { defineProps, defineEmit, reactive, useContext } from 'vue' // 用于暴露组件的方法,必定程度上让组件更加清晰把 const { expose } = useContext() defineProps({ visible: { type: Boolean, default: () => false }, data: { type: Array, default: () => [] } }) const emit = defineEmit(['update:visible']) const onConfirmClick = () => { emit('update:visible', false) } expose({ onConfirmClick }) </script>
<style lang="less"> </style>
复制代码
import * as userApi from '@/server/api/user'
export default {
state: {
userInfo: {}
},
mutations: {
setUserInfo(state, data) {
state.userInfo = data
},
clearUserInfo(state, data) {
state.userInfo = {}
},
},
actions: {
async getUserInfo({ commit, state }) {
const res = await userApi.getUserInfo()
commit('setUserInfo', res.data)
}
}
}
复制代码
<script setup>
import { isRef } from 'vue'
import { useStore,computed,isRef } from 'vuex'
const store = useStore()
const userInfo = computed(() => store.state.user.userInfo)
const getUserInfo = () => store.dispatch('getUserInfo')
const setUserInfo = () => store.commit('setUserInfo')
const is = isRef(userInfo)
console.log(is)
// 输出true,注意若是在script中使用该属性的话须要.value,在模板使用可忽略
</script>
复制代码
// vue2
<script>
mounted(){
console.log(this.$route.query)
console.log(this.$route.params)
// this.$router.push({path: /index})
}
</script>
复制代码
// vue3
<script setup>
import { onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
onMounted(() => {
console.log(route.query)
console.log(route.params)
// router.push({path: /index})
})
</script>
复制代码
// vue2
import Vue from 'vue'
Vue.prototype.$message = message
Vue.prototype.$notification = notification
Vue.prototype.$info = Modal.info
Vue.prototype.$success = Modal.success
Vue.prototype.$error = Modal.error
Vue.prototype.$warning = Modal.warning
// 使用
<template>
<panel class="size-wrapper" ref="panel"> 这是主页 </panel>
</template>
<script>
mounted(){
this.$loading().show()
this.$loading().close()
}
</srcipt>
复制代码
// vue3
import App from '@/App.vue'
const app = createApp(App)
app.config.globalProperties.$message = message
app.config.globalProperties.$notification = notification
app.config.globalProperties.$info = Modal.info
app.config.globalProperties.$success = Modal.success
app.config.globalProperties.$error = Modal.error
app.config.globalProperties.$warning = Modal.warning
// 使用
<script setup>
import { getCurrentInstance } from 'vue'
// const { ctx } = getCurrentInstance()
// 使用proxy代替ctx
const { proxy: ctx } = getCurrentInstance()
onMounted(() => {
const loading = ctx.$loading()
loading.closed()
})
</script>
复制代码
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()], // 插件
outDir: 'dist', // 打包目录
// 服务器配置
server: {
port: 3000,
open: true,
https: false,
ssr: false,
// 设置代理
proxy: {
'/api': {
target: 'http://127.0.0.1:8461/api',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
},
// @重写命令路径
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
})
复制代码