最近 vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并发布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前体验 Vue 3.0 版本的 Function-based component api。笔者出于学习的目的,提前在项目中尝试了vue-function-api。
笔者计划写两篇文章,本文为笔者计划的第一篇,主要为笔者在体验 Vue Function API 的学习心得。第二篇计划写阅读vue-function-api的核心部分代码原理,包括setup、observable、lifecycle。
Vue 2.x 及以前的高阶组件的组织形式或多或少都会面临一些问题,特别是在需要处理重复逻辑的项目中,一旦开发者组织项目结构组织得不好,组件代码极有可能被人诟病为“胶水代码”。而在 Vue 2.x 及之前的版本,解决此类问题的办法大致是下面的方案:
笔者维护的项目也需要处理大量复用逻辑,在这之前,笔者一直尝试使用mixin的方式来实现组件的复用。有些问题也一直会对开发者和维护者造成困惑,如一个组件同时mixin多个组件,很难分清对应的属性或方法写在哪个mixin里。其次,mixin的命名空间冲突也可能造成问题。难以保证不同的mixin不用到同一个属性名。为此,官方团队提出函数式写法的意见征求稿,也就是RFC:Function-based component API。使用函数式的写法,可以做到更灵活地复用组件,开发者在组织高阶组件时,不必在组件组织上考虑复用,可以更好地把精力集中在功能本身的开发上。
注:本文只是笔者使用vue-function-api提前体验 Vue Function API ,而这个 API 只是 Vue 3.0 的 RFC,而并非与最终 Vue 3.x API 一致。发布后可能有不一致的地方。
要想提前在Vue 2.x中体验 Vue Function API ,需要引入vue-function-api,基本引入方式如下:
import Vue from 'vue';
import { plugin as VueFunctionApiPlugin } from 'vue-function-api';
Vue.use(VueFunctionApiPlugin);
先来看一个基本的例子:
<template>
<div>
<span>count is {{ count }}</span>
<span>plusOne is {{ plusOne }}</span>
<button @click="increment">count++</button>
</div>
</template>
<script>
import Vue from 'vue';
import { value, computed, watch, onMounted } from 'vue-function-api';
export default {
setup(props, context) {
// reactive state
const count = value(0);
// computed state
const plusOne = computed(() => count.value + 1);
// method
const increment = () => {
count.value++;
};
// watch
watch(
() => count.value * 2,
val => {
console.log(`count * 2 is ${val}`);
}
);
// lifecycle
onMounted(() => {
console.log(`mounted`);
});
// expose bindings on render context
return {
count,
plusOne,
increment,
};
},
};
</script>
setup函数是Vue Function API 构建的函数式写法的主逻辑,当组件被创建时,就会被调用,函数接受两个参数,分别是父级组件传入的props和当前组件的上下文context。看下面这个例子,可以知道在context中可以获取到下列属性值:
const MyComponent = {
props: {
name: String
},
setup(props, context) {
console.log(props.name);
// context.attrs
// context.slots
// context.refs
// context.emit
// context.parent
// context.root
}
}
value函数创建一个包装对象,它包含一个响应式属性value:
那么为何要使用value呢,因为在JavaScript中,基本类型并没有引用,为了保证属性是响应式的,只能借助包装对象来实现,这样做的好处是组件状态会以引用的方式保存下来,从而可以被在setup中调用的不同的模块的函数以参数的形式传递,既能复用逻辑,又能方便地实现响应式。
直接获取包装对象的值必须使用.value,但是,如果包装对象作为另一个响应式对象的属性,Vue内部会通过proxy来自动展开包装对象。同时,在模板渲染的上下文中,也会被自动展开。
import { state, value } from 'vue-function-api';
const MyComponent = {
setup() {
const count = value(0);
const obj = state({
count,
});
console.log(obj.count) // 作为另一个响应式对象的属性,会被自动展开
obj.count++ // 作为另一个响应式对象的属性,会被自动展开
count.value++ // 直接获取响应式对象,必须使用.value
return {
count,
};
},
template: `<button @click="count++">{{ count }}</button>`,
};
如果某一个状态不需要在不同函数中被响应式修改,可以通过state创建响应式对象,这个state创建的响应式对象并不是包装对象,不需要使用.value来取值。
watch和computed的基本概念与 Vue 2.x 的watch和computed一致,watch可以用于追踪状态变化来执行一些后续操作,computed用于计算属性,用于依赖属性发生变化进行重新计算。
computed返回一个只读的包装对象,和普通包装对象一样可以被setup函数返回,这样就可以在模板上下文中使用computed属性。可以接受两个参数,第一个参数返回当前的计算属性值,当传递第二个参数时,computed是可写的。
import { value, computed } from 'vue-function-api';
const count = value(0);
const countPlusOne = computed(() => count.value + 1);
console.log(countPlusOne.value); // 1
count.value++;
console.log(countPlusOne.value); // 2
// 可写的计算属性值
const writableComputed = computed(
// read
() => count.value + 1,
// write
val => {
count.value = val - 1;
},
);
watch第一个参数和computed类似,返回被监听的包装对象属性值,不过另外需要传递两个参数:第二个参数是回调函数,当数据源发生变化时触发回调函数,第三个参数是options。其默认行为与 Vue 2.x 有所不同:
// double 是一个计算包装对象
const double = computed(() => count.value * 2);
watch(double, value => {
console.log('double the count is: ', value);
}); // -> double the count is: 0
count.value++; // -> double the count is: 2
当watch多个被包装对象属性时,参数均可以通过数组的方式进行传递,同时,与 Vue 2.x 的vm.$watch一样,watch返回取消监听的函数:
const stop = watch(
[valueA, () => valueB.value],
([a, b], [prevA, prevB]) => {
console.log(`a is: ${a}`);
console.log(`b is: ${b}`);
}
);
stop();
注意:在RFC:Function-based component API初稿中,有提到effect-cleanup,是用于清理一些特殊情况的副作用的,目前已经在提案中被取消了。
所有现有的生命周期都有对应的钩子函数,通过onXXX的形式创建,但有一点不同的是,destoryed钩子函数需要使用unmounted代替:
import { onMounted, onUpdated, onUnmounted } from 'vue-function-api';
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!');
});
onUpdated(() => {
console.log('updated!');
});
// destroyed 调整为 unmounted
onUnmounted(() => {
console.log('unmounted!');
});
},
};
上面的详解部分,主要抽取的是 Vue Function API 的常见部分,并非RFC:Function-based component API的全部,例如其中的依赖注入,TypeScript类型推导等优势,在这里,由于篇幅有限,想要了解更多的朋友,可以点开RFC:Function-based component API查看。个人也在Function-based component API讨论区看到了更多地一些意见:
setup() {
const state = reactive({
count: 0,
});
const double = computed(() => state.count * 2);
function increment() {
state.count++;
}
return {
...toBindings(state), // retains reactivity on mutations made to `state`
double,
increment,
};
}
下一篇文章中,笔者将阅读vue-function-api的核心部分代码原理,包括setup、observable、lifecycle等,从内部探索 Vue Function API 可能带给我们的改变。
当然,目前 Vue Function API 还处在讨论阶段,Vue 3.0 还处在开发阶段,还是期待下半年 Vue 3.0 的初版问世吧,希望能给我们带来更多的惊喜。
原文来自:https://segmentfault.com/a/1190000020038527
在 Native 开发中,Android 和 IOS 平台都在系统层面直接提供给了应用开发识别图像的一些能力,比如对于二维码/条形码的识别,Android 可以使用 barcode API 、 iOS 可以使用 CIQRCodeFeature API 。
Js的API设计原则总共包含了七个大块。系卤煮自己总结的一些经验和教训。本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来。很难做到详尽充实,如果有好的建议或者不对的地方,还望不吝赐教斧正。
现在越来越流行前后端分离开发,使用ajax交互。所以api接口文档就变的十分有意义了,目前市场有哪些比较优秀的接口文档管理工具呢?比如:MinDoc,eoLinker,apizza,RAML,Swagger等等
无论网站,还是App目前基本都是基于api接口模式的开发,那么api的安全就尤为重要了。目前攻击最常见的就是“短信轰炸机”,由于短信接口验证是App,网站检验用户手机号最真实的途径,使用短信验证码在提供便利的同时,也成了呗恶意攻击的对象,那么如何才能防止被恶意调用呢?
整理提供最新的各种免费JSON接口,其中有部分需要用JSONP调用。方面前端同学的学习或在网站中的使用,包括:免费的天气预报、地图、IP、手机信息查询、翻译、新闻等api接口
要弄清楚什么是RESTful API,首先要弄清楚什么是REST。REST -- REpresentational State Transfer,英语的直译就是“表现层状态转移”。如果看这个概念,估计没几个人能明白是什么意思。
Fetch API 已经作为现代浏览器中异步网络请求的标准方法,其使用 Promise 作为基本构造要素。Fetch 在主流浏览器中都有很好的支持,除了IE。
随着移动互联网的发展, 基于互联网的应用正变得越来越普及,在这个过程中,更多的平台将自身的资源开放给开发者来调用。对外提供的API 调用使得平台之间的内容关联性更强,同时这些开放的平台也为用户、开发者和中小网站带来了更大的价值。
环境centos,添加deamon.json后,dockerd命令可以启动docker,这时请求 127.0.0.1:2375 可以正常访问,使用systemctl无法启动docker的情况.无法启动docker:查看当前的docker配置
你是否正在设计第一个Web应用程序?也许你过去已经建立了一些,但是目前也正在寻找语言的变化以提高你的技能,或尝试新的东西。有了所有信息,就很难决定为下一个产品或项目选择哪种编程语言。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!