Vue初体验
最近刚接触到Vue,他主要是以MVVM为主要的主要风格,那么MVVM是什么呢?
M----Model 模型
V----View 视图
VM------ViewModel 视图模型
基本思想:给予view中各种控件一个对应的数据对象,并同步两者,VM就是view对应着Model,将程序员从复杂的DOM操作中解放出来..
主要用法:
Demo1:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="vue.min.js"></script> </head> <body> <div id="app"> <p>{{ msg }}</p> </div> <script> //创建一个Vue实例; //当导入包之后,在Browser的内存中就多了一个Vue的构造函数; var vm = new Vue({ el: '#app', //该Vue对象是针对id为app元素的 data: { //data中存放的是el中需要用到的数据 msg: 'Welcome!' } }) </script> </body> </html>
下面是一些应用,大家可以复制下自己测下感受感受:
Demo2:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="vue.min.js"></script> <style> [v-cloak] { display: none; } </style> </head> <body> <div id="app"> <p v-cloak>{{ msg }}</p> <!-- 默认不会覆盖html内容,但会有闪烁问题:表达式会解析的比较慢使网页上能够直接看到 --> <h4 v-text="msg"></h4> <!-- 默认v-text是没有闪烁问题的,但会覆盖html内容,都不会解析html--> <div v-html="msg2"> 111 </div> <!-- v-bind使属性内的值绑定到Vue对象内的data域中的对应值 --> <!-- v-bind的缩写: : --> <!-- v-bind中可以写合法的JS表达式 --> <!-- v-bind只能实现数据的单向绑定:从vm中向View中绑定 --> <!-- v-on的缩写: @ --> <input type="button" value="Button" v-bind:title="mytitle + '111' " v-on:click.stop="push"> <!-- .stop阻止元素及其父元素中所有的事件冒泡 --> <input type="button" value="Button" v-bind:title="mytitle + '111' " v-on:click.prevent="pull"> <!-- .prevent阻止元素及其父元素中所有的默认行为--> <!-- .capture添加事件监听:事件由外向内执行--> <!-- .self只能自己触发事件(阻止自身所有的冒泡和默认行为)--> <!-- .once只能触发一次--> </div> <script> /* 注意1:在 VM实例中,如果要获取data上的数据,或者想要调用method中的方法,必须通过 * this.属性名 或 this.方法名来访问,this就表示该Vue实例 * 注意2:VM实例会自动监听自身data域中所有数据的变更,自动会同步到页面中去 */ var vm = new Vue({ el: '#app', data: { msg: 'Welcome!', msg2: '<h1>Welcome!</h1>', mytitle: 'SOS', intervalId: null }, methods:{ //在实例中用到的方法 push: function(){ if(this.intervalId != null){return;} this.intervalId = setInterval( () => { //=>使内部的this指向外部的this var start = this.msg.substring(0, 1); var end = this.msg.substring(1); this.msg = end + start; }, 500); }, pull: function(){ clearInterval(this.intervalId); this.intervalId == null; } } }) </script> </body> </html>
Demo3:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="vue.min.js"></script> </head> <body> <div id="app"> <h1 :class="['thin', 'italic', flag?'active':'']">{{ msg }}</h1> <p v-for="(item, i) in list">{{ item }}对应索引值: {{ i }}</p> <p v-for="user in array">Id: {{ user.id }} name: {{ user.name }}</p> <!-- in 後面可以放: 普通数组,对象数组,对象,数字(从1开始) --> <input type="number" v-bind="id"> <input type="text" v-model="name"> <input type="button" value="添加" @click="add"> <!-- <input type="button" value="删除" @click="delete"> --> <!-- 用key来进行数据的强制关联 key属性只能用number或者String key在使用时必须使用v-bind属性绑定的值,指定key的值 --> <p v-for="greatMan in list1" :key="greatMan.id">id: {{ greatMan.id }} name: {{ greatMan.name }}</p> </div> <script> var vm = new Vue({ el: '#app', data: { name: '', id: '', msg: '你好!', flag: true, list: [1, 2, 3, 4, 5], array: [ { id: 001, name: "aaa"}, { id: 002, name: "bbb"}, { id: 003, name: "ccc"} ], list1: [ { id: 1, name: "李斯"}, { id: 2, name: "嬴政"}, { id: 3, name: "赵高"}, { id: 4, name: "韩非"}, { id: 5, name: "荀子"}, ] }, methods: { add: function(){ if(this.id) this.list1.push({ id: this.id, name: this.name }) }, delete: function(){ //this.list1.pop } } }) </script> </body> </html>
Demo4:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="vue.min.js"></script> </head> <body> <div id="app"> <input type="button" value="toggle" @click="toggle"> <!-- v-if会移除/创建元素,减少初始渲染消耗 --> <p v-if="flag">{{ msg }}</p> <!-- 而v-show不会移除元素,只会显示/隐藏元素,切换性能比较好 --> <p v-show="flag">{{ msg }}</p>
<!-- v-show内可以写稍微复杂一点的逻辑表达式,例如:
v-show=" !showList && getview == 'menu' "
getview即vue对象内的域 -->
</div> <script> var vm = new Vue({ el: '#app', data: { msg: 'Welcome!', flag: true }, methods:{ toggle: function(){ this.flag = !this.flag; } } }) </script> </body> </html>
Demo5:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="jquery.min.js"></script> <script src="bootstrap.min.js"></script> <script src="vue.min.js"></script> </head> <body> <div id="app"> <input type="text" v-model="keywords"> <table> <thead> <tr> <th>Id</th> <th>Name</th> <th>Ctime</th> <th>Operation</th> </tr> </thead> <tbody> <!-- 定义一个search方法,并通过传参的方式,搜索关键字后返回新的结果数组 --> <tr v-for="item in search(keywords)" :key="item.id"> <td>{{ item.id }}</td> <td v-text="item.name"></td> <td>{{ item.ctime }}</td> <td> <a href="" @click.prevent="del(item.id)">删除</a> </td> </tr> </tbody> </table> </div> <script> //创建一个Vue实例; //当导入包之后,在Browser的内存中就多了一个Vue的构造函数; var vm = new Vue({ el: '#app', //该Vue对象是针对id为app元素的 data: { //data中存放的是el中需要用到的数据 msg: 'Welcome!', id: '', name: '', keywords: '', list: [ { id: 1, name: 'BenZ', ctime: new Date() }, { id: 2, name: 'BMW', ctime: new Date() } ] }, methods:{ del: function(id){ var index = this.list.some((item, i) => { //当不知道循环次数时用some方式去遍历数组 if(item.id == id){ this.list.splice(i, 1); return true; } }) }, search: function(keywords){ var List = []; this.list.forEach(item => { if(item.name.indexOf(keywords) != -1){ List.push(item); } }); return List; } // $("p:contains(is)") jQuery选择器:选择所有包含is文本的p标签 } }) </script> </body> </html>
Demo6:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="jquery.min.js"></script> <script src="bootstrap.min.js"></script> <script src="vue.min.js"></script> </head> <body> <div id="app"> <p>{{ msg | msgFilter('a') }}</p> <!-- |号之前作为管道数据传输给过滤器 --> </div> <script> //过滤器的使用 //创建全局过滤器,可以被多个Vue对象所访问,第一个参数已经被规定为管道符,第二个参数之后可以传递进来了 Vue.filter('msgFilter', function(data, condition) { //对于过滤出来的内容所作的操作 var reg = /d/g; return data.replace(reg, condition); //第一个参数也可用RegExp }); var vm = new Vue({ el: '#app', //该Vue对象是针对id为app元素的 data: { //data中存放的是el中需要用到的数据 msg: 'ddddddaddddd' } }) </script> </body> </html>
Demo7:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="jquery.min.js"></script> <script src="bootstrap.min.js"></script> <script src="vue.min.js"></script> </head> <body> <div id="app"> <p>{{ ctime | dateFormat("YYY-mm-dd") }}</p> </div> <script> Vue.filter('dateFormat', function (datastr, parttern) { var dt = new Date(datastr); var y = dt.getFullYear(); var m = dt.getMonth() + 1; var d = dt.getDay(); if(parttern && parttern.toLowerCase() === 'yyyy-mm-dd') { return `${y}-${m}-${d}`; //相当于: y + '-' + m + '-' + d }else{ var hh = dt.getHours(); var mm = dt.getMinutes(); var ss = dt.getSeconds(); return `${y}-${m}-${d} ${hh}:${mm}:${ss}` } }); var vm = new Vue({ el: '#app', data: { ctime: new Date() }, methods: { }, filters: { //定义私有过滤器 调用过滤器遵从'就近原则' dateFormat: function(datastr, parttern = ''){ var dt = new Date(datastr); var y = dt.getFullYear(); var m = dt.getMonth() + 1; var d = dt.getDay(); var reg = /(^\d$)/; if(parttern && parttern.toLowerCase() === 'yyyy-mm-dd') { return `${y}-${m}-${d}`; //相当于: y + '-' + m + '-' + d }else{ var hh = dt.getHours()+''; var mm = dt.getMinutes()+''; var ss = dt.getSeconds()+''; hh.replace(reg, "0$1"); mm.replace(reg, "0$1"); ss.replace(reg, "0$1"); return `${y}-${m}-${d} ${hh}:${mm}:${ss}` } } } }) </script> </body> </html>
Demo8:
<!DOCTYPE html> <html> <head> <title>title</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <script src="jquery.min.js"></script> <script src="bootstrap.min.js"></script> <script src="vue.min.js"></script> </head> <body> <div id="app"> <!-- Vue提供的全部监控的按键别名: .enter .tab .delete 捕获delete与backspace .esc .space .up .down .left .right 也可以用jQuery的按键监视:通过event和对应按键码(KeyCode)实现 docu.onkeydown = function (event) { if (event.keyCode == 116) { event.preventDefault(); window.history.go(-1);//返回上一页 } } --> <p>{{ msg }}</p> <!-- 自定义全局指令 --> <input type="text" @keyup.enter="TODO" v-focus> <!-- v-focus(自定义指令)使进入页面之后自动获取文本框焦点--> </div> <script> //自定义全局按键修饰符: Vue.config.keyCodes.f2 = 113; //自定义按键别名和对应真实keyCode var vm = new Vue({ el: '#app', data: { msg: 'Welcome!' }, methods:{ TODO: function(){ console.log("TODO"); } } }) //注册一个全局自定义指令 v-focus,除了el参数,还可以传多个参数,但el的位置必须是第一个,el相当于操作的DOM对象 Vue.directive('focus', { inserted: function(el){ el.focus() } }) </script> </body> </html>
*******************************************************分割线**************************************************
文章仅作为自己学习记录所用,观点仅供参考,如需转载,请注明出处...