本篇文章适用于熟练掌握Vue2的小伙伴们,不想重新学习Vue3,那看本篇文章就够啦!希望大家收获多多!!
 Vue3是向下兼容的,可以运行Vue2代码
一、页面区别
Vue2定义属性方法
<template>
  <div >
    <div>简单属性</div>
    <div>{{ msg }}</div>
    <div><button @click="updateMsg">修改简单属性</button></div>
    <div>对象属性</div>
    <div>{{ ObjMsg.msg }}</div>
    <div><button @click="updateObjMsg">修改对象属性</button></div>
  </div>
</template>
<script>
export default {
  name: "namePage",
  data() {
    return {
      msg: "简单属性",
      ObjMsg: {
        msg: "对象属性",
      },
    };
  },
  methods: {
    updateMsg() {
      this.msg = "修改简单属性";
    },
    updateObjMsg() {
      this.ObjMsg.msg = "修改对象属性";
    },
  },
};
</script>
<style lang="scss" scoped></style>
 
Vue3组合式API定义属性方法
不用定义method、data 更方便
<template>
  <div >
    <div>简单属性</div>
    <div>{{ msg }}</div>
    <div><button @click="updateMsg">修改简单属性</button></div>
    <div>对象属性</div>
    <div>{{ ObjMsg.msg }}</div>
    <div><button @click="updateObjMsg">修改对象属性</button></div>
  </div>
</template>
<script setup>
//需要导入ref 和reactive
import { ref, reactive } from 'vue'
//ref定义简单属性
const msg = ref('简单属性')
const updateMsg = () => {
  //注意:没有this对象了
  msg.value = '修改了简单属性'
}
//reactive定义对象属性  
const ObjMsg = reactive({
  msg: '对象属性'
})
const updateObjMsg = () => {
  ObjMsg.msg = '修改了对象属性'
}
  //reactive也可以使用ref(最终都是转为ref的)但是需要使用.value来访问
// const ObjMsg = ref({
//   msg: '对象属性'
// })
// const updateObjMsg = () => {
//   ObjMsg.value.msg = '修改了对象属性'
// }
</script>
<style scoped>
</style> 
详解<script setup>
<script setup> 是 Vue 3 中引入的一种新的脚本编写方式,它允许您以更加简洁的方式编写 Vue 组件。<script setup> 提供了一种声明式的方式来定义组件的逻辑,同时它还支持组合 API,使得代码更加简洁和易于理解。
<script setup> 的基本用法:
导入组合 API:
直接在 <script setup> 中导入 Vue 的组合 API,如 ref、reactive 等。
定义响应式状态:
使用 ref 或 reactive 定义响应式状态。
定义方法:
直接定义方法,无需像传统的 Vue 选项 API 那样将方法放在 methods 对象中。
自动暴露:
<script setup> 中定义的所有顶级变量和函数都会自动暴露给模板使用,无需显式地使用 export default。
类型声明:
可以使用 TypeScript 进行类型声明。
结果
上方两种效果相同

二、router使用的区别
vue2中使用router
定义router
import Vue from "vue";
import VueRouter from "vue-router";
import newPage from "../views/vuePage.vue";
import indexPage from "../views/indexPage.vue";
Vue.use(VueRouter);
const routes = [
    {
        path: '/',
        name: 'indexPage',
        component: indexPage
    },
    {
        path: '/newPage',
        name: 'newPage',
        component: newPage
    },
];
const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
});
export default router;
 
在main.js中引入router
import Vue from 'vue'
import App from './App.vue'
import router from './router'
 Vue.config.productionTip = false
new Vue({
  router,//注册路由
  render: h => h(App),
}).$mount('#app')
 
在vue中使用router
//template中
<el-button class="button1" type="danger" @click="goToVue">Vue基础</el-button>
//method中
goToVue() {
        // 使用编程式导航跳转到 /newPage 页面
        this.$router.push({
          path: '/newPage'
        })
      }, 
Vue3使用router
定义router
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
// 导入组件
import HelloWorld from '../components/HelloWorld.vue';
// 定义路由
const routes = [
  { path: '/', component: HelloWorld },
];
// 创建路由器实例
const router = createRouter({
  history: createWebHistory(),
  routes,
});
// 导出路由器
export default router; 
在main.js中使用
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'; // 导入路由配置
// createApp(App).mount('#app')
// 引入全局样式
const app = createApp(App);
// 使用路由
app.use(router);
// 挂载根组件
app.mount('#app'); 
在vue中使用router
<template>
      <button @click="toHellow">跳转</button>
</template>
  
  <script setup>
  //需要导入router
  import { useRouter ,useRoute} from 'vue-router'
  const router = useRouter();
  const route = useRoute();
  
  const toHellow = () => {
    //注意:没有this对象了
    //跳转
    console.log('当前页面路由', route.path)
    router.push('/HelloWorld')
  }
  
  
  </script>
  
  <style scoped>
  
  </style> 
三、全局变量方法和变量
vue2中定义全局变量
main.js中定义
定义Utils的isEmpty方法并Vue.prototype.Utils = Utils;
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
// Vue.config.productionTip = false
//定义全局变量isEmpty
const Utils = {
  isEmpty:(value) =>{
    if(value === null || value === undefined || value === ''){
      return true;
    }else{
      return false;
    }
  }
}
Vue.prototype.Utils = Utils;
new Vue({
  router,//注册路由
  render: h => h(App),
}).$mount('#app')
 
页面使用
 created() {
      let a="new"
      console.log("调用全局变量判断是否为空",this.Utils.isEmpty(a))
    }, 
Vue3中定义全局变量(方法)
main.js中定义
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'; // 导入路由配置
// createApp(App).mount('#app')
//定义全局变量isEmpty
const Utils = {
    isEmpty:(value) =>{
      if(value === null || value === undefined || value === ''){
        return true;
      }else{
        return false;
  
      }
    }
  }
// 引入全局样式
const app = createApp(App);
app.config.globalProperties.$utils = Utils;
// 使用路由
app.use(router);
// 挂载根组件
app.mount('#app'); 
页面使用
通过代理
import { useRouter, useRoute } from 'vue-router'
import { getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const init = () => {
    let a="aaaaa"
    console.log('当前页面实例', proxy.Utils.isEmpty(a))
}
init() 
四、watch监听属性
vue2的watch监听属性
<template>
<div>
  <div>需要监听的值:{{msg}}</div>
  <button @click="updateMsg">修改</button>
</div>
</template>
<script>
export default {
  name: "pPage",
  data() {
    return {
      msg: "123456"
    }
  },
  methods: {
    updateMsg() {
      this.msg = new Date().getTime();
    }
  },
  watch: {
    //简单形式
    // msg(newValue, oldValue) {
    //   console.log("newValue", newValue);
    //   console.log("oldValue", oldValue);
    // }
    //对象形式
    msg: {
      deep: true,
      immediate: true,//初始化是否执行
      handler(newValue, oldValue) {
        console.log("newValue", newValue);
        console.log("oldValue", oldValue);
      },
    }
  }
}
</script>
<style scoped>
</style>
 
 

Vue3的watch监听属性
<template>
    <div>需要监听的值:{{ msg }}</div>
    <button @click="toChange">改变</button>
</template>
  
<script setup>
import { ref,watch } from 'vue';
const msg = ref('1111')
const toChange = () => {
    msg.value = new Date().getTime();
}
//简单的没有其他设置的监听
// watch(msg, (newVal, oldVal) => {
//     console.log('监听msg变化', newVal, oldVal)
// })
//对象形式
watch(msg, (newVal, oldVal) => {
    console.log('监听msg变化', newVal, oldVal)
}, {
    immediate: true,
    deep: true
})
</script>
  
<style scoped></style> 
 

区别总结
语法差异:
Vue 2 中,watch 是定义在组件的选项对象中的。
Vue 3 中,使用 Composition API 的 watch 函数。
配置选项:
Vue 2 中,你可以直接在 watch 的对象形式中指定 deep 和 immediate 选项。
Vue 3 中,这些选项同样可以通过第三个参数传递给 watch 函数。
回调函数:
Vue 2 中,简单的回调函数可以直接定义在 watch 对象中。
Vue 3 中,回调函数作为 watch 函数的第一个参数。
监听的对象:
Vue 2 中,watch 直接监听数据属性。
Vue 3 中,通常监听通过 Composition API 创建的响应式引用。
五、生命周期
vue2中的生命周期
export default {
  data() {
    return {
      message: 'Hello Vue!'
    };
  },
  created() {
    console.log('Component created.');
  },
  mounted() {
    console.log('Component mounted.');
  },
  beforeDestroy() {
    console.log('Component will be destroyed.');
  },
  destroyed() {
    console.log('Component destroyed.');
  },
  methods: {
    updateMsg() {
      this.msg = new Date().getTime();
    }
  },
}; 
vue3中的生命周期
import { onMounted, onBeforeUnmount, ref } from 'vue';
export default {
  setup() {
    const message = ref('Hello Vue!');
    onMounted(() => {
      console.log('Component mounted.');
    });
    onBeforeUnmount(() => {
      console.log('Component will be unmounted.');
    });
    return {
      message
    };
  }
}; 
主要区别
1、Composition API 的引入:
Vue 3 引入了 Composition API,其中 setup 函数取代了 beforeCreate 和 created 钩子的功能。
setup 函数在组件初始化时调用,可以接收 props 参数,并返回模板中使用的数据、计算属性、方法等。
2、生命周期钩子的名称变更:
beforeDestroy 更名为 beforeUnmount。
destroyed 更名为 unmounted。
3、生命周期钩子的移除:
Vue 3 移除了 beforeCreate 和 created 钩子,因为它们的功能被 setup 所替代。
4、生命周期钩子的新增:
Vue 3 并没有新增生命周期钩子,但通过 Composition API 提供了更多的灵活性。
Vue 2 的生命周期钩子如下所示:
创建阶段 beforeCreate created beforeMount mounted
更新阶段 beforeUpdate updated
销毁阶段 beforeDestroy destroyed
错误处理 errorCaptured
异步组件 activated deactivated
服务端渲染 serverPrefetch
Vue 3 的生命周期钩子如下所示:
创建阶段 setup (Composition API)
beforeCreate 和 created 被 setup 替代
挂载阶段 beforeMount mounted
更新阶段 beforeUpdate updated
销毁阶段 beforeUnmount unmounted
错误处理 errorCaptured
异步组件 activated deactivated
服务端渲染 serverPrefetch
六、父子组件的调用
Vue2父子组件间的调用
1、父组件给子组件传值使用props
父组件:
<div>
    <SonPage  msg="通过props传递值---父=>子" ></SonPage>
    <h1>父组件</h1>
  </div> 
子组件
<div :style="{border: '1px solid red'}">
  <h1>子组件</h1>
  <div>我是父组件传入的参数:{{ msg }}</div>
</div>
<script>
export default {
  props: {
    msg: {
      type: String,
    }
  },
  name: "SonPage",
}
</script> 
2、父组件调用子组件方法
父组件
使用 this.$refs.sonRef.子组件方法名。父组件在使用子组件时要加ref,上下一致
<template>
  <div>
    <SonPage ref="sonRef" ></SonPage>
    <h1>父组件</h1>
    <button @click="opSon">我要调用子组件</button>
  </div>
</template>
<script>
import SonPage from "@/views/SonPage";
export default {
  name: "pPage",
  components: {SonPage},
 
  methods: {
    opSon() {
      this.$refs.sonRef.ParentOpSon("我是父组件调用子组件方法传入的参数");
    },
  },
}
</script> 
子组件
<template>
  <div :style="{border: '1px solid red'}">
    <h1>子组件</h1>
    <div>这里是父组件调用子组件方法传入的参数:{{ msg2 }}</div>
  </div>
</template>
<script>
export default {
  name: "SonPage",
  data() {
    return {
      msg2: ""
    }
  },
  methods: {
    ParentOpSon(parentMsg) {
      this.msg2 = parentMsg;
    },
  },
}
</script>
<style scoped>
</style>
 
结果:

3、子组件调用父组件方法
父组件
使用子组件标签上加@【子组件的this.$emit中第一个参数名】。方法使用 e就是子组件的参数
<template>
  <div>
    <SonPage @opParent="parentMethod"></SonPage>
    <h1>父组件</h1>
    <div>我是子组件调用父组件方法传入的参数{{ sonMsg }}</div>
  </div>
</template>
<script>
import SonPage from "@/views/SonPage";
export default {
  name: "pPage",
  components: {SonPage},
  data() {
    return {
      sonMsg: ""
    }
  },
  methods: {
    parentMethod(e) {
      console.log(e);
      this.sonMsg = e;
    }
  },
}
</script>
<style scoped>
</style>
 
子组件
子组件中使用this.$emit("父组件标签上的@的名"," 调用父组件方法的参数")
<template>
  <div :style="{border: '1px solid red'}">
    <h1>子组件</h1>
    <button @click="opParent">我要调用父组件的方法</button>
  </div>
</template>
<script>
export default {
  name: "SonPage",
  data() {
    return {
      msg2: ""
    }
  },
  methods: {
    opParent() {
      this.$emit("opParent", "我是子组件调用父组件方法传入的参数")
    }
  },
}
</script>
<style scoped>
</style>
 
结果:

Vue3父子组件间的调用
1、父组件给子组件传值使用
父组件
注意::msg
<template>
    <button @click="toHellow">跳转</button>
    <div>
    <SonPage :msg="myMsg"></SonPage>
    <h1>父组件</h1>
  </div>
</template>
  
<script setup>
import SonPage from './sonPage.vue'
const myMsg = '我是父组件传入的参数'
</script>
  
<style scoped></style> 
子组件
注意使用 <script setup>和defineProps
<template>
    <div :style="{border: '1px solid red'}">
      <h1>子组件</h1>
      <div>这里是父组件传入的参数:{{ msg }}</div>
    </div>
  </template>
  <script setup>
  import { defineProps } from 'vue';
 defineProps({
        msg: {
        type: String,
        default: ''
      }
  })
  </script>
  <style scoped>
  </style>
   
2、父组件调用子组件方法
父组件
父组件中的子组件标签需要添加ref并定义, ref.vue.子组件名字(参数) 即可调用成功
<template>
    <div>
    <SonPage ref="sonRef"></SonPage>
    <button @click="opSon">我要调用子组件</button>
  </div>
    <h1>父组件</h1>
</template>
  
<script setup>
import SonPage from './sonPage.vue'
import { ref } from 'vue'
const sonRef = ref();
  
const opSon = () => {
    sonRef.value.ParentOPSon('我是父组件调用子组件方法传入的参数')
}
</script>
  
<style scoped></style> 
子组件
定义一个方法,并且使用defineExpose导出
<template>
    <div :style="{border: '1px solid red'}">
      <h1>子组件</h1>
  <div>这是父组件调用子组件方法传入的参数:{{msg2}}</div>
    </div>
  </template>
  
  <script setup>
import { ref , defineExpose} from 'vue';
const msg2 = ref('');
const ParentOPSon= (parentMsg)=>{
  msg2.value=parentMsg
}
//导出给父组件调用
defineExpose({
  ParentOPSon
})
  </script>
  <style scoped></style>
   
结果

3、子组件调用父组件方法
父组件
通过 <SonPage @opParent="onOpParent" /> 注册了对 opParent 事件的监听,并定义了一个 parentMethod 方法来处理这个事件。
<template>
    <div>
        <SonPage @opParent="parentMethod"></SonPage>
    </div>
    <div>我是子组件调用父组件方法传入的参数:{{ sonMsg }}</div>
    <h1>父组件</h1>
</template>
  
<script setup>
import SonPage from './sonPage.vue'
import { ref } from 'vue'
const sonMsg = ref();
//子组件调用父组件方法
const parentMethod = (e) => {
    console.log('子组件调用父组件方法传入的参数', e)
    sonMsg.value = e
}
</script>
  
<style scoped></style> 
子组件
注意在 defineEmits 中明确地声明您想要触发的所有自定义事件。
使用emit('opParent', '子组件调用父组件的方法');调用父组件方法,第一个参数需要与父组件中@名字一样
<template>
    <div :style="{border: '1px solid red'}">
      <h1>子组件</h1>
      <button @click="opParentFF">我要调用父组件的方法</button>
    </div>
  </template>
  
  <script setup>
import { defineEmits } from 'vue';
//声明自定义事件
const emit = defineEmits(['opParent']);
const opParentFF = () => {
  console.log('子组件调用父组件的方法');
  // 调用父组件的方法
  emit('opParent', '子组件调用父组件的方法');
};
  </script>
  <style scoped></style>
   
结果

看到这里就基本结束喽,如有变化后期会及时更新的~
本人小白一个
可能存在部分问题
欢迎大家批评指正哦~



















