VUE2和VUE3区别对比一览

bash 复制代码
## Vue3总结
### 官方文档
* [Vue3](https://v3.cn.vuejs.org/api/options*data.html)
* [Vue2](https://vuejs.bootcss.com/api/)
### Vue3相对于Vue2的语法特性

#### 1.获取数据
* vue2
```javascript
export default {
  data() {
  	return {
      name: 'myName',
    }
  },
  mounted() {
  	console.log(this.name)
  } 
}
  • vue3
javascript 复制代码
import {ref} from 'vue'
export default {
  setup() {
  	const name = ref('myName')
	  console.log(name.value)
    return {name}
  }
}
2.使用方法
  • vue2
javascript 复制代码
export default {
  methods: {
    show() {
      console.log('show方法被调用')
    }
  },
  mounted() {
  	this.show()
  }
}
  • vue3
javascript 复制代码
import {onMounted} from 'vue'
export default {
  setup() {
    function show() {
      console.log('show方法被调用')
    }
    onMounted(() => {
      show()
    })
    return {show}
  }
}
3.子组件向父组件通信
  • vue2
javascript 复制代码
export default {
  methods: {
    change() {
      this.$emit('valueChange', 3)
    }
  },
}
  • vue3
javascript 复制代码
import {onMounted} from 'vue'
export default {
  setup(props, context) {
    function change() {
      context.emit('valueChange', 3)
    }
  }
}
4.获取Vuex对象
  • vue2
javascript 复制代码
export default {
  mounted() {
  	console.log(this.$store.state.name)
	  this.$store.commit('show')
  } 
}
  • vue3
javascript 复制代码
import {onMounted} from 'vue'
import {useStore} from 'vuex'
export default {
  setup(props, context) {
  	const store = useStore()
    onMounted(() => {
      console.log(store.name)
      store.commit('show')
    })
  }
}
5.v-for里的ref
  • vue3
vue 复制代码
<template>
  // el当前元素,divs是存储每个元素的数组
  <div v-for="(item, index) in list" :ref="el => { divs[index] = el }">{{ item }}</div>
</template>
<script>
import {onMounted, ref} from 'vue';
export default {
  setup() {
    const divs = ref([]);
    onMounted(() => {
      console.log(divs.value)
    });
    return {
      divs
    };
  },
};
</script>
6.Vue3支持碎片,就是说在组件可以拥有多个根节点
  • vue2
vue 复制代码
<template>
  <div class='form-element'>
    <h2>{{ title }}</h2>
  </div>
</template>
  • vue3
vue 复制代码
<template>
  <div class='form-element'></div>
  <h2> {{ title }}</h2>
</template>
7.Composition API
  • Vue2与Vue3 最大的区别 --- Vue2使用选项类型API(Options API)对比Vue3合成型API(Composition API)
    • 旧的选项型API在代码里分割了不同的属性: data,computed属性,methods,等等。新的合成型API能让我们用方法(function)来分割,相比于旧的API使用属性来分组,这样代码会更加简便和整洁。
  • 建立数据 data - Vue2中会把数据放入data属性中,Vue3中需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发
    • 从vue引入reactive
    • 使用reactive()方法来声名我们的数据为响应性数据
    • 使用setup()方法来返回我们的响应性数据,从而我们的template可以获取这些响应性数据
  • vue2
javascript 复制代码
export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login () {
      // 登陆方法
    }
  },
  components:{
    "buttonComponent":btnComponent
  },
  computed:{
	  lowerCaseUsername(){
	    return this.username.toLowerCase();     
	  }
  }
}
  • vue3
vue 复制代码
<template>
  <div>
    <h2> {{ state.username }} </h2>
  </div>
</template>
<script>
import { reactive } from 'vue'
export default {
  props: {
    title: String
  },
  setup () {
    const state = reactive({ //数据
      username: '',
      password: '',
      lowerCaseUsername: computed(() => state.username.toLowerCase()) //计算属性
    })
     //方法
    const login = () => {
      // 登陆方法
    }
    return { 
      login,
      state
    }
  }
}
</script>
8.生命周期钩子 --- Lifecyle Hooks
复制代码
Vue2--------------vue3
beforeCreate  -> setup()
created       -> setup()
beforeMount   -> onBeforeMount
mounted       -> onMounted
beforeUpdate  -> onBeforeUpdate
updated       -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed     -> onUnmounted
activated     -> onActivated
deactivated   -> onDeactivated
9.父子组件传参
javascript 复制代码
import { toRefs } from 'vue'
setup(props, { attrs, slots, emit }) {
	const { title } = toRefs(props)
	console.log(title.value)
  onMounted(() => {
    console.log('title: ' + props.title)
  })
}
10.vue3 Teleport瞬移组件
  • Teleport一般被翻译成瞬间移动组件,实际上是不好理解的.我把他理解成"独立组件"
  • 他可以那你写的组件挂载到任何你想挂载的DOM上,所以是很自由很独立的
  • 以一个例子来看:编写一个弹窗组件
vue 复制代码
<template>
  <teleport to="#modal">
    <div id="center" v-if="isOpen">
      <h2><slot>this is a modal</slot></h2>
      <button @click="buttonClick">Close</button>
    </div>
  </teleport>
</template>
<script>
export default {
  props: {
    isOpen: Boolean,
  },
  emits: {
    'close-modal': null
  },
  setup(props, context) {
    const buttonClick = () => {
      context.emit('close-modal')
    }
    return {
      buttonClick
    }
  }
}
</script>
<style>
  #center {
    width: 200px;
    height: 200px;
    border: 2px solid black;
    background: white;
    position: fixed;
    left: 50%;
    top: 50%;
    margin-left: -100px;
    margin-top: -100px;
  }
</style>
  • 在app.vue中使用的时候跟普通组件调用是一样的
vue 复制代码
<template>
  <div id="app">
    <button @click="openModal">Open Modal</button><br/>
    <modal :isOpen="modalIsOpen" @close-modal="onModalClose"> My Modal !!!!</modal>
  </div>
</template>
<script>
import Modal from './components/Modal.vue'
import{ref} from 'vue'
export default {
  name: 'App',
  components: {
    Modal
  },
  setup() {
    const modalIsOpen = ref(false)
    const openModal = () => {
      modalIsOpen.value = true
    }
    const onModalClose = () => {
      modalIsOpen.value = false
    }
    return {
      modalIsOpen,
      openModal,
      onModalClose
    }
  }
}
</script>
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
  • Teleport 可以把modal组件渲染到任意你想渲染的外部Dom上,不必嵌套在#app中,这样就可以互不干扰了,可以把Teleport看成一个传送门,把你的组件传送到任何地方
  • 使用的时候 to属性可以确定想要挂载的DOM节点下面
  • 在public文件夹下的index.html中增加一个节点,这样可以看到modal组件就是没有挂载在app下,不再受app组件的影响了
javascript 复制代码
<body>
  <div id="app"></div>
  <div id="modal"></div>
</body>
11.vue2与vue3在标签或者组件中的ref="formRef"的dom元素的使用
  • vue2中直接使用this. r e f s . f o r m R e f 或者 t h i s . refs.formRef或者this. refs.formRef或者this.refs['formRef']的方式就可以获取该组件或者dom的内容
  • vue3中由于setup函数中没有了this,那该如何使用呢?
vue 复制代码
<template>
  <div ref="mainContainer" ></div>
</template>
<script>
setup() {
  const mainContainer = ref(null)
  onMounted(()=>{console.log(mainContainer)})
  return {
    mainContainer,
  }
}
</script>
  • 由于setup函数创建时还没有VNode 所以想要使用该属性必须得在onMounted函数里面可以使用获取
    ###table---cloums中render函数渲染组件的写法:
vue 复制代码
import { resolveComponent } from 'vue'   // 需先引入 resolveComponent
cloums中写法render写法
{
          title: '操作',
          align: 'center',
          width: 100,
          fixed: 'right',
          key: 'couTypeCategoryName',
          render: (h, params) => {
            return h(resolveComponent('el-switch'), {
              modelValue: params.row.isShow,
              'active-value': 1,
              'inactive-value': 0,
              // 'onUpdate:modelValue': value => params.row.state = value
              onChange: (val) => {
                
              },
            })
          }
  },

一、在Table表格中渲染input、switch等 在 3.x v-model中,自定义组件相当于传递一个modelValue prop 并发出一个update:modelValue事件

复制代码
render: (h, params) => {
  return h(resolveComponent('el-input'), {
    size: 'small',
    modelValue: params.row.comments,
    'onUpdate:modelValue': (value) => (params.row.comments = value),
  })
},

二、插槽

复制代码
  <template #footer>
    <span class="dialog-footer">
      <el-button>取消</el-button>
      <el-button type="primary">确定</el-button>
    </span>
  </template>

三、filters

在vue3中被移除

###Fragment

vue2每个模版必须有一个根节点

vue3可以有多个根节点

vue 复制代码
<!--vue2-->
<template>
  <div>
    <span></span>
    <span></span>
  </div>
</template>
<!--vue3-->
<template>
  <span>hello</span>
  <span>world</span>
</template>

###v-if v-for 优先级

vue2 时 v-for 优先级高,所以v-for 和v-if一起会耗性能,增加了喝多不必要的判断

vue3 v-if比v-for有更高的优先级

###vVNode Prop

vue2和vue3的虚拟dom参数有所区别,vue3更加扁平化

js 复制代码
<!--vue2-->
render: (h, params) => {
  let btnArr = [
    h(
      'Button',
      {
        props: {
          type: 'primary',
        },
        style: {
          marginLeft: '8px',
        },
        on: {
          click: () => {
            this.modalType = 'detail'
            this.viewType = 2
            this.item = params.row
            this.pageStatus = true
            this.pState = true
          },
        },
      },
      '查看详情'
    ),
  ]
  return h('div', btnArr)
},
<!--vue3-->
render:(h,params)=>{
    return  h(resolveComponent('el-input-number'), {
        type: 'number',
        size: 'large',
        modelValue:params.row.value,
        stepStrictly:true,
        controls:false,
        min:"1",
        'onUpdate:modelValue':(value) => { params.row.value = parseInt(value)},
        style: { width:'200px'},
    })
}

###ref和reactive 响应式的基础

接受一个参数,返回一个响应式数据

不同的是ref一般处理基础数据类型,reactive一般处理引用数据类型

使用 reactive,toRefs 保证 reactive 对象属性保持响应性

vue 复制代码
import { ref, computed, reactive, toRefs } from 'vue'

setup() {
  const DataProps  = reactive({
    count: 0,
    increase: () => { data.count++},
    double: computed(() => data.count * 2)
  })
  const refData = toRefs(data)
  return {
    ...refData
  }
}

###v-model

vue2只能绑定一个,vue3可以绑定多个

vue 复制代码
<!--父组件-->
<template>
  // v-model:modelValue简写为v-model
  // 可绑定多个v-model
  <child
    v-model="state.name"
    v-model:age="state.age"
  />
</template>

<script setup>
  import { reactive } from 'vue'
  // 引入子组件
  import child from './child.vue'

  const state = reactive({
    name: 'Jerry',
    age: 20
  })
</script>
子组件
<template>
  <span @click="changeInfo">我叫{{ modelValue }},今年{{ age }}岁</span>
</template>

<script setup>
// import { defineEmits, defineProps } from 'vue'
// defineEmits和defineProps在<script setup>中自动可用,无需导入
// 需在.eslintrc.js文件中【globals】下配置【defineEmits: true】、【defineProps: true】

defineProps({
  modelValue: String,
  age: Number
})

const emit = defineEmits(['update:modelValue', 'update:age'])
const changeInfo = () => {
  // 触发父组件值更新
  emit('update:modelValue', 'Tom')
  emit('update:age', 30)
}
</script>

###defineComponent函数,只是对setup函数进行封装,返回options的对象;

###父组件获取子组件的属性和方法

vue 复制代码
<!--父组件-->
<template>
  <child ref="comp"></child>
  <button @click="handlerClick">按钮</button>
</template>
<script setup>
import child from "./comp/expose.vue"
import { ref } from "vue"
const comp = ref(null)
const handlerClick = () => {
  console.log(comp.value.a) // 获取子组件对外暴露的属性
  comp.value.someMethod() // 调用子组件对外暴露的方法
}
</script>
<!--子组件-->

<template>

  <div>{{a}}</div>
  <button @click='someMethod'>按钮子</button>
</template>
<script setup>
import { ref } from 'vue'
let someMethod=()=>{
  console.log(666)
}

const a = 1
const b = ref(2)

defineExpose({
  a,
  b,
  someMethod
})
</script>

###其他

1.vue2 defineProperty只能监听某个属性,不能对全对象监听

2 vue3 Proxy 代理,可以检测到数组内部数据的变化

3.vue3 Teleport瞬移组件

4.Vue2 - 这里把数据放入data属性中

5.vue 3 Composition API

需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。

从vue引入reactive

使用reactive()方法来声名我们的数据为响应性数据

使用setup()方法来返回我们的响应性数据,从而我们的template可以获取这些响应性数据

vue3Composition API生命后期

setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method

onBeforeMount() : 组件挂载到节点上之前执行的函数。

onMounted() : 组件挂载完成后执行的函数。

onBeforeUpdate(): 组件更新之前执行的函数。

onUpdated(): 组件更新完成之后执行的函数。

onBeforeUnmount(): 组件卸载之前执行的函数。

onUnmounted(): 组件卸载完成后执行的函数

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax