张东红

张东红 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

张东红 收藏了文章 · 2020-01-03

前端培训-中级阶段(9)- 原生Ajax的运行原理与实现(2019-08-08期)

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。

ajax 对于现在的前端来说已经是一件必需品了。单页应用?前后端分离?远程搜索?异步加载?能做的功能太多了。
当然,一直以来我们都是用一些封装好的api去使用(jQuery.ajaxaxios)。今天我们就来了解原生的Ajax。

Ajax是什么?

Asynchronous JavaScript + XML(异步JavaScript和XML), 其本身不是一种技术,而是一个在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML or XHTML, Cascading Style Sheets, JavaScript, The Document Object Model, XML, XSLT, 以及最重要的 XMLHttpRequest object。当使用结合了这些技术的AJAX模型以后, 网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面。这使得程序能够更快地回应用户的操作。

尽管X在Ajax中代表XML, 但由于JSON的许多优势,比如更加轻量以及作为Javascript的一部分,目前JSON的使用比XML更加普遍。JSON和XML都被用于在Ajax模型中打包信息。

Ajax的原理

浏览器发送请求 HttpRequest,服务器给出响应 HttpResponse。不同于正常打开页面的是,Ajax通常使用的数据需要二次加工
比如一首歌的歌曲信息,使用Ajax加载到之后,我们再通过一定的方式把数据显示在页面之上。

当然,我们的html页面,也是通过这样的原理展示的,只不过是浏览器去拉,然后解析html,渲染给我们看。

Ajax的优点

  1. 速度更快。同等条件下,降低了流量,减少了无用数据的加载。
  2. 流量少。一个html和一个json那个更小,我就不说了吧。
  3. 保持之前的界面不变化。比如说验证码,比如说异步加载等等。可以保留历史的输入。

Ajax的核心API

  1. XMLHttpRequest

    1. var xhr= new XMLHttpRequest(); 创建一个XHR对象,用于发起请求
    2. xhr.open('GET', 'https://www.lilnong.top/static/json/manifest.json'); 设置为GET请求,请求https://www.lilnong.top/stati...
    3. xhr.send(); 发送请求。这个时候浏览器会开启一个线程去请求,回调函数会放在等待队列中。
    4. 回调函数

      1. onload
      2. onerror
      3. abort
      4. onreadystatechange
  2. Fetch
    一个比 XHR 更的 API。支持 Promise,简直不要太爽。

     fetch('https://www.lilnong.top/static/json/manifest.json')
         .then(response=>response.json())
         .then(data=>console.log(data));

XMLHttpRequest

之前我们已经大体的了解一下XHR,下面我们深入的介绍一下。测试地址,可以点按钮,然后看network中的请求

new 一个 XHR 对象

new XMLHttpRequest();无参

老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:new ActiveXObject("Microsoft.XMLHTTP");。话说兼容ie,还不用jquery的人很少吧。

使用 XHR 对象发送请求

xhr = new XMLHttpRequest();
xhr.open("GET","https://www.lilnong.top/static/json/front-end.json",true);
xhr.send();

open(method,url,async)

设置一个请求

  1. methods为请求类型。参数如 GETPOSTPUTDELETEHEAD
  2. url为请求地址。
  3. async。true(异步) false(同步)。

send(params)

发送这个请求,如果是post的话,参数是body的内容。get的话,需要带在open的url上。

  1. 支持String
  2. FormData
  3. blob

设置请求头 setRequestHeader

xhr.setRequestHeader(key,value);
通常有几种情况我们需要设置。

  1. 上传
    setRequestHeader("Content-type","application/x-www-form-urlencoded");这样设置等于砸场子。肯定不支持。
    那么常用的Content-type有什么呢?分别对应的数据是什么呢?留个作业吧(毕竟我之前写过)
  2. token 验证
    一般名字都是自定义的。登录的token。csrf 的 token。

响应

一般来说就是拿到 response 来处理了。因为这些都是和后端协商好的。JSON、XML、或者其他数据。
可以返回ArrayBuffer、Blob、Document、DOMString,具体是哪种类型取决于XMLHttpRequest.responseType的值。

readyState

每当 readyState 改变时,就会触发 onreadystatechange 事件。标明当前XHR的状态,onreadystatechange 事件被触发 4 次(0 - 4), 分别是: 0-1、1-2、2-3、3-4,对应着 readyState 的每个变化。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪(status为返回的状态码)

回调

  1. onload 请求成功
  2. onerror 请求失败
  3. onreadystatechange readyState 改变时
  4. progress 下载进度
  5. .upload.progress 上传进度
  6. ontimeout 超时
  7. onabort 被终止

其他 属性&方法

  1. timeout
    unsigned long 即无符号长整型,表示该请求的最大请求时间(毫秒),超过该时间请求会自动结束。
  2. withCredentials
    Boolean,用来指定跨域的请求是否应该使用证书(如cookie或授权header头)。
  3. .abort()
    如果请求已经被发送,则立刻中止请求.
  4. .getResponseHeader()
    返回包含指定响应头的字符串,如果响应尚未收到或响应中不存在该报头,则返回null。
    可以用来拿服务器时间

fetch

fetch --mdn,感兴趣的可以去看看,我这里只简单介绍。毕竟这个api还需要发展。

但是promise真的好爽写起来真的好短支持的返回类型也好多。还有就是新的API基本都是想要跨平台(想想axios)。

Window 和 WorkerGlobalScope 都实现了 WorkerOrGlobalScope。——这意味着基本在任何场景下只要你想获取资源,都可以使用 位于 WorkerOrGlobalScope 中的 fetch() 方法。

创建&发送

fetch(input[, init]);
input是你想要请求的资源。支持两种类型

  1. 一个 USVString 字符串,包含要获取资源的 URL。一些浏览器会接受 blob: 和 data: 作为 schemes.
  2. 一个 Request 对象。

init就是一些参数

  1. method 请求使用的方法,如 GET、POST。
  2. headers 请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
  3. body 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
  4. 等等,还有好多,可以去MDN查看

HTTP response codes

附上MDN原文地址,我只列举一些常见的。
简单来说分为五类

  1. 1xx 消息响应
  2. 2xx 成功响应
  3. 3xx 重定向
  4. 4xx 客户端错误
  5. 5xx 服务器端错误
状态码状态描述详细描述常见场景
200OK (成功)请求成功.成功的意义根据请求所使用的方法不同而不同.GET: 资源已被提取,并作为响应体传回客户端.HEAD: 实体头已作为响应头传回客户端.POST: 经过服务器处理客户端传来的数据,适合的资源作为响应体传回客户端.TRACE: 服务器收到请求消息作为响应体传回客户端.PUT、DELETE、OPTIONS 方法永远不会返回 200 状态码.加载网页,加载资源,加载成功,可以说最常见
206Partial Content (部分内容)当客户端通过使用range头字段进行文件分段下载时使用该状态码一般出现在大文件,比如MP4
301Moved Permanently (永久移动)该状态码表示所请求的URI资源路径已经改变,新的URL会在响应的Location:头字段里找到.用于永久移动,比如说http跳转到https,比如想要更换域名。通常搜索引擎爬虫抓到301会替换保存的资源地址。
302Found (临时移动)该状态码表示所请求的URI资源路径临时改变,并且还可能继续改变.因此客户端在以后访问时还得继续使用该URI.新的URL会在响应的Location:头字段里找到用于临时重定向,比如登录失效需要去登录页,比如作品目前在审核。
304Not Modified(未修改)告诉客户端,所请求的内容距离上次访问并没有变化. 客户端可以直接从浏览器缓存里获取该资源.一般就是js被缓存,css被缓存。当然也有写get请求数据接口也会缓存。
400Bad Request(错误请求)因发送的请求语法错误,服务器无法正常读取.一般来说都是body数据异常,比如服务端要params,body里面是JSON
401Unauthorized(未授权)需要身份验证后才能获取所请求的内容,类似于403错误.不同点是.401错误后,只要正确输入帐号密码,验证即可通过.
403Forbidden(禁止访问)客户端没有权利访问所请求内容,服务器拒绝本次请求.通常都是token失效
404Not Found(未找到)服务器找不到所请求的资源.由于经常发生此种情况,所以该状态码在上网时是非常常见的.接口未定义,资源不存在
500Internal Server Error (内部服务器错误)服务器遇到未知的无法解决的问题.
501Implemented (未实现)服务器不支持该请求中使用的方法,比如POST 和 PUT.只有GET 和 HEAD 是RFC2616规范中规定服务器必须实现的方法.
502Bad Gateway (网关错误)服务器作为网关且从上游服务器获取到了一个无效的HTTP响应.
503Service Unavailable (服务不可用)由于临时的服务器维护或者过载,服务器当前无法处理请求.这个状况是临时的,并且将在一段时间以后恢复.如果能够预计延迟时间,那么响应中可以包含一个Retry-After:头用以标明这个延迟时间.如果没有给出这个Retry-After:信息,那么客户端应当以处理500响应的方式处理它.同时,这种情况下,一个友好的用于解释服务器出现问题的页面应当被返回,并且,缓存相关的HTTP头信息也应该包含,因为通常这种错误提示网页不应当被客户端缓存.
504Gateway Timeout (网关超时)服务器作为网关且不能从上游服务器及时的得到响应返回给客户端.

微信公众号:前端linong

clipboard.png

初级阶段文章目录

  1. 前端培训-初级阶段(17) - 数据存储(cookie、session、stroage)
  2. 前端培训-初级阶段(13) - 正则表达式
  3. 前端培训-初级阶段(13) - 类、模块、继承
  4. 前端培训-初级阶段(13) - ECMAScript (内置对象、函数)
  5. 前端培训-初级阶段(13) - ECMAScript (语法、变量、值、类型、运算符、语句)
  6. 前端培训-初级阶段(13、18)
  7. 前端培训-初级阶段(9 -12)
  8. 前端培训-初级阶段(5 - 8)
  9. 前端培训-初级阶段(1 - 4)

中级阶段文章目录

  1. 前端培训-中级阶段(2) - 事件(event) 事件冒泡、捕获 - (2019-06-20期)
  2. 前端培训-中级阶段(3) - DOM 文档对象模型(2019-06-27期)
  3. 前端培训-中级阶段(4)- BOM 浏览器对象模型(2019-07-04期)
  4. 前端培训-中级阶段(5)- jQuery的概念与基本使用(2019-07-11期)
  5. 前端培训-中级阶段(6)- jQuery元素节点操作(2019-07-18期)
  6. 前端培训-中级阶段(7)- jQuery的事件绑定链式操作及原理(2019-07-25期)
  7. 前端培训-中级阶段(8)- jQuery元素属性样式操作(2019-08-01期)

资料

  1. 前端培训目录、前端培训规划、前端培训计划
  2. XMLHttpRequest
  3. XMLHttpRequest.upload
  4. XMLHttpRequest.readyState
查看原文

张东红 发布了文章 · 2019-12-19

vue基础

反转字符串

<div id="app">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">反转字符串   </button>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
</script>
输出为:Runoob! 点击按钮转换为 !boonuR

Prop 验证

组件可以为 props 指定验证要求。

为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:

   Vue.component('my-component',  { 
       props:  {  
           // 基础的类型检查 (\`null\` 和 \`undefined\` 会通过任何类型验证) 
           propA:  Number,
           // 多个可能的类型 
           propB:  [String,  Number],  
           // 必填的字符串 propC:  { 
           propC:  { 
              type:  String, 
              required:  true  
           },
           // 带有默认值的数字
           propD:  { 
               type:  Number,  
               default:  100  
           },
           // 带有默认值的对象
           propE:  { 
                type:  Object,  
                // 对象或数组默认值必须从一个工厂函数获取                      default: function(){  
                return  {message:  'hello'}                                               
               }  
           },
           // 自定义验证函数 
           propF:  { 
               validator:function(value){  
               // 这个值必须匹配下列字符串中的一个  
               return  ['success',  'warning', 'danger'].indexOf(value)  !==  -1  }  
           }
         } 
      })
查看原文

赞 0 收藏 0 评论 0

张东红 发布了文章 · 2019-12-16

js笔记(基础知识)

收藏小知识

变黑


filter:brightness(0%)   /* 全黑 */
filter:brightness(0.4)  /* 40% 亮度 */
filter:brightness(1)    /* 无效果 */
filter:brightness(200%) /* 两倍亮度 */

详细链接参考:https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter-function/brightness

条件语句
显示隐藏
 <body>
  <input type="button" name="" value="切换" id="btn">
  <div class="box" id="box" ></div>
 </body>
 window.onload = function(){
    var oBtn = document.getElemenById('btn');
    var oDiv = document.getElemenById('box');
}
oBtn.onclick = function(){
     if(oDiv.style.display == 'none' ){
        oDiv.style.display == 'block' 
     }else{
        oDiv.style.display == 'none'
     }
}
 .box{
         width:30px;
         height:30px;
         background:yellow;
    }

switch

switch(Number(label)){
    case 100:
        return '色情';
    case 200:
        return '广告';
    case 400:
        return '违禁';
    case 500:
        return '涉政';
    case 600:
        return '谩骂';
    case 700:
        return '灌水';                    
    case 110:
        return '性感';                
    case 300:
        return '暴恐';
    case 210:
        return '二维码';                
    default:
        return label;
}

下面的事件中会提到

onmouseout 属性在鼠标指针移动到元素外时触发。

onmouseup 事件会在鼠标按键被松开时发生。
onmousedown 事件会在鼠标按键被按下时发生。
提示:与 onmouseup 事件相关联的事件触发次序 (左边/中间 鼠标按钮):

  1. onmousedown
  2. onmouseup
  3. onclick

与 onmouseup 事件相关联的事件触发次序 (右边鼠标按钮):

  1. onmousedown
  2. onmouseup
  3. oncontextmenu

onload
当页面完成加载时,显示一个提示框。

<body onload="mymessage()"></body>
function mymessage(){
    alert("消息在 onload 事件触发后弹出。");
}

onfocus
当输入字段获得焦点时,改变其背景色。

输入你的名字: <input type="text" onfocus="myFunction(this)">
<p>当输入框获取焦点时,修改背景色(background-color属性) 将被触发。</p>
function myFunction(x){
    x.style.background="yellow";
}

鼠标事件
当指针移动到元素上方时,改变其颜色;当指针移出文本后,会再次改变其颜色。

 <h1 onmouseover="style.color='red'" onmouseout="style.color='black'">将鼠标移至文部上</h1>


修改所有 <p> 元素的背景颜色:

<body>
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Runoob!</p>
<p>点击按钮修改 p 元素的背景颜色。</p>
<button onclick="myFunction()">点我</button>
<script>
    function myFunction() {
        var myCollection = document.getElementsByTagName("p");
        var i;
        for (i = 0; i < myCollection.length; i++) {
            myCollection[i].style.color = "red";
        }
    }
</script>



函数

调用带参数的函数

1.在调用函数时,您可以向其传递值,这些值被称为参数。
这些参数可以在函数中使用。
您可以发送任意多的参数,由逗号 (,) 分隔:
变量和参数必须以一致的顺序出现。第一个变量就是第一个被传递的参数的给定的值,以此类推。
实例

<p>点击这个按钮,来调用带参数的函数。</p>
<button onclick="myFunction('Harry Potter','Wizard')">点击这里</button>
<script>
function myFunction(name,job){
    alert("Welcome " + name + ", the " + job);
}
</script>

上面的函数在按钮被点击时会提示 "Welcome Harry Potter, the Wizard"。
函数很灵活,您可以使用不同的参数来调用该函数,这样就会给出不同的消息:
实例

<button onclick="myFunction('Harry Potter','Wizard')">点击这里</button>
<button onclick="myFunction('Bob','Builder')">点击这里</button>
(俩个按钮用一个函数传参)

根据您点击的不同的按钮,上面的例子会提示 "Welcome Harry Potter, the Wizard" 或 "Welcome Bob, the Builder"。

事件

1.HTML 事件可以是浏览器行为,也可以是用户行为。
(1)按钮元素中添加了 onclick 属性 (并加上代码):

实例
<button onclick="getElementById('demo').innerHTML=Date()">现在的时间是?</button>
<p id="demo"></p>

输出显示的是当前的时间(点击按钮展示)

(2)上实例中,JavaScript 代码将修改 id="demo" 元素的内容。
在下一个实例中,代码将修改自身元素的内容 (使用 this.innerHTML):

实例
<button onclick="this.innerHTML=Date()">现在的时间是?</button>
(点击按钮在按钮里展示)

(3)JavaScript代码通常是几行代码。比较常见的是通过事件属性来调用:

实例
<button onclick="displayDate()">现在的时间是?</button>
常见的HTML事件
事件描述
onchangeHTML 元素改变
onclick用户点击 HTML 元素
onmouseover用户在一个HTML元素上移动鼠标
onmouseout用户从一个HTML元素上移开鼠标
onkeydown用户按下键盘按键
onload浏览器已完成页面的加载

字符串

字符串长度

可以使用内置属性 length 来计算字符串的长度:

  var txt = "Hello World!";
  document.write("<p>" + txt.length + "</p>");
  12
  var txt="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  document.write("<p>" + txt.length + "</p>");
  26
  
特殊字符串

在 JavaScript 中,字符串写在单引号或双引号中。
因为这样,以下实例 JavaScript 无法解析:

"We are the so-called "Vikings" from the north."

字符串 "We are the so-called " 被截断。
如何解决以上的问题呢?可以使用反斜杠 (\) 来转义 "Vikings" 字符串中的双引号,如下:
 

"We are the so-called \\"Vikings\\" from the north."  

反斜杠是一个转义字符。 转义字符将特殊字符转换为字符串字符:
转义字符 (\) 可以用于转义撇号,换行,引号,等其他特殊字符。
下表中列举了在字符串中可以使用转义字符转义的特殊字符:

代码输出
\'单引号
\"双引号
\\反斜杠
\n换行
\r回车
\ttab(制表符)
\b退格符
\f换页符
字符串可以是对象

通常, JavaScript 字符串是原始值,可以使用字符创建:var firstName = "John"
但我们也可以使用 new 关键字将字符串定义为一个对象:var firstName = new String("John")

var x = "John";              // x是一个字符串
var y = new String("John");  // y是一个对象
document.getElementById("demo").innerHTML =typeof x + " " + typeof y;
typeof x // 返回 String
typeof y // 返回 Object

不要创建 String 对象。它会拖慢执行速度,并可能产生其他副作用:

var x = "John";              // x 是字符串
var y = new String("John");  // y 是一个对象
document.getElementById("demo").innerHTML = x===y;
(x === y) // 结果为 false,因为 x 是字符串,y 是对象
转换类型

你可以使用typeof操作符来查看 JavaScript 变量的数据类型。

实例

typeof"John"// 返回 string  
typeof 3.14// 返回 number  
typeof NaN                   // 返回 number  
typeof false// 返回 boolean  
typeof [1,2,3,4]              // 返回 object  
typeof {name:'John', age:34} // 返回 object  
typeof newDate()            // 返回 object  
typeof function() {}        // 返回 function  
typeof myCar                 // 返回 undefined (如果 myCar 没有声明)  
typeof null// 返回 object

请注意:

  • NaN 的数据类型是 number
  • 数组(Array)的数据类型是 object
  • 日期(Date)的数据类型为 object
  • null 的数据类型是 object
  • 未定义变量的数据类型为 undefined

如果对象是 JavaScript Array 或 JavaScript Date ,我们就无法通过typeof来判断他们的类型,因为都是 返回 object。

constructor 属性

constructor属性返回所有 JavaScript 变量的构造函数。

实例

"John".constructor                // 返回函数 String()  { \[native code\] }  
(3.14).constructor                // 返回函数 Number()  { \[native code\] }  
false.constructor                 // 返回函数 Boolean() { \[native code\] }  
\[1,2,3,4\].constructor             // 返回函数 Array()   { \[native code\] }  
{name:'John', age:34}.constructor // 返回函数 Object()  { \[native code\] }  
newDate().constructor            // 返回函数 Date()    { \[native code\] }  
function() {}.constructor        // 返回函数 Function(){ \[native code\] }

将数字转换为字符串

全局方法String()可以将数字转换为字符串。

该方法可用于任何类型的数字,字母,变量,表达式:

实例

String(x)         // 将变量 x 转换为字符串并返回  
String(123)      // 将数字 123 转换为字符串并返回  
String(100+23) // 将数字表达式转换为字符串并返回

Number 方法toString()也是有同样的效果。

实例

x.toString()  
(123).toString()  
(100+23).toString()

将布尔值转换为字符串

全局方法String()可以将布尔值转换为字符串。

String(false)       // 返回 "false"  
String(true)        // 返回 "true"

Boolean 方法toString()也有相同的效果。

false.toString()    // 返回 "false"  
true.toString()     // 返回 "true"

将日期转换为字符串

Date() 返回字符串。

Date()     // 返回 Thu Jul 17 2014 15:38:19 GMT+0200 (W. Europe Daylight Time)

全局方法 String() 可以将日期对象转换为字符串。

String(new Date())     // 返回 Thu Jul 17 2014 15:38:19 GMT+0200 (W. Europe Daylight Time)

Date 方法toString()也有相同的效果。

实例

obj = new Date()  
obj.toString()  // 返回 Thu Jul 17 2014 15:38:19 GMT+0200 (W. Europe Daylight Time)

将字符串转换为数字

全局方法Number()可以将字符串转换为数字。
字符串包含数字(如 "3.14") 转换为数字 (如 3.14).
空字符串转换为 0。
其他的字符串会转换为 NaN (不是个数字)。

Number("3.14")   // 返回 3.14  
Number(" ")      // 返回 0  
Number("")       // 返回 0  
Number("99 88")  // 返回 NaN

一元运算符 +

实例

vary ="5";     // y 是一个字符串  
varx = + y;     // x 是一个数字

如果变量不能转换,它仍然会是一个数字,但值为 NaN (不是一个数字):

实例

vary ="John";  // y 是一个字符串  
varx = + y;      // x 是一个数字 (NaN)

将布尔值转换为数字

全局方法Number()可将布尔值转换为数字。

Number(false)    // 返回 0  
Number(true)     // 返回 1

将日期转换为数字

全局方法Number()可将日期转换为数字。

d =newDate();  
Number(d)         // 返回 1404568027739

日期方法getTime()也有相同的效果。

d =newDate();  
d.getTime()       // 返回 1404568027739

自动转换类型

当 JavaScript 尝试操作一个 "错误" 的数据类型时,会自动转换为 "正确" 的数据类型。

以下输出结果不是你所期望的:

5+null   // 返回 5         null 转换为 0  
"5"+null // 返回"5null"   null 转换为 "null"  
"5"+1   // 返回 "51"      1 转换为 "1"   
"5"\-1    // 返回 4         "5" 转换为 5

自动转换为字符串

当你尝试输出一个对象或一个变量时 JavaScript 会自动调用变量的 toString() 方法:

document.getElementById("demo").innerHTML = myVar;  

myVar = {name:"Fjohn"}  // toString 转换为 "\[object Object\]"  
myVar = \[1,2,3,4\]       // toString 转换为 "1,2,3,4"  
myVar = new Date()      // toString 转换为 "Fri Jul 18 2014 09:08:55 GMT+0200"  

数字和布尔值也经常相互转换:

myVar = 123             // toString 转换为 "123"  
myVar = true            // toString 转换为 "true"  
myVar = false           // toString 转换为 "false"

使用对象构造器

本例使用函数来构造对象:

<script>
function person(firstname,lastname,age,eyecolor){
    this.firstname=firstname;
    this.lastname=lastname;
    this.age=age;
    this.eyecolor=eyecolor;
}
myFather=new person("John","Doe",50,"blue");
document.write(myFather.firstname + " is " + myFather.age + " years old.");
</script>

输出为:John is 50 years old.
在JavaScript中,this通常指向的是我们正在执行的函数本身,或者是指向该函数所属的对象(运行时)

创建 JavaScript 对象实例

一旦您有了对象构造器,就可以创建新的对象实例,就像这样:

var myFather=new person("John","Doe",50,"blue");  
var myMother=new person("Sally","Rally",48,"green");



把属性添加到 JavaScript 对象

您可以通过为对象赋值,向已有对象添加新属性:

假设 person 对象已存在 - 您可以为其添加这些新属性:firstname、lastname、age 以及 eyecolor:

person.firstname="John";  
person.lastname="Doe";  
person.age=30;  
person.eyecolor="blue";  
x=person.firstname;

在以上代码执行后,x 的值将是:John

把方法添加到 JavaScript 对象

方法只不过是附加在对象上的函数。

在构造器函数内部定义对象的方法:

function person(firstname,lastname,age,eyecolor)  { 
    this.firstname=firstname;
    this.lastname=lastname; 
    this.age=age; 
    this.eyecolor=eyecolor; 
    
    this.changeName=changeName; 
    function changeName(name) 
     { 
     this.lastname=name; 
     }  
 }
 myMother=new person("Sally","Rally",48,"green");
 myMother.changeName("Doe");
 document.write(myMother.lastname);

changeName() 函数 name 的值赋给 person 的 lastname 属性。

JavaScript for...in 循环

JavaScript for...in 语句循环遍历对象的属性。

语法

for  (variable in  object)  { 执行的代码……  }

注意:for...in 循环中的代码块将针对每个属性执行一次。

<p>点击下面的按钮,循环遍历对象 "person" 的属性。</p>
<button onclick="myFunction()">点击这里</button>
<p id="demo"></p>
function myFunction(){
    var x;
    var txt="";
    var person={fname:"Bill",lname:"Gates",age:56}; 
    for (x in person){
        txt=txt + person[x];
    }
    document.getElementById("demo").innerHTML=txt;
}
输出结果BillGates56

prototype 继承

所有的 JavaScript 对象都会从一个 prototype(原型对象)中继承属性和方法:

  • Date对象从Date.prototype继承。
  • Array对象从Array.prototype继承。
  • Person对象从Person.prototype继承。

所有 JavaScript 中的对象都是位于原型链顶端的 Object 的实例。

JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

Date对象,Array对象, 以及Person对象从Object.prototype继承。

添加属性和方法

有的时候我们想要在所有已经存在的对象添加新的属性或方法。

另外,有时候我们想要在对象的构造函数中添加属性或方法。

使用 prototype 属性就可以给对象的构造函数添加新的属性:

实例

function  Person(first, last, age, eyecolor)  {     
this.firstName = first; 
this.lastName = last; 
this.age = age; 
this.eyeColor = eyecolor; 
}  
Person.prototype.nationality = "English";
var myFather = new Person("John", "Doe", 50, "blue");
document.getElementById("demo").innerHTML =
"我父亲的国籍是 " + myFather.nationality; 

输出为我父亲的国籍是 English

当然我们也可以使用 prototype 属性就可以给对象的构造函数添加新的方法:

function Person(first, last, age, eye) {
     this.firstName \= first;
     this.lastName \= last;
     this.age \= age;
     this.eyeColor \= eye;
}
Person.prototype.name \= function() 
    return this.firstName + " " + this.lastName
}; ​
var myFather \= new Person("John", "Doe", 50, "blue");
document.getElementById("demo").innerHTML \=
"我对父亲是 " + myFather.name();

输出为我对父亲是 John Doe









































































































查看原文

赞 0 收藏 0 评论 0

张东红 发布了文章 · 2019-12-11

晚会工作人员,专区活动知识点

晚会工作人员

1.如果想显示输入vv号展示头像和昵称可以用以下方法:

显示vv号 回车显示昵称头像<body>
<label style="margin-left:20px;">用户ID:&nbsp;</label>
<span @blur="getUserInfo()" v-if="modifyModal.type == 2">{{editParams.userid}}</span>
<Input v-if="modifyModal.type == 1" style="width:120px;" v-model="editParams.userid" @blur="getUserInfo()" @keyup.enter.native="getUserInfo()"></Input>
:@keyup.enter.native=""(回车或者点击)
显示昵称:
<label style="margin-left:20px;">昵称:&nbsp;</label>     
<span style="margin-left:14px;">{{editParams.nickname}}</span>
显示照片:
<label style="margin-left:20px;">用户照片:</label></br>
<img :data-original="(editParams.photo)" style="width:80px;height:80px;" class="img_image">
<a :href="editParams.photo" class="http_a" download='' target="_blank"> <Button type="warning"  >下载图片</Button></a>
a标签链接 下载图片

js相应的地方传参数

2.传分页参数的时候要根据后台返回的传

this.totalSize = data.total || 0;    

3.(新增显示用户头像以后上传裁剪图片不显示裁剪图像或者是编辑不显示裁剪头像,还有就是新增不显示用户头像只有添加裁剪头像以后才能显示裁剪后的头像)这是遇到的一个坑

    if (cutImg.dom_shade_img.src == location.href && !this.editParams.photo) {
        this.$Message.success('请添加照片');
        return
    }
    if (this.editParams.photo && cutImg.dom_shade_img.src == location.href) {
        this.submitData(this.editParams.photo, 1)
        return
    }

传参数的时候传裁剪后的图片或者是头像

    photo: type == 1 ? this.editParams.photo : ('https://'+photo),

type == 1是我加了个区分 新增编辑的确定用1或2判断

   <Button type="success" @click="modifySure" v-if="modifyModal&&modifyModal.type == 1">保存</Button>
   <Button type="success" @click="modifySure" v-if="modifyModal&&modifyModal.type == 2">确定</Button>

4.裁剪头像的写法在晚会工作人员里

专区活动

1.把俩个跳转页面的共同table写在了一起(因为内容是一样的)

      <div class="form_zuhud" v-if="recommendFlag||modifyModal">
            <Table :stripe="false" border align="center" >
                <thead>
                    <tr>
                        <th>专区</th>
                        <th>活动</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>{{parentStractName}}</td>
                        <td>{{title}}</td>
                    </tr>
                </tbody>
            </Table>
        </div>
  1. 添加工作人员的参数传错了 再添加按钮的部分添加然后接口传参用

        amend(item){        
           this.activityid = item.activityid;
           this.parentStractId = item.parentStractId;                   
           this.dataDome(item.activityid,item.parentStractId)    
           },

    dataDome给添加接口赋值,(查询已添加的人展示出来),详细看代码

查看原文

赞 0 收藏 0 评论 0

张东红 收藏了文章 · 2019-12-09

前端培训-初级阶段(1 - 4)

本着提升技术水平,打牢基础知识的中心思想。前端内部开始小课堂啦(本人凭借身高优势,人群中多看了我一眼,稳稳拿到第一课)。

前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。

好了,不闲扯,接下来进入我们的正题。

我们要讲什么

  1. 课程体系介绍、HTML+CSS基本入门知识
  2. 网站运行原理
  3. HTML常用标签、表单新类型、网页SEO优化
  4. HTML5语义化标签、音视频标签

HTML+CSS 简介

HTML(超文本标记语言 — HyperText Markup Language)是构成 Web 世界的一砖一瓦。它定义了网页内容的含义和结构。它使用标记来注明文本、图片和其他内容,以便于在 Web 浏览器中显示。HTML 中的标签不区分大小写

举例来说, 我的内容是一些段落(<p>)还是一个有序列表(<ul>)?我的网页上有插入图片(<img>)吗?有数据表格(<table>)吗?

CSS(层叠样式表 — Cascading Style Sheets),是一种样式表语言,用来描述 HTML 或 XML(包括如 SVG、MathML、XHTML 之类的 XML 分支语言)文档的呈现。CSS 描述了 HTML 元素在屏幕上应该如何渲染。

举例来说,我的文字是黑色还是红色的?在屏幕的何处展示内容?用什么背景图像和颜色来装饰?

网站运行原理(发展历程)

  1. HTML 创建结构,我们想在互联网发布我们的信息,我们通过文字、图片、音视频。
  2. CSS 美化界面,页面太丑了,都是文字,我们想要排版一下。
  3. JS 逻辑控制,我们想要校验表单,做个轮播图什么的。
  4. 静态服务部署(文件服务器),通过上面的内容,我们可以有一个漂亮的页面了,接下来我们需要发布到网上,让其他人可以访问。
  5. IP 可以理解为唯一标识(身份证),通过 IP 可以很快找到我们的服务器。
  6. 通过上面的内容,其他人可以通过网络来访问我们的页面,但是 IP 是一串数字,太难记了。我们需要一个好记的域名。
  7. 动态服务,网站壮大之后,我们需要区分用户(登录,评论),这个时候我们要引入服务端(node/java/php)

到这里就差不多了。当然还有新的问题,新的问题也会有新的解决方案。

HTML 常用标签

<!DOCTYPE> 定义文档类型。

<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。
<!DOCTYPE> 声明不是 HTML标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。
在 HTML 4.01 中,<!DOCTYPE> 声明引用DTD,因为 HTML 4.01 基于 SGML。DTD 规定了标记语言的规则,这样浏览器才能正确地呈现内容。 HTML5 不基于SGML,所以不需要引用 DTD。
提示:请始终向 HTML 文档添加 <!DOCTYPE> 声明,这样浏览器才能获知文档类型。
标签名描述状态
<a>标签定义超链接。页面互联的基础设施,用于从一张页面链接到另一张页面。
<div>无敌块结构
<span>无敌行内结构
<form>表单
<input>表单控件
<img>图像
<meta>定义关于 HTML 文档的元信息。
<p>定义段落
<table>表格
<center>居中×
<font>字体样式×
<header>表现HTML的标题数据HTML5-语义
<footer>页面的页脚部分HTML5-语义
<nav>页面中的导航元素HTML5-语义
<article>正文内容HTML5-语义
<section>表示页面中的一个独立内容区块,里面有自己的结构,比如章节、页眉、页脚、内容部分HTML5-语义
<aside>表现页面侧边栏内容。HTML5-语义
<canvas>画布能力HTML5-功能

HTML5 标签

这个东西也出来好久了。相信大家也都开始使用了。核心就是增加了更多的语义化标签,废弃了一些纯粹显示效果的标记

HTML5 中的一些有趣的新特性:
用于绘画的 canvas 元素
用于媒介回放的 video 和 audio 元素
对本地离线存储有更好的支持
新的特殊内容元素,比如 article、footer、header、nav、section
新的表单控件,比如 calendar、date、time、email、url、search
clipboard.png
  1. input所有标签测试地址
  2. 定位测试测试-需要科学上网-使用的是谷歌的服务
  3. 录音和视频测试地址

网页 SEO

SEO 优化是搜索引擎优化(Search Engine Optimization)。这个问题,面试经常被问到有没有。其实有个简单的办法,,毕竟人家搜索引擎公司也是要挣钱嘛。

  1. 在首页加入 meta 标签提供一些元数据(titledescriptionkeywords
  2. 注意合理使用语义化标签(h1
  3. 合理的使用属性(imgalt
  4. 禁止外链(no follow
  5. 合理的 robots.txtsitemap百度链接提交
Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。
Sitemap 可方便网站管理员通知搜索引擎他们网站上有哪些可供抓取的网页。最简单的 Sitemap 形式,就是XML 文件,在其中列出网站中的网址以及关于每个网址的其他元数据(上次更新的时间、更改的频率以及相对于网站上其他网址的重要程度为何等),以便搜索引擎可以更加智能地抓取网站。

参考资料

  1. (引用) 培训目录出处-已备份到笔记
  2. 浏览器输入URL后HTTP请求返回的完整过程
  3. 输入URL到页面加载完成
  4. MDN
  5. (引用) HTML <!DOCTYPE> 标签
  6. 求助道面试题,在前端项目中,如何进行seo优化,你在哪些项目里有过seo优化,效果如何?
  7. 前端进阶系列(一):SEO和HTML语义化
  8. (引用) Robots协议
  9. (引用) sitemap
  10. SEO怎么优化网站
查看原文

张东红 发布了文章 · 2019-12-09

文章复审笔记

1.参数里面有类似文章状态(0私密,2公开)好几种的可以用以下方法
<td>{{authstatusFn(item.authstatus)}}</td>

       authstatusFn(authstatus){
            if (authstatus == -1) {
                return '新创建未保存';
            } else if (authstatus == 0) {
                return '私密';
            } else if (authstatus == 1) {
                return '部分可见';
            }else if (authstatus == 2) {
                return '公开';
            }
        },

2.(1)处理图片可以用这个
<td><img :data-original="imgUrlCdn(item.userimg)" style="max-width:100px;"></td>

    imgUrlCdn(_url) {
        if (_url) {
            if (_url.indexOf('http://file') != -1) {
            return _url.replace("http://file", 'http://upcdn.file');
            } else {
            return 'https://images.51vv.com/upload/' + _url
            }
        } else {
            return ''
        }
        },

(2) 裁剪图片用这个
<td><img :data-original="tailor(data.photo)" style="width:60px;height:60px;" class="item_image"></td>

        tailor (url, type) { // 裁剪图片
            if (url) {
                var changeHead = url.replace("http://file",'http://upcdn.file');
                if (type == 1) {
                    return changeHead
                } else {
                    var suffix = changeHead.split('.')[changeHead.split('.').length-1]
                    if (suffix == 'png') {
                        return changeHead+'.cw100.png'
                    } else if (suffix == 'jpg') {
                        return changeHead+'.cw100.jpg'
                    } else if (suffix == 'jpeg') {
                        return changeHead+'.cw100.jpeg'
                    } else if (suffix == 'gif') {
                        return changeHead+'.cw100.gif'
                    } else {
                        return changeHead
                    }
                }
            } else {
                return 'http://upcdn.mpres.51vv.com/image/a52b2ebcf09b9575d80b99b777c4fd25.png'
            }
        },        
        
        
查看原文

赞 0 收藏 0 评论 0

张东红 发布了文章 · 2019-12-09

文章审核笔记

1.分页

   <Loading v-show="loading==null"></Loading>
    <p id="prompting" v-show="tableList && (tableList.length == 0)">暂无有效数据可供展示</p>
    <Pagination class="ui-pagination" :total="totalSize" :current="curPage" :pageSize="viewNumber" showSkip showTotal @change="pageChange"></Pagination>

2.这个是文章预览展示的(敏感词,图片划红框,标红色字)

 // 原始文章
  getOriginArticle(){
  this.$http.post('/mpcms/vvarticle/getVvmusicArticleSectionByEntityShow', {articleid: this.busiid}, {emulateJSON: true}).then(function (res) {
    // console.log('审核',res);
    var data = res.body;
    data.list.unshift({
      sectionid:-1,
      textraw:data.list[0].articletitle,
      sectiontype:-1

    },{
      sectionid:-1,
      mediaurl:data.list[0].coverpic,
      sectiontype:-2
    })
    this.originList = data.list;
    console.log(1122,this.originList);
    this.getDealArticle();
   
  });
}, 
// 处理后的文章
getDealArticle(){
  this.$http.post('/mpcms/metadata/getArticleAllByBusiid', {busiid: this.busiid}, {emulateJSON: true}).then(function (res) {
    // console.log('审核',res);
    var data = res.body;

    if (data.state == 1000) {
      let dealList = data.list;
      for(let i =0; i<this.originList.length;i++){
        this.originList[i].linkurl = this.originList[i].linkurl && JSON.parse(this.originList[i].linkurl);
        for(let j=0;j<dealList.length;j++){
          if(this.originList[i].sectionid == dealList[j].extid2){
            if(dealList[j].type == 1){
              // 处理文字
              if(dealList[j].hint){
                let arrHint = JSON.parse(dealList[j].hint);
                for(let r=0;r<arrHint.length;r++){
                  let reg = new RegExp("(" + arrHint[r] + ")", "ig");
                  dealList[j].text = dealList[j].text.replace(reg, '<font class="font_a">$1</font>');
                }
                 this.originList[i].textraw =  dealList[j].text;
              }

            }
            if(dealList[j].type == 3){
              // 处理图片
              this.originList[i].antispamState= dealList[j].antispamState;
              this.originList[i].label= dealList[j].label;
            }
          }
        }
      }

     console.log(this.originList);
      this.$refs.articleInfo.render(this.originList);

    } else {
        this.$Message.error(data.msg);
    }
  });
}, 

3.

  parseStatus (antispamState) {
  if (antispamState == -1) {
    return '初始化';
  } else if (antispamState == 0) {
    return '通过';
  } else if (antispamState == 1) {
    return '嫌疑';
  }else if (antispamState == 2) {
    return '不通过';
  } else if (antispamState == 3) {
    return '纯表情';
  }
},



查看原文

赞 0 收藏 0 评论 0

张东红 发布了文章 · 2019-12-09

家族投稿白名单知识点

1.时间(formatDate(data.data, 'yyyy-MM-dd hh:mm:ss'))

  formatDate: function(time, fmt) {
  if (time) {
    var date = new Date(time);
    var o = {
      "y+": date.getFullYear(),~~~~
      "M+": date.getMonth() + 1,
      "d+": date.getDate(),
      "h+": date.getHours(),
      "m+": date.getMinutes(),
      "s+": date.getSeconds()
    };
    for (var k in o) {
      if (new RegExp("(" + k + ")").test(fmt)) {
        var str = o[k] + "";
        fmt = fmt.replace(RegExp.$1, str.length === 1 ? "0" + str : str);
      }
    }
    return fmt;
  } else {
    return "";
  }
},

2.判断不能重复添加

 if (data.state === 1000) {
 if (data.count != 1) {
   this.insertAuthenticationFamilyWhitelist();
 } else {
   this.$Message.warning("该家族已添加过,不能重复添加");
      this.addShow = false;
   }
 } else if (data.state === 2000) {
      this.$Message.warning(data.msg);
 }

3.删除(deleteAlbum)

  deleteAlbum(data) {
  let params = { familyid: data.familyid };
  this.$confirm("此操作将永久删除该家族, 是否继续?", {
    maskClose: true,
    ok() {
      this.$http
        .post(
          "/mpcms/space/updateAuthenticationFamilyWhitelist",
          this.ajaxDateFormat(params),
          {
            emulateJSON: true
          }
        )
        .then(function(response) {
        //   console.log("删除返回", response);
          var data = response.body;
          if (data && data.state == 1000) {
            this.$Message.success("删除成功!");
            this.init();
          } else {
            this.$Message.error("接口报错了");
          }
        });
    },
    cancel() {
      console.info("cancel");
    }
  });
},
  1. if (data.state == 1000) {
         this.$Message.warning("添加成功");
         this.addShow = false;
         this.init();
       } else if (data.state === 2000) {
         this.$Message.warning(data.msg);
       }   
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
查看原文

赞 0 收藏 0 评论 0

张东红 发布了文章 · 2019-10-08

Vue.js基础教程

开发工具准备:

1.根据个人喜欢选择IDE,我使用的是WebStorm,推荐使用Atom和VSCode;
2.安装git base和node.js;
3.安装vue-cli,命令npm i -g @vue/cli;
4.新建vue-cli项目:
方法一:通过图形界面进行安装vue ui;
方法二:通过命令行安装vue create project-name
5.运行项目npm run serve,端口8080。

双向绑定v-model

双向绑定大多用于表单事件,通过监听使用者输入的事件来更新内容。
现阶段大部分工作在App.vue上,template与普通写法一致,js写法:

export default {
    name: 'app',
    data() {
        return {
            title: 'vue.js',
            myname: '请输入名字'
        }
    }
}

去掉空白符.trim
直接在v-model后加上.trim即可。

<input type="text" v-model.trim="name" value="name">

懒加载.lazy
在离开input时才更新输入的内容,在v-model后加上.lazy即可。

限定输入数字.number
在v-model后加上.number即可。

遍历v-for
遍历有一个基本的模板:

<div id="app">
    <ul v-for="(item,index) in member" :key="index">
        <li>{{item}}</li>
    </ul>
</div>

组件component
在App.vue中引入components中的组件:

<template>
  <div id="app">
    <Card />
  </div>
</template>

<script>
  import Card from './components/Card'
  
  export default {
    components: {
      Card
    }
  }
</script>

数据传递props

<template>
    <div id="app">
        <Card :cardData="cardData"/>
    </div>
</template>

其中:cardData="cardData"是这个组件的核心,用于绑定属性cardData。其他数据展示工作放在Card.vue组件中进行。

<template>
    <div class="card_wall">
        <div class="card" v-for="item in cardData" :key="item.name">
            <div class="card_title">{{item.name}}</div>
            <div class="card_body">
                <p>生日:{{item.birthday}}</p>
                <p>E-mail:{{item.mail}}</p>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        props: {
            cardData: {
                type: Array,
                required: true
            }
        }
    }
</script>

这里解析一下<div class="card_wall"></div>包裹<div class="card"></div>主要是方便后期应用扩展,以及让应用整体更稳定。

生命周期
我不喜欢用官网的生命流程图来讲解这个内容,使用文字表达更加让思维清晰。

1.初始化:设置数据监听,编译模板,挂载到DOM并在数据变化时更新DOM等;
2.生命周期钩子:其实就是一个过程处理,类似于服务站。

生命周期钩子简介

 1.beforeCreate:实例初始化
 2.created:实例建立完成(可以取得$data)
 3.beforeMount:模板挂载之前(还没有生成html)
 4.mounted:模板挂载完成
 5.beforeUpdate:如果data发生变化,触发组件更新,重新渲染
 6.updated:更新完成
 7.beforeDestroy:实例销毁之前(实例还可以使用)
 8.destroyed:实例已销毁(所有绑定被解除、所有事件监听器被移除、所有子实例被移除)
生命周期钩子用得最多的是mounted,主要用在调用属性、方法的时候,

指令

v-once指令
第一次渲染完成后变为静态内容,其下的所有子元素都是这样的效果。

v-pre指令
v-pre指令会让指定元素被忽略。

v-cloak指令
v-cloak指令用于去除页面渲染数据时出现闪现的情况,使用方法:

<template>
  <div id="app">
    <div v-cloak>${ item.title }</div>
  </div>
</template>

<style>
  [v-cloak] {
      display: none;
  }
</style>

v-html指令

v-html指令会把html标签渲染成DOM显示在页面上。
v-html指令只能对可信任的用户使用,否则容易受到XSS攻击。

动画
Vue动画一般在真正需要使用的情况下才加入页面,推荐在CSS中使用动画。

加入渐变的时机

1.v-if条件渲染
2.v-show条件显示
3.动态组件
4.组件的根节点

渐变的分类

1.v-enter定义进入渐变时开始的样式。
  只存在组件插入前,组件插入后就移除。
2.v-enter-active定义进入渐变的过程效果,可以设定渐变过程的时间(duration)和速度曲线(easing curve)。
  在组件被插入前生效,在完成动画时移除。
3.v-enter-to定义进入渐变后结束的样式。
  在组件被插入后生效,同时v-enter被移除,并在完成进入渐变动画时移除。
4.v-leave定义离开渐变时开始的样式。
  在触发组件离开渐变时生效,接着马上移除。
5.v-leave-active定义离开渐变的过程效果,可以设定渐变过程的时间(duration)和速度曲线(easing curve)。
  在触发组件离开渐变时生效,在完成动画时移除。
6.v-leave-to定义离开渐变后结束的样式。
  在触发组件离开渐变时生效,同时v-enter被移除,并在完成离开渐变动画时移除。

transition自定义名称

<template>
  <div id="app">
    <div class="main">
      <button @click="change = !change">縮放控制器</button>
      <transition name="zoom">
        <div v-if="change" class="ant_man_style"></div>
      </transition>
    </div>
  </div>
</template>
.zoom-enter, .zoom-leave-to {
width: 0px;
height: 0px;
}
.zoom-enter-active, .zoom-leave-active {
transition: width 1s, height 1s;
}

animation

可以使用CSS中的animation动画设计更为华丽的效果。
.zoom-leave-active {
animation: special_effects 1.5s;
}

.zoom-enter-active {
animation: special_effects 1.5s reverse;
}
@keyframes special_effects {}

transition自定义动画类别

除了在<transition>中设定name自定义前缀(属性),还可以预设动画类别。
    ·enter-class定义进入动画时开始的样式。
    ·enter-active-class定义进入动画的过程效果。
    ·enter-to-class定义进入动画后结束的样式。
    ·leave-class定义离开动画时开始的样式。
    ·leave-active-class定义离开动画的过程效果。
    ·leave-to-class定义离开动画后结束的样式。

以上六个自定义属性优先级别高于一般渐变类别。

JavaScript钩子

<transition>还可以绑定JavaScriptHooks,除了单独使用,也能结合CSS transition和animations一起使用。   
     ·beforeEnter(el)在进入渐变或动画前生效。
     ·enter(el,callback)在进入渐变或动画的组件插入时生效。
     ·afterEnter(el)在进入渐变或动画结束时生效。
     ·enterCanceled(el)在未完成渐变或动画时取消。
     ·beforeLeave(el)在离开渐变或动画前生效。
     ·leaveCancelled(el)在未完成渐变或动画时取消。
     
<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"
  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled">
  <div v-if="change" class="ant_man_style"></div>
</transition>

在enter和leave中必须使用done,不然它们会同时生效,动画也会瞬间完成。

设定初始载入时的渐变
如果想要设定一开始载入画面时组件的渐变效果,可以通过设定appear属性来实现。

·appear-class载入时开始的样式。
·appear-to-class载入过程的样式。
·appear-active-class载入结束时样式。
    <transition
     appear
     appear-class="show-appear-class"
     appear-to-class="show-appear-to-class"
     appear-active-class="show-appear-active-class">
    </transition>

先在<transition>标签内加入appear,接着类似自定义动画可以给class name命名。

初始载入JavaScript Hooks

 ·beforeAppear载入前
 ·appear载入时
 ·afterAppear载入后
 ·appearCancelled取消载入(载入开始后)
    
<div id="app">
  <transition
    appear
    @before-appear="beforeAppear"
    @appear="appear"
    @after-appear="afterAppear"
    @appear-cancelled="appearCancelled">
    <div v-if="change" class="ant_man_style"></div>
  </transition>
</div>

key

对相同的标签元素使用key进行区分。

渐变模式in-out和out-in

 in-out模式
  1.新加入的元素做渐变进入。
  2.渐变进入结束后,原存在的元素再渐变离开。
 out-in模式
  1.原存在的元素渐变离开。
  2.渐变离开结束后,新元素再渐变进入。
<transition mode="out-in"></transition>
<transition mode="in-out"></transition>

列表过渡

·<transition-group>会渲染出一个html标签,预设是<span>,也可以选择自定义tag为其他标签。
·无法使用(渐变模式in-out和out-in),因为不再是元素之间来回切换。
·每个元素需要设定一个key值,不能重复。

列表乱数排序

<transition-group>能够改变数组的排序,使用前需要先安装shuffle

npm i --save lodash.shuffle

let shuffle = require('lodash.shuffle')

过滤器filter

filters串联
filter可以同时串联多个filter函数。

filters参数
$emit

1.父组件可以使用props把数据传递给子组件。
2.子组件可以使用$emit触发父组件的自定义事件。

查看原文

赞 0 收藏 0 评论 0

张东红 发布了文章 · 2019-09-04

js(数组,对象)

1.js中的最重要的类型就是对象
1.对象是名/值对的集合,或字符串到值映射的集合

var book = {
   topic:"js";     //属性"topic"的值是"js"
   fat:true        //属性"fat"的值是true
};

2.通过"."或"[]"来访问对象属性

book.topic                   //"js"
book["fat"]                  //另一种获取属性的方式
book.author = "Flanagan";    //通过赋值创建一个新的属性
book.contents = {}           //{}是个空对象,它没有属性

3.js同样支持数组(以数组为索引的列表)

primes[primes.length -1]    //数组的最后一个元素
var empty = []              //[]是空数组,它具有0个元素
empty.length                //输出为0

4.数组和对象都可以包含一个数组或对象

var points = [            //具有俩个元素的数组
  {x: 0,y: 0},            //每个元素都是一个对象
  {x: 1,y: 1}             
];
var data = [              //一个包含俩个属性的对象
  trial1: [[1,2],[3,4]],  //每一个属性都是数组
  trial2: [[2,3],[4,5]]   //数组的元素也是数组
]

5.js中 最常见的表达式写法:

3+2                          // 5  加法
3-2                          // 1  减法
3*2                          // 6  乘法
3/2                          // 1.5 除法
points[1].x - points[0].x    // 1 更复杂的操作数也能正常工作
"3"+"2"                      // 32  字符串链接
var count = 0;               //定义一个变量
count += 2;                  //自增2: 和"count = count + 2;"写法一样
count *= 3;                  //自增3: 和"count = count * 2;"写法一样

6.用二维数组做一个9*9表格

var table = new Array(10);                        //表格有10行
for(var i=0;i<table.length;i++){
    table(i) = new Array(10);                     //每行有10列
    for(var row=0;row<table.length;row++){
        for(var col=0;col<table.length;col++){
            table[row][col] = row*col;
        }
    }
} 

7.使用多维数组来计算
var product = table5; //35

8.JavaScript 数组方法
js方法tostring()把数组转换为数组值(逗号分隔)的字符串

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  document.getElementById("demo").innerHTML = fruits.toString();
  输出结果是:
             Banana,Orange,Apple,Mango

jion()方法也可以将所有数组元素结合为一个字符串
它的行为类似tostring(),还可以规定分隔符

   var fruits = ["Banana", "Orange","Apple", "Mango"];
   document.getElementById("demo").innerHTML = fruits.join(" * "); 
   结果:
       Banana * Orange * Apple * Mango
       

13.Popping和Pushing
Popping和Pushing指的是:
从数组弹出项目,或向数组推入项目
Popping:
pop()方法从数组中删除最后一个元素

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  fruits.pop();              // 从 fruits 删除最后一个元素("Mango")
  document.getElementById("demo").innerHTML = fruits;
  结果:
      Banana,Orange,Apple

pop()方法返回“被弹出”的值

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  document.getElementById("demo").innerHTML = fruits.pop();  
  结果: 
      Mango
      

pushing:
push()方法(在数组结尾处)向数组添加一个新的元素

 var fruits = ["Banana", "Orange", "Apple", "Mango"];
 document.getElementById("demo").innerHTML = fruits;
 function myFunction() {
   fruits.push("Kiwi");
   document.getElementById("demo").innerHTML = fruits;
 }
 结果:   
     Banana,Orange,Orange,Mango,Kiwi

push()方法返回新数组的长度(新加一个数组并返回长度):

 var fruits = ["Banana", "Orange", "Apple", "Mango"];
 document.getElementById("demo1").innerHTML = fruits;    
 function myFunction() {
   document.getElementById("demo2").innerHTML = fruits.push("Lemon");
   document.getElementById("demo1").innerHTML = fruits;
 }
 结果:
      Banana,Orange,Orange,Mango,Kiwi
      5
      
      

位移元素
位移与弹出等同,但处理首个元素而不是最后一个
shift()方法会删除首个数组元素,并把所有其他元素"位移"到更低的索引

   var fruits = ["Banana", "Orange", "Apple", "Mango"];
   fruits.shift();            // 从 fruits 删除第一个元素 "Banana"
   document.getElementById("demo").innerHTML = fruits;
   结果: 
       Orange,Apple,Mango

shift()方法返回“被移除”的字符串(首个元素)

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  document.getElementById("demo").innerHTML = fruits.shift();  
  结果:
      Banana

unshift()方法(在开头)向数组添加新元素,并"返回位移"旧元素

  var fruits = ["Banana", "Orange", "Apple", "Mango"];
  document.getElementById("demo").innerHTML = fruits;
  function myFunction() {
    fruits.unshift("Lemon");
    document.getElementById("demo").innerHTML = fruits;
  }
  结果:
      Lemon,Banana,Orange,Apple,Mango

unshift()方法返回新数组的长度

 var fruits = ["Banana", "Orange", "Apple", "Mango"];
 document.getElementById("demo2").innerHTML = fruits.unshift("Lemon");
 结果:
     5

更改元素
通过使用它们的索引号来访问数组元素:
数组索引(下标)以 0 开始。[0] 是第一个数组元素,[1] 是第二个,[2] 是第三个 ...

var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo1").innerHTML = fruits;
fruits[0] = "Lemon";
document.getElementById("demo2").innerHTML = fruits;

结果:

   Banana,Orange,Apple,Mango
   Lemon,Orange,Apple,Mango

length 属性提供了向数组追加新元素的简易方法:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo").innerHTML = fruits;    
function myFunction() {
  fruits[fruits.length] = "Lemon";
  document.getElementById("demo").innerHTML = fruits;
}
结果:
   Banana,Orange,Apple,Mango,Lemon


删除元素
既然 JavaScript 数组属于对象,其中的元素就可以使用 JavaScript delete 运算符来删除:

<p id="demo1"></p>
<p id="demo2"></p>    
<script>
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo1").innerHTML =
"第一种水果是:" + fruits[0];
delete fruits[0];
document.getElementById("demo2").innerHTML =
"第一种水果是:" + fruits[0];
</script>
结果:
    第一种水果是:Banana
    第一种水果是:undefined

使用 delete 会在数组留下未定义的空洞。请使用 pop() 或 shift() 取而代之。

拼接数组
splice() 方法可用于向数组添加新项

<button onclick="myFunction()">试一试</button>
<p id="demo1"></p>
<p id="demo2"></p>
<script>
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo1").innerHTML = "原数组:<br>" + fruits;
function myFunction() {
   fruits.splice(2,0, "Lemon", "Kiwi");
   document.getElementById("demo2").innerHTML = "新数组:<br>" + fruits;
}
</script>
结果:
    原数组:
    Banana,Orange,Apple,Mango        
    新数组:
    Banana,Orange,Lemon,Kiwi,Apple,Mango
    

第一个参数(2)定义了应添加新元素的位置(拼接)。
第二个参数(0)定义应删除多少元素。
其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。

splice() 方法返回一个包含已删除项的数组:

<p id="demo1"></p>
<p id="demo2"></p>
<p id="demo3"></p>    
<script>
var fruits = ["Banana", "Orange", "Apple", "Mango"];
document.getElementById("demo1").innerHTML = "原数组:<br> " + fruits;    
function myFunction() {
  var removed = fruits.splice(2, 2, "Lemon", "Kiwi"); 
  document.getElementById("demo2").innerHTML = "新数组:<br>" + fruits;
  document.getElementById("demo3").innerHTML = "已删除项:<br> " + removed; 
}
结果:
    原数组:
    Banana,Orange,Apple,Mango        
    新数组:
    Banana,Orange,Lemon,Kiwi        
    已删除项:
    Apple,Mango

使用splic()来删除元素
通过聪明的参数设定,您能够使用 splice() 在数组中不留“空洞”的情况下移除元素:

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    document.getElementById("demo").innerHTML = fruits;
    function myFunction() {
      fruits.splice(0, 1);
      document.getElementById("demo").innerHTML = fruits;
    }
    结果:
        Orange,Apple,Mango

合并(连接)数组
concat() 方法通过合并(连接)现有数组来创建一个新数组:
实例(合并两个数组)

 var myGirls = ["Emma", "Isabella"];
 var myBoys = ["Jacob", "Michael", "Ethan"];
 var myChildren = myGirls.concat(myBoys);    
 document.getElementById("demo").innerHTML = myChildren;
 结果:
     Emma,Isabella,Jacob,Michael,Ethan

concat() 方法不会更改现有数组。它总是返回一个新数组。
concat() 方法可以使用任意数量的数组参数:

实例(合并三个数组)

var arr1 = ["Emma", "Isabella"];
var arr2 = ["Jacob", "Michael", "Ethan"];
var arr3 = ["Joshua", "Daniel"];    
var myChildren = arr1.concat(arr2, arr3);     
document.getElementById("demo").innerHTML = myChildren;
结果:
   Emma,Isabella,Jacob,Michael,Ethan,Joshua,Daniel

concat() 方法也可以将值作为参数
实例(将数组与值合并)

var arr1 = ["Emma", "Isabella"];
var myChildren = arr1.concat(["Jacob", "Michael", "Ethan"]); 
document.getElementById("demo").innerHTML = myChildren;
结果:
    Emma,Isabella,Jacob,Michael,Ethan


裁剪数组
slice()用数组的某个片段切出新的数组
本例从数组元素 1 ("Orange")开始切出一段数组:

    var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
    var citrus = fruits.slice(1);
    document.getElementById("demo").innerHTML = fruits + "<br><br>" + citrus;
    结果:
        Banana,Orange,Lemon,Apple,Mango
        Orange,Lemon,Apple,Mango

slice()创建新数组,它不会从原数组中删除任何元素:
本例从数组元素 3 ("Apple")开始切出一段数组:

   var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
   var citrus = fruits.slice(3);
   document.getElementById("demo").innerHTML = fruits + "<br><br>" + citrus;
   结果:
       Banana,Orange,Lemon,Apple,Mango
       Apple,Mango           

slice()可以接受俩个参数,比如(1,3)
该方法会从开始参数选取元素,直到结束参数(不包括)为止:

  var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
  var citrus = fruits.slice(1,3);
  document.getElementById("demo").innerHTML = fruits + "<br><br>" + citrus;
  结果:
      Banana,Orange,Lemon,Apple,Mango
      Orange,Lemon

如果结束参数被省略,比如第一个例子,则 slice() 会切出数组的剩余部分:

 var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
 var citrus = fruits.slice(2);
 document.getElementById("demo").innerHTML = fruits + "<br><br>" + citrus;
 结果:
     Banana,Orange,Lemon,Apple,Mango
     Lemon,Apple,Mango

自动 toString()
如果需要原始值,则 JavaScript 会自动把数组转换为字符串。下面两个例子将产生相同的结果:

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    document.getElementById("demo").innerHTML = fruits.toString();
    
    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    document.getElementById("demo").innerHTML = fruits;
    俩个结果相同:
       Banana,Orange,Apple,Mango
       


js中for Eash ,for in, fou of循环用法
一.一般的遍历数组的方法:

  var array = [1,2,3,4,5,6,7];  
  for (var i = 0; i < array.length; i) {  
      console.log(i,array[i]);  
  }  

二、用for in的方遍历数组

for(let index in array) {  
    console.log(index,array[index]);  
};  

三、forEach

array.forEach(v=>{  
  console.log(v);  

});
array.forEach(function(v){

 console.log(v);  

});

四、用for in不仅可以对数组,也可以对enumerable对象操作

var A = {a:1,b:2,c:3,d:"hello world"};  
for(let k in A) {  
    console.log(k,A[k]);  
} 

五、在ES6中,增加了一个for of循环,使用起来很简单

for(let v of array) {  
    console.log(v);  
};  
  let s = "helloabc"; 
  for(let c of s) {  
  console.log(c); 
 }

总结来说:for in总是得到对像的key或数组,字符串的下标,而for of和forEach一样,是直接得到值
结果for of不能对象用
对于新出来的Map,Set上面

var set = new Set();  
set.add("a").add("b").add("d").add("c");  
var map = new Map();  
map.set("a",1).set("b",2).set(999,3);  
for (let v of set) {  
    console.log(v);  
}  
console.log("--------------------");  
for(let [k,v] of map) {  
    console.log(k,v);  
}  



javascript遍历对象详细总结
1.原生javascript遍历
(1)for循环遍历

let array1 = ['a','b','c'];
for (let i = 0;i < array1.length;i++){
  console.log(array1[i]);  // a  b  c 
}

(2)JavaScript 提供了 foreach() map() 两个可遍历 Array对象 的方    

forEach和map用法类似,都可以遍历到数组的每个元素,而且参数一致; 

Array.forEach(function(value , index , array){ //value为遍历的当前元素,index为当前索引, 

array为正在操作的数组

  //do something
},thisArg)      //thisArg为执行回调时的this值

不同点:
forEach() 方法对数组的每个元素执行一次提供的函数。总是返回undefined;
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。返回值是一个新的数组;
例子如下:

var array1 = [1,2,3,4,5];     
var x = array1.forEach(function(value,index){     
    console.log(value);   //可遍历到所有数组元素    
    return value + 10
});
console.log(x);   //undefined    无论怎样,总返回undefined     
var y = array1.map(function(value,index){     
    console.log(value);   //可遍历到所有数组元素    
    return value + 10
});
console.log(y);   //[11, 12, 13, 14, 15]   返回一个新的数组

对于类似数组的结构,可先转换为数组,再进行遍历

let divList = document.querySelectorAll('div');   //divList不是数组,而是nodeList
 
//进行转换后再遍历
[].slice.call(divList).forEach(function(element,index){
  element.classList.add('test')
})
 
 
Array.prototype.slice.call(divList).forEach(function(element,index){
  element.classList.remove('test')
})
 
[...divList].forEach(function(element,index){   //<strong>ES6写法</strong>
  //do something
})

复制代码
(3)for ··· in ··· / for ··· of ···

for...in 语句以任意顺序遍历一个对象的可枚举属性。对于每个不同的属性,语句都会被执行。每次迭代时,分配的是属性名  

补充 : 因为迭代的顺序是依赖于执行环境的,所以数组遍历不一定按次序访问元素。 因此当迭代那些访问次序重要的 arrays 时用整数索引去进行 for 循环 (或者使用 Array.prototype.forEach() 或 for...of 循环) 。

    let array2 = ['a','b','c']
    let obj1 = {
      name : 'lei',
      age : '16'
    }
     
    for(variable  in array2){   //variable  为 index
      console.log(variable )   //0 1 2
    }
     
    for(variable  in obj1){   //variable 为属性名
      console.log(variable)   //name age
    }

ES6新增了 遍历器(Iterator)机制,为不同的数据结构提供统一的访问机制。只要部署了Iterator的数据结构都可以使用 for ··· of ··· 完成遍历操作 ( Iterator详解 : http://es6.ruanyifeng.com/#do... ),每次迭代分配的是 属性值

原生具备 Iterator 接口的数据结构如下:

Array Map Set String TypedArray 函数的arguments对象 NodeList对象

    let array2 = ['a','b','c']
    let obj1 = {
      name : 'lei',
      age : '16'
    }
     
    for(variable  of array2){   //<strong>variable  为 value</strong>
      console.log(variable )   //'a','b','c'
    }
     
    for(variable  of obj1){  //<strong>普通对象不能这样用</strong>
      console.log(variable)   // 报错 : main.js:11Uncaught TypeError: 
     obj1[Symbol.iterator] is not a function
    }<br><br>let divList = document.querySelectorAll('div');<br><br>for(element of 
     divlist){  //可遍历所有的div节点<br>  //do something <br>}




  除了迭代时分配的一个是属性名、一个是属性值外,for in 和 for of 还有其他不同 (MDN文档: https://developer.mozilla.org...

  for...in循环会遍历一个object所有的可枚举属性。

  for...of会遍历具有iterator接口的数据结构

  for...in 遍历(当前对象及其原型上的)每一个属性名称,而 for...of遍历(当前对象上的)每一个属性值

    Object.prototype.objCustom = function () {};
    Array.prototype.arrCustom = function () {};
     
    let iterable = [3, 5, 7];
    iterable.foo = "hello";
     
    for (let i in iterable) {
      console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
    }
     
    for (let i of iterable) {
      console.log(i); // logs 3, 5, 7
    } 




创建第一个 Vue 应用

    <body>
    <div id="app">
      {{ message }}
    </div>
    <!-- JavaScript 代码需要放在尾部(指定的HTML元素之后) -->
    <script>
    new Vue({
        el:'#app',
        data: {
            message:'Hello World!'
        }
    });
    </script>

笔记

<div id="app">
  <p>{{* message}}</p>
  <p>{{ message }}</p>
  <!-- 字符串连接 -->
  <p>{{ message + '官网地址:www.runoob.com' }}</p>
  <!-- 字符串反转 -->
  <p>{{ message.split('').reverse().join('') }}</p>
  <input v-model="message">
</div>


列表输出
v-for

div id="app">
  <ul>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ul>
</div>
<script>
new Vue({
  el: '#app',
  data: {
    todos: [
      { text: '菜鸟教程' },
      { text: 'www.runoob.com' },
      { text: 'www.w3cschool.cc' }
    ]
  }
})
</script>

多维数组实例

<div id="app">
  <ul id="example-2">
  <li v-for="item in items">
    {{ parentMessage }} - {{ $index }} - {{ item.message }}
  </li>
</ul>
</div>
<script>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: '菜鸟教程官网',
    items: [
      { message: 'www.runoob.com' },
      { message: 'www.runoob.com' }
    ]
  }
})
</script>


条件判断
在字符串模板中,如 Handlebars,我们得像这样写一个条件块:

<!-- Handlebars 模板 -->
{{#if ok}}
  <h1>Yes</h1>
{{/if}}

在 Vue.js,我们使用 v-if 指令实现同样的功能:

<h1 v-if="ok">Yes</h1>

也可以用 v-else 添加一个 "else" 块:

<div id="app">
    <div v-if="Math.random() > 0.5">
      随机数大于 0.5
    </div>
    <div v-else>
      随机数不大于 0.5
    </div>
</div>
<script>
new Vue({
  el: '#app'
})
</script>

输出结果:随机数不大于 0.5

因为 v-if 是一个指令,需要将它添加到一个元素上。但是如果我们想切换多个元素呢?此时我们可以把一个 <template> 元素当做包装元素,并在上面使用 v-if,最终的渲染结果不会包含它。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

v-show
v-show作用与v-if类似,不同的是v-show的元素会始终渲染并保持在 DOM 中,且v-show不支持<template>标签。

<h1 v-show="ok">Hello!</h1>


过滤器
与Linux中的管道类似,vue.js也使用的是|:

{{message | uppercase}}

这样就能输出message的大写了,过滤器也能串联在一起使用:

{{message | reverse | uppercase}}

这里reverse并不是内建的过滤器,我们可以用Vue.filter自定义:

 Vue.filter('reverse', function (value) {
      return value.split('').reverse().join('')
 })
















查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 0 次点赞
  • 获得 2 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 2 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2019-05-22
个人主页被 418 人浏览