Vue.js - 1
Vue.js - 2javascript
例: <div id="app"> <!-- 原数据输出 i am tom --> <p>{{msg}}</p> <!-- msg是原数据 | upper是过滤器名 --> <!-- 原数据过滤后输出 I am tom --> <p>{{msg | upper}}</p> </div> <script> // 全局过滤器的结构,利用.filter关键字,第一个参数是自定义的过滤器名, // 第二个参数是一个回调函数,回调函数的第一个参数是原数据. Vue.filter('upper', function (value) { // 截取原数据的第一个字符并转换为大写字母 + 从第一个字符以后截取的字符串. return value.slice(0, 1).toUpperCase() + value.slice(1) }); new Vue({ el: "#app", data: { msg: "i am tom" }, }) </script>
<!-- 带参数的过滤器 --> 例: <div id="app"> <!-- 这里过滤器传进来的参数是upper --> <!-- 根据js中写的逻辑那么就输出 I am jerry --> <p>{{msg | selectCase('upper')}}</p> </div> <script> // 'selectCase'是自定义过滤器名,第二个参数是一个回调函数, // 回调函数的第一个参数是原数据,第二个参数这里作条件判断用. Vue.filter('selectCase', function (value, select) { //若是回调函数中第二个参数 == upper 就将原数据中的第一个字符转换为大写字母, //反之若是回调函数中第二个参数 == lower 就将原数据中的第一个字符转换为小写字母 if (select == 'upper') { return value.slice(0, 1).toUpperCase() + value.slice(1) } else if (select == 'lower') { return value.slice(0, 1).toLowerCase() + value.slice(1) } }); new Vue({ el: "#app", data: { msg: "i am jerry" }, }) </script>
<!-- 多个过滤器能够连用 --> 例: <div id="app"> <!--多个过滤器能够连用--> <!-- 第一次过滤:原数据 -> I am jerry 第一次过滤:基于上次过滤结果 -> i am jerry 最后一次过滤后输出 i am jerry-How are you --> {{msg | upper | selectCase('lower') | str}} </div> <script> // 过滤器1 Vue.filter('upper', function (value) { return value.slice(0, 1).toUpperCase() + value.slice(1) }); // 过滤器2 Vue.filter('selectCase', function (value, select) { if (select == 'upper') { return value.slice(0, 1).toUpperCase() + value.slice(1) } else if (select == 'lower') { return value.slice(0, 1).toLowerCase() + value.slice(1) } }); // 过滤器3 Vue.filter('str', function (value) { return value + "-How are you" }); new Vue({ el: "#app", data: { msg: "i am jerry" }, }) </script>
例: <div id="app"> <!-- msg原数据 lower过滤器 输出 i am tom --> <p>{{msg | lower}}</p> </div> <script> new Vue({ el: "#app", data: { msg: "I am tom" }, // 局部定义过滤器 // 跟 el data平级 定义一个filters filters: { // lower是自定义过滤器名,后面跟上一个函数,value一样是原数据. 'lower': function (value) { return value.slice(0, 1).toLowerCase() + value.slice(1) } } }) </script>
<!-- 全局定义自定义指令 --> <div id="app"> <!-- 加载页面input框自动获取焦点 --> <input type="text" v-focus> </div> <script> // 自定义指令的关键字是.directive; // 第一个参数是自定义指令名,要取消v-,在标签上把v-加上; // 第二个参数是一个对象,对象的内部是自定义指令运行的阶段,阶段key对应一个函数; // 函数的第一个参数是元素节点,第二个参数是一些必要的属性参数,在函数内部来进行自定义指令的逻辑. Vue.directive('focus',{ inserted:function (el, binding) { el.focus(); } }); new Vue({ el: "#app", data: {} }) </script>
<!-- 全局定义自定义指令 --> <div id="app"> <!-- 黄色 --> <div v-color>猜个人颜色</div> <!-- 红色 --> <div v-color="color">猜个人颜色</div> </div> <script> // bind和inserted是咱们自定义指令的两个经常使用的阶段. // bind执行在inserted以前,是在指令绑定到元素时执行,或者叫编译这个指令时执行. // 他们的运行相似于事件的机制,就是当指令绑定到dom时,执行bind后边的函数. // 当将原dom对象用Vue编译好之后(例如v-if,v-for都须要用Vue编译才能在正常浏览器中显示). // vue将编译后的对象,替换掉原节点,替换好以后,触发inserted后边的函数, // vue的运行过程,是先熏染页面,而后再获取页面的结构进行编译. // 编译成的对象叫作虚拟dom. // 编译完成真实的dom对象后,替换掉页面的dom结构. /* 总结:bind阶段:指令初次绑定到dom元素时,调用bind后面的函数(只调用一次) inserted阶段:Vue将原dom对象编译好,再替换掉原dom元素,再调用inserted后面的函数. */ Vue.directive('color',{ //inserted执行在bind以后 inserted(el,binding){ alert("inserted"); el.style.backgroundColor="yellow"; el.style.backgroundColor=binding.value; console.log(binding.value); // red }, // bind执行在inserted以前 bind:function (el, binding) { alert("bind"); el.style.backgroundColor="yellow"; } }); new Vue({ el: "#app", data: { color:"red" } }) </script>
<div id="app"> <!--局部定义自定义指令--> <input type="text" v-fo> </div> <script> new Vue({ el: "#app", data: {}, // 局部定义自定义指令 directives:{ 'fo':{ inserted:function (el, binding) { el.focus(); } } } }) </script>
<!-- 简单的例子开始 --> 例1: <div id="app"> <!-- {{}}中的复杂方法 输出 dlrow olleh --> <p>{{ message.split('').reverse().join('') }}</p> <!-- 使用computed属性替换掉的 输出 dlrow olleh --> <p>{{ myMsg }}</p> </div> <script> new Vue({ el: "#app", data: { message: "hello world" }, // 使用computed属性,替换掉{{}}中的复杂方法 computed: { myMsg: function () { //以空字符串截取成一个数组再反转过来以空字符串转换成字符串 return this.message.split('').reverse().join('') }, }, </script>
<!--加法运算的功能,p标签时两个input框的计算结果,而且input框改变时,同时改变p标签结果--> 例2: <div id="app"> <!-- 由于输入的是字符串因此要转换为number类型再进行运算 --> <input type="text" v-model.number="input1"> + <input type="text" v-model.number="input2"> = <!--equal是使用computed属性计算出来的 --> <span>{{ equal }}</span> --- <!--equal2是经过methods函数内部逻辑计算出来的,运算结果同上--> <span>{{ equal2() }}</span> </div> <script> new Vue({ el: "#app", data: { input1: 0, input2: 0 }, // 使用computed属性,替换掉{{}}中的复杂方法 computed: { equal: function () { return this.input1 + this.input2 }, }, // 在函数里也能够进行逻辑运算 methods: { equal2:function () { return this.input1 + this.input2 }, } </script>
<!--需求:咱们但愿把数据大于0的项显示出来,把小于0的项过滤掉--> 例3: <div id="app"> <ul> <li v-for="item in changedArr">{{item}}</li> </ul> </div> <script> new Vue({ el: "#app", data: { arr: [1, 2, 3, 4, 5, -1, -2, -3] }, // 使用computed属性,替换掉{{}}中的复杂方法 computed: { // 过滤后的数组 changedArr: function () { return this.arr.filter(function (item, index) { //该函数返回结果是true的项组成的新数组 return item > 0 }) } }, </script>
Component 组件html
1. 写法一:使用Vue.extend方法定义组件,使用 Vue.component方法注册组件vue
<div id="app"> <!-- 这里的标签必须与全局注册的标签一致 --> <tmp1></tmp1> </div> <script type="text/javascript"> // 1. 写法一:使用Vue.extend方法定义组件,使用 Vue.component方法注册组件 //定义组件 var tmp1 = Vue.extend({ template:"<div><a href='#'>注册</a></div>" }); //全局注册组件 Vue.component('tmp1',tmp1); new Vue({ el:"#app", data:{} }); </script>
2.写法二: 使用 Vue.component方法定义注册组件一步到位java
<div id="app"> <!-- 这里的标签必须与全局注册的标签一致 --> <tmp2></tmp2> </div> <script type="text/javascript"> //定义和注册组件一步到位 Vue.component('tmp2',{ template:"<div><a href='#'>tmp2</a></div>" }) new Vue({ el:"#app", data:{} }); </script>
3.写法三:将组件内容定义到template模板中ios
<!--将组件内容定义到template模板中 --> <template id="tmp3"> <div><a href='#'>tmp3</a></div> </template> <div id="app"> <tmp3></tmp3> </div> <script type="text/javascript"> Vue.component('tmp3',{ template:"#tmp3" }) new Vue({ el:"#app", data:{} }); </script>
4.写法四:将组件内容定义到类型为 x-template的script模板中git
<!-- 将组件内容定义到类型为 x-template的script模板中 --> <script type="x-template" id="tmp4"> <div><a href='#'>tmp4</a></div> </script> <div id="app"> <tmp4></tmp4> <login-To></login-To> </div> <script type="text/javascript"> Vue.component('tmp4',{ template:"#tmp4" }) // 命名时的注意点:使用驼峰形式命名时,须要把view层的标签改为中划线链接的形式 Vue.component('loginTo',{ template:"#tmp4" }) new Vue({ el:"#app", data:{} }); </script>
<!-- 定义组件id为tmp的组件模板 --> <template id="tmp"> <div> Hello World <!-- login组件必须放在内部设置一个根节点 --> <!-- template不算根节点 --> <login></login> </div> <!-- 在account组建中使用login子组件 --> </template> <div id="app"> <account></account> </div> <script type="text/javascript"> //定义和注册account组件 Vue.component("account",{ template:"#tmp", //在account组件中定义和注册一个login子组件 //这里面的组件是局部组件 components:{ 'login':{ template:"<p>登陆</p>" } } }) new Vue({ el:"#app", data:{} }); </script>
<!-- 组件模板 --> <template id="temp"> <div @click = "login()"> Hello World <!-- 定义的子组件只能在父组件中使用,不然无论用,子组件的事件不会冒泡到父元素身上 --> <login @click = "login()"></login> <!-- .stop禁止事件冒泡到父元素身上 --> <button @click.stop = "login()">点我</button> </div> </template> <div id="app"> <!-- 使用组件 --> <account></account> </div> <!--子组件只能在父组件的模板中使用, 组件跟组件的做用域是相互独立的 组件跟组件全部的属性都是独立的,包括methods,filters,directives,data 这也是局部定义属性的意义. --> <script type="text/javascript"> //定义和注册组件 Vue.component("account",{ template:"#temp", components:{ 'login':{ template:"<button>登陆</button>" } }, // 注意:原来在new Vue()中定义的data是一个对象 // 可是在组件中定义的data是一个方法,而且在这个方法中必定要return一个对象 data:function(){ return { msg: "我是account组件中的msg!" }; }, //定义一个方法 methods:{ login:function(){ alert(this.msg); } } }); new Vue({ el:"#app", data:{} }); </script>
Vue能够借助于vue-resource或者axios来实现AJAX请求(axios不支持jsonp),
同源策略:A网页设置的 Cookie,B网页不能打开,除非这两个网页"同源"。所谓"同源"指的是"三个 相同"。
协议相同
域名相同
端口相同
例:http://xxx.com:80/login.html
协议:http
域名:xxx.com
端口:80github
http请求报文ajax
浏览器与服务器数据交互是遵循http协议的,当浏览器要访问服务器的时候,浏览器须要将相关请求数据提交给服务器(例如:浏览器信息,url地址,参数等),一般是经过请求报文来提交的npm
请求报文的格式分为:json
一、请求报文行 二、请求报文头 三、请求报文体
http响应报文
当浏览器请求服务器的时候,服务器须要将数据返回给浏览器,这种数据是经过响应报文响应回浏览器的
响应报文的格式分为:
一、响应报文行 二、响应报文头 三、响应报文体
就是利用<script>标签没有跨域限制的“漏洞”(历史遗迹啊)来达到与第三方通信的目的。
<script> function test(data) { console.log(data); } </script> <script src="http://vue.studyit.io/api/jsonp?callback=test"> </script>
CORS须要浏览器和服务器同时支持。目前,全部浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。
所以,实现CORS通讯的关键是服务器。只要服务器实现了CORS接口,就能够跨源通讯。
Vue与后台Api进行交互一般是利用vue-resource(其中的一种方法)来实现的,本质上vue-resource是经过http来完成AJAX请求响应的
get请求地址:http://vue.studyit.io/api/get...
post请求地址:http://vue.studyit.io/api/add... 参数:name:'奔驰'
jsonp请求地址:http://vue.studyit.io/api/jsonp
vue结合vue-resource写法步骤
一、经过 https://cdn.jsdelivr.net/vue.resource/1.2.1/vue-resource.min.js 下载到vue-resource文件 二、在html页面中经过script标签导入vue-resource.min.js 文件后,就会自动的在Vue对象实例上初始化 $http 三、使用 // 全局Vue对象写法 Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback); Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback); // 在Vue对象中的写法 this.$http.get('/someUrl', [options]).then(successCallback, errorCallback); this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
vue-resource get请求
写法格式: this.$http.get('请求的url', [可选参数对象,使用{}传参]).then(成功回调函数, 失败回调函数); 成功回调函数参数对象主要属性说明: 一、url : 请求的原始url 二、body: 响应报文体中的数据(咱们一般用这个属性获取服务器返回的数据) 三、其余属性请看文档 举例: this.$http.get('http://vuecms.ittun.com/api/getlunbo?id=1').then(function(res){console.log(res.body)}, function(err){//err是异常数据});
vue-resource post请求
写法格式: this.$http.post('请求的url',[可选参数请求报文体对象body,使用{}传参], [可选参数对象,使用{}传参]).then(成功回调函数, 失败回调函数); 成功回调函数参数对象主要属性说明: 一、url : 请求的原始url 二、body: 响应报文体中的数据(咱们一般用这个属性获取服务器返回的数据) 三、其余属性请看文档 注意点: $http.post()方法中的第二个参数固定写成:{emulateJSON:true},不然可能形成服务器没法接收到请求报文体中的参数值 举例: this.$http.post('http://vuecms.ittun.com/api/adddata?id=1' //请求的url ,{content:'hello'} //请求报文体中传入的参数对象,多个使用逗号分隔 ,{emulateJSON:true} //固定写法,保证服务器能够获取到请求报文体参数值 ).then(function(res){console.log(res.body)}, function(err){//err是异常数据});
vue-resource jsonp请求
jsonp请求主要用来解决ajax跨域请求问题,使用jsonp实现跨域首先要保证服务器api支持jsonp请求的格式 写法格式: this.$http.jsonp('请求的url', [可选参数对象,使用{}传参]).then(成功回调函数, 失败回调函数); 成功回调函数参数对象主要属性说明: 一、url : 请求的原始url 二、body: 响应报文体中的数据(咱们一般用这个属性获取服务器返回的数据) 三、其余属性请看文档 举例: this.$http.jsonp('http://vuecms.ittun.com/api/getlunbo?id=1').then(function(res){console.log(res.body)}, function(err){//err是异常数据});
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; text-decoration: none; } .title { margin: 0 auto; width: 100px; height: 100px; } h2 { text-align: center; margin: 50px; font-family: "宋体"; color: #333; font-size: 26px; } a { color: #d8505c; } table { border: 1px solid #999; border-collapse: collapse; width: 800px; margin: 20px auto; text-align: center; } table th { background: skyblue; border: 1px solid #999; padding: 5px; } table td { border: 1px solid #999; padding: 5px; } .add { width: 800px; margin: 20px auto 0 auto; text-align: center; font-size: 0; } .add input { outline: none; border: none; width: 200px; height: 30px; border: 1px solid #ccc; padding-left: 10px; } .add .addInp { border-right: transparent; } .add .search { margin-top: 10px; } .add button { border: none; width: 50px; height: 32px; background: skyblue; color: #FFF; vertical-align: top; } </style> <!-- 引入Vue.js文件 --> <script src="./js/vue.js"></script> <!-- https://cdn.jsdelivr.net/vue.resource/1.2.1/vue-resource.min.js 下载到vue-resource文件 --> <script src="./js/vue-resource.js"></script> </head> <body> <div id="app"> <div class="add"> <h2>产品管理</h2> <!-- v-focus 挂载上自定义指令 --> <input type="text" class="addInp" v-model.trim = "value" placeholder="请输入产品名称" @keyup.enter = "add()" v-focus > <!-- 点击添加按钮调用add函数添加数据 --> <button @click = "add()">添加</button><br> <!-- 筛选数据列表 --> <input type="text" class="search" placeholder="请输入筛选内容" v-model = "filterValue" > </div> <table> <thead> <th>编号</th> <th>名称</th> <th>建立时间</th> <th>操做</th> </thead> <tbody> <!-- 用v-for遍历arr数组中的每个对象,并把相应数据渲染到页面上展现 --> <tr v-for = "(item,index) in changeArr"> <td>{{index + 1}}</td> <td>{{item.name}}</td> <td>{{item.ctime | timefmt}}</td> <!-- 点击删除调用del函数删除加数据 注意:须要传入参数index --> <td><a href="javascript:;" @click = "del(item.id)">删除</a></td> </tr> </tbody> </table> </div> <script type="text/javascript"> Vue.filter('timefmt',function(value) { value = new Date(value); var year = value.getFullYear(); var month = value.getMonth() + 1; var day = value.getDate(); var hour = value.getHours(); var minute = value.getMinutes(); var second = value.getSeconds(); //二次处理 day = day<10?"0"+day:day; hour = hour<10?"0"+hour:hour; minute = minute<10?"0"+minute:minute; second = second<10?"0"+second:second; return year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second; }); new Vue({ //规定做用域 el:"#app", //放置全部数据 data:{ arr:[ // {name: '宝马',ctime: new Date}, // {name: '奔驰',ctime: new Date}, // {name: '奥迪',ctime: new Date} ], //用于获取input中的数据 value:"", filterValue:"" }, created:function(){ this.getData(); }, methods:{ //渲染数据到页面上 getData:function(){ //肯定url var url = "http://vue.studyit.io/api/getprodlist"; this.$http.get(url).then(function(res){ //提取数据 var data = res.body; //判断获取到的数据是否正确 if(data.status != 0){ alert("获取数据失败"); return; } //将获取到的数据放入到data中 this.arr = data.message; },function(err){ console.log(err); }); }, //添加数据 add:function(){ //非空判断 if(this.value == ""){ alert("输入内容不能为空!"); return; } // this指的是Vue实例对象 // 查重复数据 for(var i=0;i<this.arr.length;i++){ //若是数据中的每一项的名称跟输入的名称同样的时候提醒已添加过, //并及时return掉不在执行后续代码 if(this.arr[i].name == this.value){ alert('此条数据你已经添加过了!') return; } } // 肯定url var url = "http://vue.studyit.io/api/addproduct"; //post请求 this.$http.post(url,{name:this.value},{emulateJSON:true}).then(function(res){ //先提取数据 var data = res.body; if(data.status == 0){ alert(data.message); // 从新调用获取数据方法用于刷新数据 this.getData(); }else { alert("数据添加失败"); } },function(err){ console.log(err); }); this.value = ""; }, // 删除数据 del:function(id){ //点击删除按钮,从当前索引开始删除一个(至关于删除自己) if(confirm('肯定要删除这条数据吗?')){ //肯定url var url = "http://vue.studyit.io/api/delproduct/"+id //获取数据 this.$http.get(url).then(function(res){ //提取数据 var data = res.body; if(data.status == 0){ alert(data.message); this.getData(); }else { alert("数据删除失败"); } }) } }, }, //局部 自定义指令 directives:{ "focus":{ inserted:function(el){ el.focus(); } } }, //利用computed属性来进行逻辑计算 computed:{ //changeArr就是改变后的新数据数组 'changeArr':function(){ //内部获取不到this var that = this; //返回过滤出来的新数组 return this.arr.filter(function(ele,index){ //根据输入的字符查找对应索引的内容 !=-1就是能够查找到 return ele.name.indexOf(that.filterValue) != -1; }) } } }); </script> </body> </html>