Vue3 对比Vue2有何使用上的不同?底层逻辑到底有何不同,一篇文章告诉你

追梦者追梦者 -
Vue3 对比Vue2有何使用上的不同?底层逻辑到底有何不同,一篇文章告诉你
Vue2的基本结构
<template>
 <div>{{msg}}</div>
</template>
<script>
export default {
  data() {
    return {
      msg: "我是内容",
    };
  },
  created() {}
  methods:{}//方法
};
</script>
<style lang="less" scoped></style>

Vue3的基本结构

<template>
  <div  @click="Vue3Click">
   {{state.msg}}
   {{content}}
  </div>
</template>
<script setup>
import { ref, onMounted, reactive } from "vue";
const state = reactive({
  msg: "我是Vue2data return里面的哟",
});
let content = ref("我还可以这样");

const Vue3Click = () => {
    console.log("我是Vue3的点击方法");
};
onMounted(() => {//生命周期钩子写法改变 
  console.log("我是页面dom加载完毕的钩子");
  Vue3Click();
});
</script>

<style lang="less" scoped>
</style>

那么reactiveref是干什么的呢? 就是把数据变成响应式 的。

Vue2的响应式是怎么实现的呢?对哦,就是用 Object.defineProperty实现的,

vue2的响应式是通过Object.defineProperty(数据劫持)方法,针对对象和数组有两种处理:

对象的话 -》通过defineProperty 对对象的属性值的读取和修改进行劫持
数组的话 -》通过拦截修改数组系列的方法来实现元素修改的劫持

有很多童鞋对数组的拦截不是很清楚,这里放一张图片更加清晰

image.png

其实现在调用数组的方法都是访问的是拦截器的方法,这样是不是就清晰很多了

明明响应式已经做好,但是Vue3现在为什么要费劲修改响应式原理呢?

想必大家都知道Vue2有一个this.$set 那为什么会出现这个方法呢?这个方法的出现解决了什么问题呢
正是因为这两个无法规避的问题
1.对象直接新添加的属性或删除已有属性, 视图不会自动更新
2.直接修改数组length, 视图不会自动更新

那么Vue3用的Proxy解决了这个问题,并且统一了劫持数组和对象的方法

new Proxy(data, {
    // 拦截读取属性值
    get (target, prop) {
        return Reflect.get(target, prop)
    },
    // 拦截设置属性值或添加新属性
    set (target, prop, value) {
        return Reflect.set(target, prop, value)
    },
    // 拦截删除属性
    deleteProperty (target, prop) {
        return Reflect.deleteProperty(target, prop)
    }
})
 
proxy.name = 'xiaofei'   

那么对象层级比较深,怎么办嘞? -- 递归

var obj = {
  a:1,
  b:{
      c:2,
    d:{e:3}
  }
}
var handler = {
  get:function(trapTarget,prop,receiver){
    var val = Reflect.get(trapTarget,prop)
    console.log('get',prop)
    if(val !== null && typeof val==='object'){
        return new Proxy(val,handler) // 代理内层
    }
    return Reflect.get(trapTarget,prop)
  },
  set:function(trapTarget,key,value,receiver){
    console.log('触发set:',key,value)
    return Reflect.set(trapTarget,key,value,receiver)
  }
}
var proxy = new Proxy(obj,handler)
proxy.b.d.e
// 输出: 均被代理
// get b
// get d
// get e 
Vue2的路由跳转

this.$router.push("/home")
Vue3变为了

import { useRouter } from "vue-router";

const router = useRouter();

router.push({ path: "/home" })
Vue2 父组件引入子组件 需要components 注册一下

Vue3 不需要注册手动components注册了,可以直接使用,给子组件传递参数,给父组件传递参数有写法有改变

//home.vue
<template>
  <div >
    我是首页接口内容
    <homeson1
      name="我可以直接被使用,并且传递给子组建"
      @transmit="transmit"
      @getlist="getlist"
    ></homeson1>
    <p>子组件传递的参数是 ----》{{ state.homesondata }}</p>
  </div>
</template>
<script setup>
import { getHomePageAllMultiWindow } from "@/request/api";
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import homeson1 from "../components/homeson1.vue";
const router = useRouter();
const state = reactive({
  homesondata:"",//子组件传递的数据
});
const transmit = (data) =>{
  state.homesondata = data;
}
const getlist = () =>{
     axios....
}
</script> 



//homeson1.vue
<template>
  <div >
    <p>{{ name }}</p>
    <button @click="transmit">子给父传递参数</button>
    <button @click="Calltheparent">直接调用父组件方法</button>
  </div>
</template>
<script setup>
import { ref, onMounted, reactive } from "vue";
let emits = defineEmits(["query","getlist"]);

defineProps({
  name: String,//我在这里接收父组件传递的参数
});

const transmit = () => {
  emits("query", "我是给父组件传递参数"); //我给父组件传递参数
};
const Calltheparent = () => {
  emits("getlist"); //直接调用父组件方法,也可以传递参数
};

</script>

特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

Tags 标签

前端javascripthtml5vue.js

扩展阅读

加个好友,技术交流

1628738909466805.jpg