Vue2和Vue3的区别

1. vue2和vue3双向数据绑定原理发生了改变

vue2 的双向数据绑定是利用ES5 的一个 API Object.definePropert()对数据进行劫持 结合 发布订阅模式的方式来实现的。

vue3 中使用了 es6ProxyAPI 对数据代理。

相比于vue2.x,使用proxy的优势如下

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

  1. 可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)

  1. 可以监听数组,不用再去单独的对数组做特异性操作 vue3.x可以检测到数组内部数据的变化

2. Vue3支持碎片(Fragments)

就是说在组件可以拥有多个根节点。

3. Composition API

vue2

export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login () {
      // 登陆方法
    }
  },
  components:{
            "buttonComponent":btnComponent
        },
  computed:{
      fullName(){
        return this.firstName+" "+this.lastName;     
      }
}
 
}

vue3

export default {
  props: {
    title: String
  },
  
  setup () {
    const state = reactive({ //数据
      username: '',
      password: '',
      lowerCaseUsername: computed(() => state.username.toLowerCase()) //计算属性
    })
     //方法
    const login = () => {
      // 登陆方法
    }
    return { 
      login,
      state
    }
  }
}

4. 建立数据 data

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


export default {
  props: {
    title: String
  },
  data () {
    return {
      username: '',
      password: ''
    }
  }
}

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

使用以下三步来建立反应性数据:

从vue引入reactive

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

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

5. 生命周期钩子

  1. 父子传参不同,setup() 函数特性

总结:

1、setup 函数时,它将接受两个参数:(props、context(包含attrs、slots、emit))

2、setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之前的函数

3、执行 setup 时,组件实例尚未被创建(在 setup() 内部,this 不会是该活跃实例的引用,即不指向vue实例,Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined)

4、与模板一起使用:需要返回一个对象 (在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用)

5、使用渲染函数:可以返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态

注意事项:

1、setup函数中不能使用this。Vue 为了避免我们错误的使用,直接将 setup函数中的this修改成了 undefined)

2、setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。但是,因为 props 是响应式的,你不能使用 ES6 解构,因为它会消除 prop 的响应性。

如果需要解构 prop,可以通过使用 setup 函数中的toRefs 来完成此操作:

父传子,props

import { toRefs } from 'vue'
 
setup(props) {
    const { title } = toRefs(props)
 
    console.log(title.value)
     onMounted(() => {
      console.log('title: ' + props.title)
    })

}

子传父,事件 - Emitting Events

7. vue3 Teleport瞬移组件

Teleport一般被翻译成瞬间移动组件,实际上是不好理解的.我把他理解成"独立组件",

他可以那你写的组件挂载到任何你想挂载的DOM上,所以是很自由很独立的

以一个例子来看:编写一个弹窗组件

<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 lang="ts">

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中使用的时候跟普通组件调用是一样的

<template>
<div id="app">
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
  <HooksDemo></HooksDemo>
  <button @click="openModal">Open Modal</button><br/>
<modal :isOpen="modalIsOpen" @close-modal="onModalClose"> My Modal !!!!</modal>
</div>
  
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import HooksDemo from './components/HooksDemo.vue'
import Modal from './components/Modal.vue'
import{ref} from 'vue'
export default {
  name: 'App',
  components: {
    HelloWorld,
    HooksDemo,
    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>


要是在app.vue文件中使用的时候,modal是在app的 DOM节点之下的,父节点的dom结构和css都会给modal产生影响

于是产生的问题

modal被包裹在其它组件之中,容易被干扰

样式也在其它组件中,容易变得非常混乱

Teleport 可以把modal组件渲染到任意你想渲染的外部Dom上,不必嵌套在#app中,这样就可以互不干扰了,可以把Teleport看成一个传送门,把你的组件传送到任何地方

使用的时候 to属性可以确定想要挂载的DOM节点下面

<template>
  <teleport to="#modal">
    <div id="center">
      <h2>柏特better</h2>
    </div>
  </teleport>
</template>

在public文件夹下的index.html中增加一个节点

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <div id="modal"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
 

)">
< <上一篇
下一篇>>