历经了艰难的插值,Vue 3.0总算在上2020-09-18正式发布了,带了巨大变动的变动,采用了Typescript 展开了小规模的解构,增添了Composition API RFC版,类似于React Hook 那样的写Vue,可以自订自己的hook ,让采用者更为的灵巧,接下去归纳呵呵vue 3.0 增添的部分新优点。
setup()ref()reactive()isRef()toRefs()computed()watch()LifeCycle Hooks(捷伊合作开发周期)Template refsglobalPropertiesSuspenseVue2与Vue3的对照
对TypeScript支持不亲善(大部份优点都放到了this第一类上,无法砸毁模块的统计正则表达式)大批的API装载在Vue第一类的蓝本上,无法避免TreeShaking。构架微观对交互式化dom图形合作开发全力支持不亲善CompositionAPI。受ReactHook启迪更方便快捷的全力支持了 jsxVue 3 的 Template 全力支持数个根条码,Vue 2 不全力支持对交互式DOM展开了改写、对模版的校对展开了强化操作方式…一、setup 表达式
setup() 表达式是 vue3 中,专门针对为模块提供更多的新优点。它为我们采用 vue3 的 Composition API 新优点提供更多了标准化的出口处, setup 表达式会在 beforeCreate 、created 以后继续执行, vue3也是中止了这两个钳子,标准化用setup替代, 该表达式相等于两个合作开发周期表达式,vue中往后的data,methods,watch等全数都用相关联的追加api写在setup()表达式中
setup(props, context) {
context.attrs
context.slots
context.emit
return {
}
}
props: 用以转交 props 统计数据context 用以表述语句, 语句第一类中包涵了一些管用的优点,这些优点在 vue 2.x 中需要通过 this 就可以出访到, 在 setup() 表达式中封禁到 this,是个 undefined回到值: return {}, 回到积极响应式统计数据, 模版中须要采用的表达式二、reactive 表达式
reactive() 表达式转交两个一般第一类,回到两个积极响应式的统计数据第一类, 想采用建立的积极响应式统计数据也很单纯,建立出来之后,在setup中return进来,间接在template中初始化方可
<template>
{{name}} // test
<template>
<script lang=”ts”>
import { defineComponent, reactive, ref, toRefs } from vue;
export default defineComponent({
setup(props, context) {
let state = reactive({
name: test
});
return state
}
});
</script>
三、ref() 表达式
ref() 表达式用以根据给定的值建立两个积极响应式的统计数据第一类,ref() 表达式初始化的回到值是两个第一类,这个第一类上只包涵两个 value 优点, 只在setup表达式内部出访ref表达式须要加.value
<template>
<div class=”mine”>
{{count}} // 10
</div>
</template>
<script lang=”ts”>
import { defineComponent, ref } from vue;
export default defineComponent({
setup() {
const count return {
count
}
}
});
</script>
在 reactive 第一类中出访 ref 建立的积极响应式统计数据
<template>
<div class=”mine”>
{{count}} -{{t}} // 10 -100
</div>
</template>
<script lang=”ts”>
import { defineComponent, reactive, ref, toRefs } from vue;
export default defineComponent({
setup() {
const count = ref<number>(10)
const obj = reactive({
t: 100,
count
})
// 通过reactive 来 }
}
});
</script>
四、isRef() 表达式
isRef() 用以判断某个值是否为 ref() 建立出来的第一类
<script lang=”ts”>
import { defineComponent, isRef, ref } from vue;
export default defineComponent({
setup(props, context) {
const name: string = vue
const age = ref<number>(18)
console.log(isRef(age)); // true
console.log(isRef(name)); // false
return {
age,
name
}
}
});
</script>
五、toRefs() 表达式
toRefs() 表达式可以将 reactive() 建立出来的积极响应式第一类,转换为一般的第一类,只不过,这个第一类上的每个优点节点,都是 ref() 类型的积极响应式统计数据
<template>
<div class=”mine”>
{{name}} // test
{{age}} // 18
</div>
</template>
<script lang=”ts”>
import { defineComponent, reactive, ref, toRefs } from vue;
export default defineComponent({
setup(props, context) {
let state = reactive({
name: test
});
const age = ref(18)
return {
…toRefs(state),
age
}
}
});
</script>
六、computed()
该表达式用以创造计算优点,和往后那样,它回到的值是两个ref第一类。 里面可以传方法,或者两个第一类,第一类中包涵set()、get()方法
6.1 建立只读的计算优点
import { computed, defineComponent, ref } from vue;
export default defineComponent({
setup(props, context) {
const age = ref(18)
// 根据 age 的值,建立两个积极响应式的计算优点 readOnlyAge,它会根据依赖的 ref 自动计算并回到两个捷伊 ref
const readOnlyAge = computed(() => age.value++) // 19
return {
age,
readOnlyAge
}
}
});
</script>
6.2 通过set()、get()方法建立两个可读可写的计算优点
<script lang=”ts”>
import { computed, defineComponent, ref } from vue;
export default defineComponent({
setup(props, context) {
const age = ref<number>(18)
const computedAge = computed({
get: () => age.value + 1,
set: value => age.value + value
})
// 为计算优点赋值的操作方式,会触发 set 表达式, 触发 set 表达式后,age 的值会被更新
age.value = 100
return {
age,
computedAge
}
}
});
</script>
七、 watch() 表达式
watch 表达式用以侦听特定的统计数据源,并在回调表达式中继续执行副作用。默认情况是懒继续执行的,也就是说仅在侦听的源统计数据变更时才继续执行回调。
7.1 监听用reactive声明的统计数据源
<script lang=”ts”>
import { computed, defineComponent, reactive, toRefs, watch } from vue;
interface Person {
name: string,
age: number
}
export default defineComponent({
setup(props, context) {
const state = reactive<Person>({ name: vue, age: 10 })
watch(
() => state.age,
(age, preAge) => {
console.log(age); // 100
console.log(preAge); // 10
}
)
// 修改age 时会触发watch 的回调, 打印变更前后的值
state.age = 100
return {
…toRefs(state)
}
}
});
</script>
7.2 监听用ref声明的统计数据源
<script lang=”ts”>
import { defineComponent, ref, watch } from vue;
interface Person {
name: string,
age: number
}
export default defineComponent({
setup(props, context) {
const age = ref<number>(10);
watch(age, () => console.log(age.value)); // 100
// 修改age 时会触发watch 的回调, 打印变更后的值
age.value = 100
return {
age
}
}
});
</script>
7.3 同时监听数个值
<script lang=”ts”>
import { computed, defineComponent, reactive, toRefs, watch } from vue;
interface Person {
name: string,
age: number
}
export default defineComponent({
setup(props, context) {
const state = reactive<Person>({ name: vue, age: 10 })
watch(
[() => state.age, () => state.name],
([newName, newAge], [oldName, oldAge]) => {
console.log(newName);
console.log(newAge);
console.log(oldName);
console.log(oldAge);
}
)
// 修改age 时会触发watch 的回调, 打印变更前后的值, 此时须要注意, 更改其中两个值, 都会继续执行watch的回调
state.age = 100
state.name = vue3
return {
…toRefs(state)
}
}
});
</script>
7.4 stop 停止监听
在 setup() 表达式内建立的 watch 监视,会在当前模块被销毁的时候自动停止。如果想明确地停止某个监视,可以初始化 watch() 表达式的回到值方可,语法如下:
<script lang=”ts”>
import { set } from lodash;
import { computed, defineComponent, reactive, toRefs, watch } from vue;
interface Person {
name: string,
age: number
}
export default defineComponent({
setup(props, context) {
const state = reactive<Person>({ name: vue, age: 10 })
const stop = watch(
[() => state.age, () => state.name],
([newName, newAge], [oldName, oldAge]) => {
console.log(newName);
console.log(newAge);
console.log(oldName);
console.log(oldAge);
}
)
// 修改age 时会触发watch 的回调, 打印变更前后的值, 此时须要注意, 更改其中两个值, 都会继续执行watch的回调
state.age = 100
state.name = vue3
setTimeout(()=> {
stop()
// 此时修改时, 不会触发watch 回调
state.age = 1000
state.name = vue3-
}, 1000) // 1秒之后讲中止watch的监听
return {
…toRefs(state)
}
}
});
</script>
八、LifeCycle Hooks(捷伊心灵后期)
新版的合作开发周期表达式,可以按需导入到模块中,且只能在 setup() 表达式中采用, 但是也可以在setup 外表述, 在 setup 中采用
<script lang=”ts”>
import { set } from lodash;
import { defineComponent, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onErrorCaptured, onMounted, onUnmounted, onUpdated } from vue;
export default defineComponent({
setup(props, context) {
onBeforeMount(()=> {
console.log(beformounted!)
})
onMounted(() => {
console.log(mounted!)
})
onBeforeUpdate(()=> {
console.log(beforupdated!)
})
onUpdated(() => {
console.log(updated!)
})
onBeforeUnmount(()=> {
console.log(beforunmounted!)
})
onUnmounted(() => {
console.log(unmounted!)
})
onErrorCaptured(()=> {
console.log(errorCaptured!)
})
return {}
}
});
</script>
九、Template refs
通过refs 来回去真实dom元素, 这个和react 的用法那样,为了获得对模版内元素或模块实例的引用,我们可以像往常那样在setup()中声明两个ref并回到它
还是跟往常那样,在 htm<template>
<!–第一步:还是跟往常那样,在 html 中写入 ref 的名称–>
<div class=”mine” ref=”elmRefs”>
<span>1111</span>
</div>
</template>
<script lang=”ts”>
import { set } from lodash;
import { defineComponent, onMounted, ref } from vue;
export default l | HTMLElement>(null);
onMounted (() => {
console.log(elmRefs.value); // 得到两个 RefImpl 的第一类, 通过 .value 出访到统计数据
})
return {
elmRefs
}
}
});
</script>
十、vue 的全局配置
通过vue 实例上config来配置,包涵Vue应用程序全局配置的第一类。您可以在装载应用程序以后修改下面列出的优点:
const app = Vue.createApp({})
app.config = {…}
为模块图形功能和观察程序期间的未捕获错误分配处理程序。错误和应用程序实例将初始化处理程序
app.config.errorHandler = (err, vm, info) => {}
可以在应用程序内的任何模块实例中出访的全局优点,模块的优点将具有优先权。这可以替代Vue 2.xVue.prototype扩展:
const app = Vue.createApp({})
app.config.globalProperties.$http = xxxxxxxxs
可以在模块用通过 getCurrentup中采用router和vuex, 通过这个优点我们就可以操作方式变量、全局优点、模块优点等等
setup( ) {
const { ctx } = getCurrentInstance();
ctx.$http
}
十一、Suspense 模块
在开始介绍 Vue 的 Suspense 模块以后,我们有必要先了解呵呵 React 的 Suspense 模块,因为他们的功能类似于。
React.lazy 接受两个表达式,这个表达式须要动态初始化 import()。它必须回到两个 Promise,该 Promise 须要 resolve 两个 default export 的 React 模块。
import React, { Suspense } from react;
const myComponent = React.lazy(() => import(./Component));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading…</div>}>
<myComponent />
</Suspense>
</div>
);
}
Vue3 也追加了 React.lazy 类似于功能的 defineAsyncComponent 表达式,处理动态引入(的模块)。defineAsyncComponent可以接受回到承诺的工厂表达式。当您从服务器检索到模块表述时,应该初始化Promise的解析回调。您还可以初始化reject(reason)来指示负载已经失败
import { defineAsyncComponent } from vue
const AsyncComp = defineAsyncComponent(() =>
import(./components/AsyncComponent.vue)
)
app.component(async-component, AsyncComp)
Vue3 也追加了 Suspense 模块:
<template>
<Suspense>
<template #default>
<my-component />
</template>
<template #fallback>
Loading …
</template>
</Suspense>
</template>
<script lang=ts>
import { defineComponent, defineAsyncComponent } from “vue”;
const MyComponent = defineAsyncComponent(() => import(./Component));
export default defineComponent({
components: {
MyComponent
},
setup() {
return {}
}
})
</script>
十二、vue 3.x 完整模块模版结构
两个完成的vue 3.x 完整模块模版结构包涵了:模块名称、 props、components、setup(hooks、computed、watch、methods 等)
<template>
<div class=”mine” ref=”elmRefs”>
<span>{{name}}</span>
<br>
<span>{{count}}</span>
<div>
<button @click=”handleClick”>测试按钮</button>
</div>
<ul>
<li v-for=”item in list” :key=”item.id”>{{item.name}}</li>
</ul>
</div>
</template>
<script lang=”ts”>
import { computed, defineComponent, getCurrentInstance, onMounted, PropType, reactive, ref, toRefs } from vue;
interface IState {
count: 0,
name: string,
list: Array<object>
}
export default defineComponent({
name: demo,
// 父模块传子模块参数
props: {
name: {
type: String as PropType<null | >,
default: vue3.x
},
list: {
type: Array as PropType<object[]>,
default: () => []
}
},
components: {
/// TODO 模块注册
},
emits: [“emits-name”], // 为了提示作用
setup (props, context) {
console.log(props.name)
console.log(props.list)
const state = reactive<IState>({
name: vue 3.0 模块,
count: 0,
list: [
{
name: vue,
id: 1
},
{
name: vuex,
id: 2
}
]
})
const a = computed(() => state.name)
onMounted(() => {
})
function handleClick () {
state.count ++
// 初始化父模块的方法
context.emit(emits-name, state.count)
}
return {
…toRefs(state),
handleClick
}
}
});
</script>
vue 3 的生态
官网源码vite构建器脚手架:https://cli.vuejs.org/vue-router-nextvuex4.0
UI 模块库
vant2.xAnt Design of Vue 2.xelement-plus
作者:撒点料儿
链接:https://juejin.im/post/6887359442354962445
著作权归作者大部份。商业转载请联系作者获得授权,非商业转载请注明出处。