前言:vue2 是option API; vue3是composition API。所以在语法上有很大不同,以下为上手vue3的常用语法。
一、vue3里 script
的三种写法
1.1 最基础 —— vue2的写法
<template>
<div>{{ num }}</div>
<button @click="onClick"> +1 </button>
</template>
<script>
export default {
data() {
return {
num : 1,
};
},
methods: {
onClick() {
this.num += 1;
},
},
}
</script>
总结: 和vue2完全一样,简单明了。无上手难度
1.2 新语法 —— setup() 属性
<template>
<div>{{ num }}</div>
<button @click="onClick"> + 1 </button>
</template>
<script>
import { ref } from 'vue';
export default {
// 注意这部分
setup() {
let num = ref(1);
const onClick = () => {
num.value += 1;
};
return {
num,
onClick,
};
},
}
</script>
总结: 所有的对象和方法都需要 return 才能在template中使用,写法繁琐,不推荐
1.3 推荐 —— <script setup>
<template>
<div>{{ num }}</div>
<button @click="onClick"> + 1 </button>
</template>
<script setup>
import { ref } from 'vue';
const num = ref(1);
const onClick = () => {
num.value += 1;
};
</script>
总结: 推荐使用第三种写法,简单明了,定义的变量或方法也无需return
才可使用。但需要注意一点
,以前在 data 中创建的属性,现在全都用 ref() 或者 reactive() 声明;在 template 中直接用,在 script 中记得加 .value
二、vue3 中的响应式数据
2.1 ref => 推荐,项目中基本已经够用
针对单个变量,将其变成响应式的数据
import { ref } from 'vue';
// todo...
setup(){
const name = ref('张三') // 不使用ref,name将不是响应式数据
return {
name // 在其他地方改变了name后,页面将同步更改;但在 script 中使用记得加 `.value`
}
}
2.2 reactive
创建响应式数据,返回的是一个对象state。注意,如果直接使用 state.属性名
的方式导出一个属性并且使用到页面中,那么这个属性将不是响应式(state这个对象才是响应式
)
import { reactive } from 'vue';
// todo...
setup(){
const state = reactive({name: '张三'})
return {
// 此时,state是一个对象并且是响应式的,但是里面的name属性却不是响应式的 ==>> 页面中使用:{{state.name}}
state
// 如果在页面中想简单一些直接使用 {{name}},可以这样导出:
name: state.name // 但是,请注意。这样导出的数据在导出时就绑定了值,并不是响应式的数据
}
}
2.3 toRefs
针对对象
,类似解构,解构出来的每一个属性都是响应式的,保证数据是响应式的
// 用法
import { toRefs } from 'vue';
// todo...
setup(){
const state = {
name: '张三',
age: 18
};
return {
...toRefs(state) // 这样里面的每一条属性都是响应式的
}
}
三、props 和 emits
defineProps
和 defineEmits
都是只能在 <script setup>
中使用的编译器宏。它们不需要导入,且会随着 <script setup>
的处理过程一同被编译掉。
3.1 props 属性
声明 props 需要使用用 defineProps()
// Vue3 的写法
<template>
<div>{{ foo }}</div>
</template>
<script setup>
// 注意这里
// defineProps 可在<script setup>直接使用,无需要引入
const props = defineProps({
foo: String
})
// 在 script 标签里使用
console.log(props.foo)
// --------------- 注意:不能结构,会失去响应式效果 -------------
const { foo } = props; // 不要这么写
console.log(foo)
</script>
3.2 emits 事件
与 props 相同,声明 emits 我们可以用 defineEmits()
<template>
<div @click="onClick">
这是一个div
</div>
</template>
<script setup>
// 注意这里
const emit = defineEmits(['add1', 'decre1']);
const onClick = () => {
emit('add1', '参数1', '参数2', '...参数n') // 注意这里
emit('decre1', '参数1', '参数2', '...参数n')
}
</script>
四、computed
<template>
<div>
<span>{{ str }}</span>
<span>{{ reversedValue }}</span>
</div>
</template>
<script setup>
import {ref, computed} from 'vue'
const str = ref('It is a string')
// 注意这里
const reversedValue = computed(() => {
// 使用 ref 需要 .value
return str.value.split('').reverse().join('');
})
</script>
五、watch
vue3 中,watch 有两种写法。一种是直接使用 watch
,还有一种是使用 watchEffect
。
watch
需要你明确指定依赖的变量,才能做到监听效果;即指定监听哪个变量watchEffect
会根据你使用的变量,自动的实现监听效果;类似computed,根据使用的变量实现监听
5.1 使用watch => 更好理解,个人推荐
<template>
<div>{{ count }}</div>
<div>{{ addCount }}</div>
<button @click="onClick"> 增加 1 </button>
</template>
<script setup>
import { ref, watch } from 'vue';
const count = ref(1);
const onClick = () => {
count.value += 1;
};
const addCount = ref(0);
// 注意: 需要明确指定依赖的是 count 这个变量
watch(count, (newValue) => {
addCount.value = newValue + 1;
})
</script>
5.2 使用 watchEffect
// Vue3 的写法
<template>
<div>{{ count }}</div>
<div>{{ addCount }}</div>
<button @click="onClick"> 增加 1 </button>
</template>
<script setup>
import { ref, watchEffect } from 'vue';
const count = ref(1);
const onClick = () => {
count.value += 1;
};
const addCount = ref(0);
// 注意这里
watchEffect(() => {
// 会自动根据 count.value 的变化,
// 触发下面的操作
addCount.value = count.value + 1;
})
</script>
六、methods
// Vue3 的写法
<template>
<div @click="onClick">
这是一个div
</div>
</template>
<script setup>
// script setup 直接定义即可;但如果是写在setup(){} 里面需要return
const onClick = () => {
// ... todo
console.log('clicked')
}
</script>
八、生命周期
Vue3 里,除了将两个 destroy
相关的钩子,改成了 unmount
;剩下需要注意的,就是在 <script setup>
中,不能使用 beforeCreate
和 created
两个钩子。
使用方法:在 setup
里,用 on
开头,加上大写首字母就行
<template>
<div></div>
</template>
<script setup>
import {
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
} from 'vue'
onBeforeMount(() => {})
onMounted(() => {})
onBeforeUpdate(() => {})
onUpdated(() => {})
onBeforeUnmount(() => {})
onUnmounted(() => {})
</script>
九、store和router
vue3 里面因为没有this,所以在页面中route、store、data的使用都和vue2.x都有所区别
- 拿到当前页面的 store 和 route
import { useRoute } from "vue-router";
import { useStore } from "vuex";
export default {
setup(props, context){ // setup 默认只执行一次
const route = useRoute(); // 全是函数式API,调用即可
const store = useStore();
// 然后就可以快乐的使用route和store了
}
}
- setup : 入口,介绍两个参数;props:参数,context:上下文对象(里面包括attr,slots,emit,props等属性和方法)
文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!