vue命令,插件
前言下面介绍一些vue的技巧,使用起来更方便,提高效率!vue指令在vue代码中很常见,比如v-model、v-bind、v-on等,官方也提供了缩写。目标是弄清楚v-xx的含义,以及如何封装自定义指令1:代码中之所以可以使用v-focus是因为下面的指令是全局注册的//指令使用baby
//注册一个全局自定义指令`v-focus`Vue.directive('focus',{//当绑定的元素被插入到DOM中时...inserted:function(el){//焦点元素el.focus()}})//也可以在本地注册,在组件中//因为本地注册时的可复用逻辑,所以一般放在mixin指令中:{focus:{//指令Defineinserted:function(el){el.focus()}}}2:看到上面的写法,自然需要注意提供的钩子函数和可选参数钩子函数,有点类似到组件的生命周期。一个指令定义对象可以提供以下钩子函数(都是可选的):bind:只调用一次,当指令第一次绑定到元素上时。可以在这里进行一次性的初始化设置。inserted:绑定元素插入到父节点时调用(只保证父节点存在,不一定插入到文档中)。update:组件的VNode更新时调用,但也有可能发生在其子VNode更新之前。指令的值可能已更改,也可能未更改。但是可以通过比较更新前后的值来忽略不必要的模板更新(钩子函数参数详见下文)。componentUpdated:命令所在组件的VNode及其子VNode全部更新后调用。unbind:仅在指令与元素解除绑定时调用一次。可选参数el:指令绑定的元素,可用于直接操作DOM。Vue虽然希望是数据驱动,但在某些场景下还是需要操作dom,但是需要保证dom的渲染更新,需要配合nextTickbinding:一个包含以下属性的对象:name:指令名称,不包括v-前缀。value:指令的绑定值,例如:在v-my-directive="1+1"中,绑定值为2。oldValue:指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否已更改均可用。expression:字符串形式的指令表达式。例如,在v-my-directive="1+1"中,表达式为"1+1"。arg:传递给命令的参数,可选。例如,在v-my-directive:foo中,参数是“foo”。修饰符:包含修饰符的对象。例如:在v-my-directive.foo.bar中,修饰符对象为{foo:true,bar:true}。vnode:vue编译生成的虚拟节点,是vue组件的产物,也叫virtualdomoldvnode:之前的虚拟节点,只有update和componentUpdatedhooks才有。一般两者的比较只涉及打补丁的过程3:可以看到命令主要涉及dom元素的获取和属性的赋值。不要滥用自定义命令!4:移动端无限加载指令示例下拉一定距离加载数据//使用
constloadMore={directives:{'load-更多':{bind:(el,binding)=>{让windowHeight=window.screen.height;//屏幕高度letheight;让置顶;让paddingBottom;让marginBottom;让请求框架;让oldScrollTop;让scrollEl;让heightEl;//获取元素属性letscrollType=el.attributes.type&&el.attributes.type.value;让scrollReduce=2;//这是一个缓冲值,处理手指滑动到实际移动的距离//根据类型判断滚动对象if(scrollType==2){scrollEl=el;heightEl=el.children[0];}else{scrollEl=document.body;heightEl=el;}//三阶段移动事件处理el.addEventListener('touchstart',()=>{height=heightEl.clientHeight;if(scrollType==2){height=height}//返回当前元素相对的距离到元素的offsetParent的顶部setTop=el.offsetTop;paddingBottom=getStyle(el,'paddingBottom');marginBottom=getStyle(el,'marginBottom');},false)el.addEventListener('touchmove',()=>{loadMore();},false)el.addEventListener('touchend',()=>{oldScrollTop=scrollEl.scrollTop;moveEnd();},false)constmoveEnd=()=>{requestFrame=requestAnimationFrame(()=>{如果(scrollEl.scrolllTop!=oldScrollTop){oldScrollTop=scrollEl.scrollTop;moveEnd()}else{cancelAnimationFrame(requestFram);height=heightEl.clientHeight;装载更多();}})}constloadMore=()=>{//滚动值逻辑触发loadmoreif(scrollEl.scrollTop+windowHeight>=height+setTop+paddingBottom+marginBottom-scrollReduce){//函数调用binding.value()实际绑定遵照指示;}}}}};5:好奇v-model背后做了什么?基于上面的理解,我们可以一步步实现v-modelv-model的作用。在
的写法下修改代码中的text值,输入框显示model->view发生变化。,直接在输入框修改显示值,监听onchange事件,打印文本值,修改model->view从数据流的角度来看,vue是单向流,v-的实现模型只是一个语法糖。我们其实还是按照model->view。//数据到模板的vue部分已经做好了{this.text=binding.value//文本的修改触发视图的改变,其实是数据驱动},false)}}}插件插件的使用比指令更广泛,而且plugins的目的是全局使用,它的install方法决定了在vue实例上挂载相应的属性plugin,通常会为Vue增加全局功能。插件的范围不限——一般有以下几种:1、添加全局方法或属性,如:vue-custom-element2、添加全局资源:instructions/filters/transitions等,如作为vue-touch3。通过全局mixin方法添加一些组件选项,比如:vue-router4。通过将它们添加到Vue.prototype来添加Vue实例方法。5.提供自己的API并提供上述一个或多个功能的库,例如vue-router。我们知道,在注册插件的时候,一般都是vue.use(xxxplugin)来安装Vue.js插件。如果插件是对象,则必须提供安装方法。如果插件是一个函数,它将被用作安装方法。在调用install方法时,会将Vue作为参数传入。install其实是一种手动提供vue实例全局挂载的方式,可以是命令,全局方法,属性等,这个要看提供的xxxplugin的形式。别问,它会在全球范围内生效!exportfunctioninitUse(Vue:GlobalAPI){//use的参数是一个函数或对象Vue.use=function(plugin:Function|Object){//检查constinstalledPlugins=(this._installedPlugins||(this._installedPlugins=[]))if(installedPlugins.indexOf(plugin)>-1){returnthis}//附加参数//除插件外提供的参数数组constargs=toArray(arguments,1)//head是Vue实例参数。unshift(this)if(typeofplugin.install==='function'){//执行obj本身的安装plugin.install.apply(plugin,args)}elseif(typeofplugin==='function''){//如果没有,直接执行pluginasInstallplugin.apply(null,args)}installedPlugins.push(plugin)returnthis}}参考https://segmentfault.com/a/1190000016256277(使用源码)https//segmentfault.com/a/1190000012827871(vue指令介绍)https://segmentfault.com/a/1190000012823043(过滤器参考)