您的位置:

首页 >

网页技巧 >

vue.js中指令Directives详解 >

vue.js中指令Directives详解

2016-03-01 09:30:36

分类:网页技巧

想必喜欢前端开发的小伙伴们都或多或少接触过MVVM这个概念,说起MVVM,第一时间想到的便是angularjs,knockoutjs等已经被广泛运用的MVVM框架,之前我也没有在这方面有很多了解,最近在做项目的过程中接触了Vue.js,这是一个小巧精致,性能优异的MVVM框架,可以说对初学者是比较容易入门的,该框架的英文文档写得很好,但是中文版访问还不太稳定,翻译也有待改进,所以自己一遍学习,一遍记录自己的思考,与各位共享学习的经验。 第一篇主要是想谈谈vue.js中的Directives即指令,在vue.js中指令就是一个通知库进行某些具体的dom操作的口令,在html中表现为如下形式:<element prefix-directiveId="[argument:] expression [| filters...]"></element>Directives分为1.Reactive Directives、2.Literal Directives、3.Empty Directives,下面结合具体的api阐述他们的作用:1.Reactive Directives(响应式指令)Reactive Directives可以绑定在Vue实例或者在Vue实例上下文中求值的表达式上,当绑定的对象发生改变时,指令中的update()会在下一个系统单位时间发生异步响应,我们来看看具体的用法:v-text:更新元素的textContent,事实上在html中{{mustache}}形式的插入值也会被编译为针对一个textNode的v-text指令。v-html:更新元素的innerHTML,由于可能插入恶意代码,使用时要注意保证来源安全。v-show:根据绑定值的true或false来决定所在元素在网页中正常显示还是显示为空。v-class:这个指令有一个可选参数,无参数时将绑定值(一般为class名)添加到所在元素的classlist当中,并且一旦检测绑定值有改动,便随之改变classlist里对应的class;提供参数时参数的true或false将决定绑定值(class)是否被添加到所在元素的classlist中,示例如下:<span v-class=" red : hasError, bold : isImportant, hidden : isHidden"></span>v-attr:更新所在元素的某些属性(由参数表示)。<canvas v-attr="width:w, height:h"></canvas>v-style:更新所在元素的样式,会智能添加浏览器供应商前缀,方便我们书写样式。这个指令有一个可选参数,无参数时,若绑定值为String则将绑定值设置为元素的style.cssText,若绑定值为Object则将Object中的样式键值对放入元素的style object当中;<div v-style="myStyles"></div>// myStyles can either be a String:"color:red; font-weight:bold;"// or an Object:{ color: 'red', // both camelCase and dash-case works fontWeight: 'bold', 'font-size': '2em'}提供参数时,参数指明了css属性的对应值:<div v-style=" top: top + 'px', left: left + 'px', background-color: 'rgb(0,0,' + bg + ')'"></div>v-on:为元素添加并更新事件监听器,参数可以是一个处理函数或者一个函数语句。<div id="demo"> <a v-on="click: onClick">Trigger a handler</a> <a v-on="click: n++">Trigger an expression</a></div>我们可以为处理函数提供参数,其中this指的是当前的ViewModel,如下例中通过传入this参数改变元素的text值:<ul id="list"> <li v-repeat="items" v-on="click: toggle(this)">{{text}}</li></ul>new Vue({ el: '#list', data: { items: [ { text: 'one', done: true }, { text: 'two', done: false } ] }, methods: { toggle: function (item) { item.done = !item.done } }})我们还可以传入$event表示触发处理函数的DOM事件,如下例传入$event阻止事件冒泡:<button v-on="click: submit('hello!', $event)">Submit</button>/* ... */{ methods: { submit: function (msg, e) { e.stopPropagation() } }}/* ... */在监听键盘事件时由于要判断按键值,可以结合filter写成如下两种形式:<!-- only call vm.submit() when the keyCode is 13 --><input v-on="keyup:submit | key 13"><!-- same as above --><input v-on="keyup:submit | key enter">当ViewModel销毁时,v-on绑定的事件会自动消除,我们不必亲自去清理这些绑定事件,这也防止了内存的泄露。 v-model:为表单元素创建一个双向绑定,详细介绍请看这里 v-if:根据绑定值的true或false来插入或移除元素,如例子中我们将根据test的正确与否决定两个<p>元素是否插入<template>当中<template v-if="test"> <p>hello</p> <p>world</p></template> v-repeat:为绑定数组或对象中的每一个item创建一个子ViewModel,或者为绑定的数字值创建对应数量的子ViewModel。并根据绑定值的改变随时更新。没有提供参数时子ViewModel会直接使用绑定数组中的分配单元作为它的$data,如果值不是一个对象,则会创建一个数据包装对象,而值会被设置在别名为$value的 key 上。<ul> <li v-repeat="users"> {{name}} {{email}} </li></ul>如果提供了参数,我们将创建一个数据包装对象,将参数作为对象的key,从而访问对象模板中的属性:<ul> <li v-repeat="user : users"> {{user.name}} {{user.email}} </li></ul>v-with:这个指令只能结合接下来讲到的v-component指令使用,作用是让子ViewModel可以继承父ViewModel的数据,我们可以传入父ViewModel的属性对象或单个属性,在子ViewModel中访问:// parent data looks like this{ user: { name: 'Foo Bar', email: '[email protected]' }}继承对象:<my-component v-with="user"> <!-- you can access properties without `user.` --> {{name}} {{email}}</my-component>继承单个属性:<my-component v-with="myName: user.name, myEmail: user.email"> <!-- you can access properties with the new keys --> {{myName}} {{myEmail}}</my-component>v-events:这个指令也只能结合接下来讲到的v-component指令使用,它使得父ViewModel能够监听子ViewModel上的事件,我们要注意区分v-on与v-events,v-events监听的是通过vm.$emit()创建的 Vue 组件系统事件,而不是 DOM 事件。我们举例说明:<!-- inside parent template --><div v-component="child" v-events="change: onChildChange"></div>当子ViewModel调用this.$emit('change', …)时会触发父ViewModel的onChildChange()方法,并且把emit函数中附加的参数传给onChildChange()方法。 2.Literal Directives(字面指令)字面指令并没有绑定到某一个对象上,字面指令是把它们的参数作为纯字符串传给bind()函数中执行一次,字面指令可以接受{{mustache}}表达式,但是该表达式只会在编译阶段执行一次,不会绑定数据的改变:下面看一看具体的api:v-component:之前提到过,这是使用我们提前声明并注册好的组件构造器将当前元素编译为子ViewModel,从而实现数据继承,之后的文章会详细介绍组件系统。 v-ref:在父ViewModel中创建子ViewModel的引用,方便父ViewModel中的$对象访问子组件:<div id="parent"> <div v-component="user-profile" v-ref="profile"></div></div>var parent = new Vue({ el: '#parent' })// 访问子组件var child = parent.$.profile这个指令只能与v-component和v-repeat一起使用,与v-repeat一起使用时,其value是与绑定数据数组对应的子组件数组。 v-el:为当前dom元素创建一个引用,供其自身vue实例使用,例如<div v-el="hi">可以使得vm.$$.hi访问到该dom元素 v-partial:将当前dom元素中的innerHTML替换为事先注册的partial,有两种写法,{{ mustache}}可以让dom元素随数据改变而更新: <!-- content will change based on vm.partialId --><div v-partial="{{partialId}}"></div>另一种写法则没有数据跟随更新的效果:<div>{{> my-partial}}</div>v-transition:为当前dom元素在指定参数值作用时添加动画效果,后续文章会详细介绍 3.Empty Directives(字面指令)v-pre:这个指令是通知编译器跳过当前dom元素和其所有子元素,这是为了在我们编程过程中对无需编译的元素节省编译时间v-cloak:在当前元素编译完成之前改指令都会存在,我们一般使用这个指令来在元素编译未完成时隐藏原始的 {{ Mustache }} 模板,可以在css中这样写:[v-cloak] { display: none }以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的。原型链首先得要明白什么是原型链,在一篇文章看懂proto和prototype的关系及区别中讲得非常详细原型链继承基本思想就是让一个原型对象指向另一个类型的实例function SuperType() { this.property = true } SuperType.prototype.getSuperValue = function () { return this.property } function SubType() { this.subproperty = false } SubType.prototype = new SuperType() SubType.prototype.getSubValue = function () { return this.subproperty } var instance = new SubType() console.log(instance.getSuperValue()) // true 代码定义了两个类型SuperType和SubType,每个类型分别有一个属性和一个方法,SubType继承了SuperType,而继承是通过创建SuperType的实例,并将该实例赋给SubType.prototype实现的。实现的本质是重写原型对象,代之以一个新类型的实例,那么存在SuperType的实例中的所有属性和方法,现在也存在于SubType.prototype中了。我们知道,在创建一个实例的时候,实例对象中会有一个内部指针指向创建它的原型,进行关联起来,在这里代码SubType.prototype = new SuperType(),也会在SubType.prototype创建一个内部指针,将SubType.prototype与SuperType关联起来。所以instance指向SubType的原型,SubType的原型又指向SuperType的原型,继而在instance在调用getSuperValue()方法的时候,会顺着这条链一直往上找。添加方法在给SubType原型添加方法的时候,如果,父类上也有同样的名字,SubType将会覆盖这个方法,达到重新的目的。 但是这个方法依然存在于父类中。记住不能以字面量的形式添加,因为,上面说过通过实例继承本质上就是重写,再使用字面量形式,又是一次重写了,但这次重写没有跟父类有任何关联,所以就会导致原型链截断。function SuperType() { this.property = true } SuperType.prototype.getSuperValue = function () { return this.property } function SubType() { this.subproperty = false } SubType.prototype = new SuperType() SubType.prototype = { getSubValue:function () { return this.subproperty } } var instance = new SubType() console.log(instance.getSuperValue()) // error 问题单纯的使用原型链继承,主要问题来自包含引用类型值的原型。function SuperType() { this.colors = ['red', 'blue', 'green'] } function SubType() { } SubType.prototype = new SuperType() var instance1 = new SubType() var instance2 = new SubType() instance1.colors.push('black') console.log(instance1.colors) // ["red", "blue", "green", "black"] console.log(instance2.colors) // ["red", "blue", "green", "black"] 在SuperType构造函数定义了一个colors属性,当SubType通过原型链继承后,这个属性就会出现SubType.prototype中,就跟专门创建了SubType.prototype.colors一样,所以会导致SubType的所有实例都会共享这个属性,所以instance1修改colors这个引用类型值,也会反映到instance2中。借用构造函数此方法为了解决原型中包含引用类型值所带来的问题。这种方法的思想就是在子类构造函数的内部调用父类构造函数,可以借助apply()和call()方法来改变对象的执行上下文function SuperType() { this.colors = ['red', 'blue', 'green'] } function SubType() { // 继承SuperType SuperType.call(this) } var instance1 = new SubType() var instance2 = new SubType() instance1.colors.push('black') console.log(instance1.colors) // ["red", "blue", "green", "black"] console.log(instance2.colors) // ["red", "blue", "green"] 在新建SubType实例是调用了SuperType构造函数,这样以来,就会在新SubType对象上执行SuperType函数中定义的所有对象初始化代码。结果,SubType的每个实例就会具有自己的colors属性的副本了。传递参数借助构造函数还有一个优势就是可以传递参数function SuperType(name) { this.name = name } function SubType() { // 继承SuperType SuperType.call(this, 'Jiang') this.job = 'student' } var instance = new SubType() console.log(instance.name) // Jiang console.log(instance.job) // student 问题如果仅仅借助构造函数,方法都在构造函数中定义,因此函数无法达到复用组合继承(原型链+构造函数)组合继承是将原型链继承和构造函数结合起来,从而发挥二者之长的一种模式。思路就是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。function SuperType(name) { this.name = name this.colors = ['red', 'blue', 'green'] } SuperType.prototype.sayName = function () { console.log(this.name) } function SubType(name, job) { // 继承属性 SuperType.call(this, name) this.job = job } // 继承方法 SubType.prototype = new SuperType() SubType.prototype.constructor = SuperType SubType.prototype.sayJob = function() { console.log(this.job) } var instance1 = new SubType('Jiang', 'student') instance1.colors.push('black') console.log(instance1.colors) //["red", "blue", "green", "black"] instance1.sayName() // 'Jiang' instance1.sayJob() // 'student' var instance2 = new SubType('J', 'doctor') console.log(instance2.colors) // //["red", "blue", "green"] instance2.sayName() // 'J' instance2.sayJob() // 'doctor' 这种模式避免了原型链和构造函数继承的缺陷,融合了他们的优点,是最常用的一种继承模式。原型式继承借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。function object(o) { function F() {} F.prototype = o return new F() } 在object函数内部,先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。本质上来说,object对传入其中的对象执行了一次浅复制。var person = { name: 'Jiang', friends: ['Shelby', 'Court'] } var anotherPerson = object(person) console.log(anotherPerson.friends) // ['Shelby', 'Court'] 这种模式要去你必须有一个对象作为另一个对象的基础。在这个例子中,person作为另一个对象的基础,把person传入object中,该函数就会返回一个新的对象。这个新对象将person作为原型,所以它的原型中就包含一个基本类型和一个引用类型。所以意味着如果还有另外一个对象关联了person,anotherPerson修改数组friends的时候,也会体现在这个对象中。Object.create()方法ES5通过Object.create()方法规范了原型式继承,可以接受两个参数,一个是用作新对象原型的对象和一个可选的为新对象定义额外属性的对象,行为相同,基本用法和上面的object一样,除了object不能接受第二个参数以外。var person = { name: 'Jiang', friends: ['Shelby', 'Court'] } var anotherPerson = Object.create(person) console.log(anotherPerson.friends) // ['Shelby', 'Court'] 寄生式继承寄生式继承的思路与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数。function createAnother(o) { var clone = Object.create(o) // 创建一个新对象 clone.sayHi = function() { // 添加方法 console.log('hi') } return clone // 返回这个对象 } var person = { name: 'Jiang' } var anotherPeson = createAnother(person) anotherPeson.sayHi() 基于person返回了一个新对象anotherPeson,新对象不仅拥有了person的属性和方法,还有自己的sayHi方法。在主要考虑对象而不是自定义类型和构造函数的情况下,这是一个有用的模式。寄生组合式继承在前面说的组合模式(原型链+构造函数)中,继承的时候需要调用两次父类构造函数。父类function SuperType(name) { this.name = name this.colors = ['red', 'blue', 'green'] } 第一次在子类构造函数中function SubType(name, job) { // 继承属性 SuperType.call(this, name) this.job = job } 第二次将子类的原型指向父类的实例// 继承方法 SubType.prototype = new SuperType() 当使用var instance = new SubType()的时候,会产生两组name和color属性,一组在SubType实例上,一组在SubType原型上,只不过实例上的屏蔽了原型上的。使用寄生式组合模式,可以规避这个问题。这种模式通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。基本思路:不必为了指定子类型的原型而调用父类的构造函数,我们需要的无非就是父类原型的一个副本。本质上就是使用寄生式继承来继承父类的原型,在将结果指定给子类型的原型。function inheritPrototype(subType, superType) { var prototype = Object.create(superType.prototype) prototype.constructor = subType subType.prototype = prototype } 该函数实现了寄生组合继承的最简单形式。这个函数接受两个参数,一个子类,一个父类。第一步创建父类原型的副本,第二步将创建的副本添加constructor属性,第三部将子类的原型指向这个副本。function SuperType(name) { this.name = name this.colors = ['red', 'blue', 'green'] } SuperType.prototype.sayName = function () { console.log(this.name) } function SubType(name, job) { // 继承属性 SuperType.call(this, name) this.job = job } // 继承 inheritPrototype(SubType, SuperType) var instance = new SubType('Jiang', 'student') instance.sayName() 补充:直接使用Object.create来实现,其实就是将上面封装的函数拆开,这样演示可以更容易理解。function SuperType(name) { this.name = name this.colors = ['red', 'blue', 'green'] } SuperType.prototype.sayName = function () { console.log(this.name) } function SubType(name, job) { // 继承属性 SuperType.call(this, name) this.job = job } // 继承 SubType.prototype = Object.create(SuperType.prototype) // 修复constructor SubType.prototype.constructor = SubType var instance = new SubType('Jiang', 'student') instance.sayName() ES6新增了一个方法,Object.setPrototypeOf,可以直接创建关联,而且不用手动添加constructor属性。// 继承 Object.setPrototypeOf(SubType.prototype, SuperType.prototype) console.log(SubType.prototype.constructor === SubType) // true 以上所述是小编给大家介绍的JavaScript的六种继承方式(推荐),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

大多数情况下我们使用左键来进行页面交互,而右键大部分对于开发者来说是审查元素的,有的时候我们也要自定义鼠标右键点击行为来达到更好的交互性,常见的有漫画左键前进、右键后退。第一步我们要屏蔽浏览器默认的右键点击行为,即阻止弹出框。首先要将阻止弹出函数绑定到目标元素上://阻止浏览器默认右键点击事件$("div").bind("contextmenu", function(){ return false;})如此一来,div元素的右击事件就被屏蔽了,而浏览器其他区域不受影响,如果你想在整个页面屏蔽右击事件,只需这样做:document.oncontextmenu = function() { return false;}接下来就可以为元素绑定右击响应函数了:$("div").mousedown(function(e) { console.log(e.which); //右键为3 if (3 == e.which) { $(this).css({ "font-size": "-=2px" }); } else if (1 == e.which) { //左键为1 $(this).css({ "font-size": "+=3px" }); }})示例效果为右击字体缩小,左击字体变大,且其它区域可以响应默认右击事件。完整代码:<head> <style type="text/css"> div{ font-size:20px; } </style> <script src="../jquery.js"></script> <script> $(function() { //阻止浏览器默认右键点击事件 /*document.oncontextmenu = function() { return false; }*/ //某元素组织右键点击事件 $("div").bind("contextmenu", function(){ return false; }) $("div").mousedown(function(e) { console.log(e.which); //右键为3 if (3 == e.which) { $(this).css({ "font-size": "-=2px" }); } else if (1 == e.which) { //左键为1 $(this).css({ "font-size": "+=3px" }); } }) }) </script></head><body> <div> div </div></body>以上这篇jQuery自定义元素右键点击事件(实现案例)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

一、变量 •全局变量 JavaScript的两个特征,不自觉地创建出全局变量是出乎意料的容易。首先,你可以甚至不需要声明就可以使用变量;第二,JavaScript有隐含的全局概念,意味着你不声明的任何变量都会成为一个全局对象属性(不是真正意义上的全局变量,可以用delete删除) 复制代码 代码如下: function sum(x,y) { // result 未声明,为隐式全局变量 result = x + y; return result; } function foo() { // 使用任务链进行部分var声明,b为隐式全局变量 var a = b = 1; } 建议: 复制代码 代码如下: function (x,y) { var a ,b ; a = b = 1;//a,b 为局部变量 } •var作用 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。 复制代码 代码如下: // 定义三个全局变量 var global_var = 1; global_novar = 2; // 反面教材 (function () { global_fromfunc = 3; // 反面教材 }()); // 试图删除 delete global_var; // false delete global_novar; // true delete global_fromfunc; // true // 测试该删除 typeof global_var; // "number" typeof global_novar; // "undefined" typeof global_fromfunc; // "undefined" •单var形式声明变量 在函数顶部使用单var语句是比较有用的一种形式。所有未初始化但声明的变量的初始值是undefined 复制代码 代码如下: function func() { var a = 1, b = 2, sum = a + b, myobject = {}, i, j; // function body... } •var散布问题 复制代码 代码如下: // 反例 myname = "global"; // 全局变量 function func() { alert(myname); //"undefined" var myname = "local"; alert(myname); // "local" } func();等同于: myname = "global"; // global variable function func() { var myname; // 等同于 -> var myname = undefined; alert(myname); // "undefined" myname = "local"; alert(myname); // "local"} func(); 二 for循环 •建议使用 复制代码 代码如下: function looper() { var i = 0, max, myarray = []; // ... for (i = 0, max = myarray.length; i < max; i++) { // 使用myarray[i]做点什么 } } 使用以下表达式代替i++ 复制代码 代码如下: i = i + 1 i += 1以下两种循环方式更快 //第一种变化的形式: var i, myarray = []; for (i = myarray.length; i–-;) { // 使用myarray[i]做点什么 } //第二种使用while循环: var myarray = [], i = myarray.length; while (i–-) { // 使用myarray[i]做点什么 } •for-in循环 应用在非数组对象的遍历上,数组使用正常的for循环,对象使用for-in循环。使用hasOwnProperty()方法,当遍历对象属性的时候可以过滤掉从原型链上下来的属性。 三 避免隐式类型转换 •坚持使用===和!== 四 避免使用eval,以及避免给setInterval(), setTimeout()和Function()构造函数传递字符串,用函数代替。 五 parseInt()数值转换 建议给基数参数赋值, 复制代码 代码如下: var month = "06", year = "09"; month = parseInt(month, 10);//开头为0的字符串会被当做8进制处理 year = parseInt(year, 10); 六 编程规范 构造函数命名:MyConstructor(); 一般函数命名:myFunction(); 变量命名:firstName; 私有属性或方法:_secondeName, 常量:PI,

强大的移动端触屏幻灯片图片和HTML内容切换插件idangerous swiper,支持自定义左右切换还是上下切换,支持多个分组切换,支持下拉更新切换,支持TAB方式切换等十几种切换效果,支持众多的选项配置,如:speed:切换的速度(毫秒)autoplay:自动播放的速度mode:切换模式 horizontal(横向) vertical(竖向)loop:是否循环播放true false如此强大的配置功能,值得使用。使用方法:1.加载插件<link rel="stylesheet" href="path_to_css/idangerous.swiper.css"><script defer src="path_to_js/idangerous.swiper-2.x.min.js"></script>2.HTML内容<div class="swiper-container"> <div class="swiper-wrapper"> <!--First Slide--> <div class="swiper-slide"> <!-- Any HTML content of the first slide goes here --> </div> <!--Second Slide--> <div class="swiper-slide"> <!-- Any HTML content of the second slide goes here --> </div> <!--Third Slide--> <div class="swiper-slide"> <!-- Any HTML content of the third slide goes here --> </div> <!--Etc..--> </div></div>3.函数调用<script type="text/javascript">window.onload = function() { var mySwiper = new Swiper('.swiper-container',{ //Your options here: mode:'horizontal', loop: true //etc.. }); }</script>插件支持jQuery和Zepto,如果使用这两者,请先加载jQuery.js<script type="text/javascript">$(function(){ var mySwiper = $('.swiper-container').swiper({ //Your options here: mode:'horizontal', loop: true //etc.. });});</script>源码下载:idangerous swiper.js以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

焦点访谈

最新最热的文章

更多 >

COPYRIGHT (©) 2017 Copyright ©2017 5060网址大全 网站地图

联系我们

827570882

扫描二维码分享到微信