系列文章目录
文章目录
一、三连问(为什么)
1、为什么需要用 ref ?
- 返回值类型,会丢失响应式
- 如在 setup、computed、合成函数,都有可能返回值类型
- Vue 如不定义 ref,用户将自造 ref,反而混乱
whyRef.vue 组件
- 值类型无处不在
- vue3 是通过 proxy 实现的响应式,但只对引用类型(数组,对象)有效
- 为使得值类型也实现响应式,ref 便出现了
<template>
<p>why ref demo {
{
state.age }} - {
{
age1 }}</p>
</template>
<script>
import {
toRefs, reactive, computed } from "vue";
function useFeatureX() {
const state = reactive({
x: 1,
y: 2,
});
return toRefs(state);
}
export default {
name: "whyRef",
setup() {
const {
x, y } = useFeatureX();
const state = reactive({
age: 20,
name: "杂货铺",
});
const age1 = computed(() => {
return state.age + 1;
});
setTimeout(() => {
console.log(x.value, y.value);
state.age = 25;
}, 1000);
return {
state,
age1,
};
},
};
</script>
2、为何需要 .value ?
- ref 是一个对象(不丢失响应式),value 存储值
- 通过
.value
属性的 get 和 set 实现响应式 - 用于模板、reactive 时,不需要
.value
,其他情况都需要
3、为什么需要 toRef 和 toRefs ?
- 初衷:不丢失响应式的情况下,把对象数据 分散/扩展(解构)
- 前提:针对的是响应式对象(reactive 封装的)非普通对象
- 注意:不创造 响应式,而是 延续 响应式
二、Vue3 升级了哪些重要的功能
1、createApp
vue2.x 对比 vue3.0
// vue2.x
const app = new Vue({
...})
// vue3
const app = Vue.createApp({
...})
vue2.x 使用对比 vue3.0
// vue2.x
Vue.use(...)
Vue.mixin(...)
Vue.component(...)
Vue.directive(...)
// vue3
app.use(...)
app.mixin(...)
app.component(...)
app.directive(...)
2、emits 属性
App.vue 父组件
- 父组件的子组件标签绑定 onSayHello 自定义事件
- info,是子给父要传递的参数
- 注意绑定的时候必须是
@onXxx
的格式,更容易识别出是监听事件(规则)
<template>
<HelloWorld @onSayHello="sayHello" />
</template>
<script>
import HelloWorld from "./components/HelloWorld.vue";
export default {
methods: {
sayHello(info) {
console.log('hello', info);
}
},
components: {
HelloWorld },
};
</script>
HelloWorld.vue 子组件
- setup里面传两个参数
- 第一个参数 props,获取属性
- 第二个参数是一个对象,对象解构之后是 emit 属性
- 之后通过 emit 调用自定义事件,后面用来传参
<template>
<p>emits 的使用</p>
</template>
<script>
export default {
name: 'HelloWorld',
emits: ['onSayHello'],
setup(props, {
emit }) {
emit('onSayHello', 'vue3')
}
};
</script>
3、生命周期
4、多事件
在 methods 里定义 one two 两个函数
<button @click="one($event), two($event)">Submit</button>
5、Fragment 组件模板
vue2.x 组件模板:多个 html 标签 必须包裹 起来
<template>
<div>
<h3>Hello Vue3</h3>
<p>前端杂货铺</p>
</div>
</template>
vue3.x 组件模板:不需要包裹
<template>
<h3>Hello Vue3</h3>
<p>前端杂货铺</p>
</template>
6、移除 .async
async 可以实现父子组件数据之间的双向绑定,与 v-model 类似
在 Vue2 中一个组件上只能有一个 v-model,而 .sync 修饰符可以有很多个
// vue2.x
<MyComponent v-bind:title.sync="title" />
// vue3.x
<MyComponent v-model:tilte="title">
7、异步组件的写法
Vue2.x 写法
new Vue({
components: {
'my-component': () => import('./xxx.vue')
}
})
Vue 3.x 写法
import {
createApp, defineAsyncComponent } from 'vue'
createApp({
components: {
AsyncComponent: defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
}
})
8、移除 filter
以下 filter 在 vue3 中不可用
{
{
message | capitalize}}
<div v-bind:id="rawId | formatId"></div>
9、Teleport
- 是一种能够将我们的组件 html 结构移动到指定位置的技术
- data 中设置
modalOpen: false
<button @click="modalOpen = true">
打开全屏模式(使用 teleport)
</button>
<teleport to="body">
<div v-if="modalOpen" class="modal">
<div>
telePort 弹窗(父元素是 body)
<button @click="modalOpen = false">关闭弹窗</button>
</div>
</div>
</teleport>
10、Suspense
- 等待异步组件时渲染一些额外内容,让应用有更好的用户体验
<Suspense>
<Test1 /> <!-- 是一个异步组件 -->
<!-- #fallback 就是一个具名插槽
即 Suspense 组件内部,有两个 slot,
其中一个具名为 falllback -->
<template #fallback>
Loading...
</template>
</Suspense>
11、Composition API
- reactive
- ref 相关
- readonly
- watch 和 watchEffect
- setup
- 生命周期钩子函数
不积跬步无以至千里 不积小流无以成江海
点个关注不迷路,持续更新中…