通过 demo 了解 Vue3 新特性
我们了解锤子的方式不是盯着它看,而是拿起来用。 💪
💎创建项目
通过vue-cli脚手架创建一个Vue3.0的项目
// 安装脚手架
npm install -g @vue/cli
// 查看版本
vue --version
// 创建项目
vue create vue3-demo
做一个简单的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()
其他的生命周期钩子函数,在原先的方法名之前,加上 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)
💎最后的话
以上,如果对你有用的话,不妨点赞收藏关注一下,谢谢 🙏
😊😊😊😊😊😊😊😊
转载自:https://juejin.cn/post/7137130257206738980