likes
comments
collection
share

通过 demo 了解 Vue3 新特性

作者站长头像
站长
· 阅读数 31

我们了解锤子的方式不是盯着它看,而是拿起来用。 💪                                           

💎创建项目

通过vue-cli脚手架创建一个Vue3.0的项目

// 安装脚手架
npm install -g @vue/cli
// 查看版本
vue --version
// 创建项目
vue create vue3-demo

通过 demo 了解 Vue3 新特性

做一个简单的demo对比一下Vue2 和 Vue3 的语法

💎Vue2的实现方式

<template>
  <div class="hello">
    <input type="text" v-model="num1" @keyup="add()">
    <span>+</span>
    <input type="text" v-model="num2" @keyup="add()">
    <span>=</span>
    {{result}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data () {
    return {
      num1: 0,
      num2: 0,
      result: 0
    }
  },
  methods: {
    add () {
      this.result = parseInt(this.num1) + parseInt(this.num2)
    }
  }
}
</script>

用到了Vue2中的双向数据绑定,事件绑定,数据模板

💎Vue3的实现方式

ref

<script>
import { ref } from 'vue'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  setup () {
     const num1 = ref(0)
    const num2 = ref(0)
    return {
      num1,
      num2
    }
  }
}
</script>

ref 改变了传统 data 的使用方式

Vue3中 setup 是取不到 this 这个变量的

同样是通过事件绑定 add 方法,在 setup 中定义 add方法,改变result的value值,并且 return 出去。


<template>
  <div class="hello">
    <input type="text" v-model="num1" @keyup="add">
    <span>+</span>
    <input type="text" v-model="num2" @keyup="add">
    <span>=</span>
    {{result}}
  </div>
</template>

<script>
import { ref } from 'vue'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  setup () {
    const num1 = ref(0)
    const num2 = ref(0)
    const result = ref(0)

    function add () {
      result.value = parseInt(num1.value) + parseInt(num2.value)
    }

    return {
      num1,
      num2,
      result,
      add
    }
  }
}
</script>

reactive

把所有和组件相关的状态,都抽离出来,放在 state 中。

state和函数add,可以写在 setup 外面

如下所示,把逻辑和状态都抽离出来了。

方便实现,组件之间逻辑的复用。

<template>
  <div class="hello">
    <input type="text" v-model="state.num1" @keyup="add">
    <span>+</span>
    <input type="text" v-model="state.num2" @keyup="add">
    <span>=</span>
    {{state.result}}
  </div>
</template>

<script>
import { reactive } from 'vue'
const state = reactive({
  num1: 0,
  num2: 0,
  result: 0
})
function add () {
  state.result = parseInt(state.num1) + parseInt(state.num2)
}
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  setup () {
    return {
      state,
      add
    }
  }
}
</script>

💎toRef 和 toRefs 的作用、用法、区别

toRef 和 toRefs 可以用来复制 reactive 里面的属性然后转成 ref

而且它既保留了响应式,也保留了引用

也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新。

如果你知道 浅拷贝 的话那么这个引用就很好理解了,它复制的其实就是引用 + 响应式 ref

不加 s 和 加 s 的区别就是这样:

toRef: 复制 reactive 里的单个属性并转成 ref

const state = reactive({
  foo: 1,
  bar: 2
})

const fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 2

state.foo++
console.log(fooRef.value) // 3

toRefs: 复制 reactive 里的所有属性并转成 ref

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:

{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// ref 和原始 property 已经“链接”起来了
state.foo++
console.log(stateAsRefs.foo.value) // 2

stateAsRefs.foo.value++
console.log(state.foo) // 3

💎computed

computed 在Vue3 中不再作为动态属性使用,而是从 vue中引入的一个方法

import { reactive, computed } from 'vue'

computed 的使用,不同于Vue2,可以这样使用,computed作为一个函数,直接在 reactive 中改变 result的值。


const state = reactive({
  num1: 0,
  num2: 0,
  result: computed(() => parseInt(state.num1) + parseInt(state.num2))
})

这样就不需要 add 方法了,直接在 setup 中 return 出 state 即可。

💎组件之间的传参

在Vue2 中,子组件向父组件传参数

this.$emit(state, payload)

在 Vue3 中没有了 this 之后,子组件如何向父组件传参?

Vue3 的 setup 有两个属性 props 和 ctx,ctx 中有 emit 方法


setup (props, { emit }) {
    const clickEvent = () => {
      emit('sendMsg', state.result)
    }
    return {
      state,
      clickEvent
    }
}

💎生命周期

🚀生命周期的变化

beforeCreate 和 created 这两个生命周期的钩子函数,已经被遗弃掉了,转而采用 setup()

通过 demo 了解 Vue3 新特性

其他的生命周期钩子函数,在原先的方法名之前,加上 on

使用示例


import { onMounted, onUpdated, onUnmounted } from 'vue'

const MyComponent = {
  setup() {
    onMounted(() => {
      console.log('mounted!')
    })
    onUpdated(() => {
      console.log('updated!')
    })
    onUnmounted(() => {
      console.log('unmounted!')
    })
  }
}

💎创建路由


import { createRouter, createWebHashHistory } from 'vue-router'

...

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

💎获取路由

Vue 3.0 中通过 getCurrentInstance 方法获取当前组件的实例,然后通过 ctx 属性获得当前上下文。

ctx.$router 是 Vue Router 实例,里面包含了 currentRoute 可以获取到当前的路由信息。


<script>
  import { getCurrentInstance } from 'vue'

  export default {
    setup () {
      const { ctx } = getCurrentInstance()
      console.log(ctx.$router.currentRoute.value)
    }
  }
</script>

💎vuex集成

import Vuex from 'vuex'

export default Vuex.createStore({
  state: {
    test: {
      a: 1
    }
  },
  mutations: {
    setTestA(state, value) {
      state.test.a = value
    }
  },
  actions: {
  },
  modules: {
  }
})

Vuex 的语法和 API 基本没有改变

引用vuex状态

const a = computed(() => ctx.$store.state.test.a)

更新 Vuex 状态

ctx.$store.commit('setTestA', count)

💎最后的话

以上,如果对你有用的话,不妨点赞收藏关注一下,谢谢 🙏

😊😊😊😊😊😊😊😊