第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]

CentOS简单配置防御ddos攻击

[不指定 2020/09/01 08:43 | by 刘新修 ]

 DDOS这种攻击的目的就是在短时间内制造数量巨大的并发连接,从而使用服务器down机或消耗掉网络带宽和系统资源导致正常用户无法正常访问浏览网站。
DoS Deflate 是一个轻量级阻止拒绝服务攻击的bash shell脚本。我们可以通过安装他并且简单配置来防御DDOS攻击。
首先安装命令:

C#代码
  1. wget http://www.inetbase.com/scripts/ddos/install.sh  
  2. chmod 700 install.sh  
  3. ./install.sh  

然后会自动进行安装,完成后会有一段版权提示与说明,按q键退出即可。
卸载命令:

C#代码
  1. wget http://www.inetbase.com/scripts/ddos/uninstall.ddos  
  2. chmod 700 uninstall.ddos  
  3. ./uninstall.ddos  

安装完成之后就可以通过简单配置来进行DDOS防御,我是用的是CentOS7操作系统配置文件目录是/usr/local/ddos/ddos.conf
或者也可以通过命令更改 vi /usr/local/ddos/ddos.conf 编辑完成后:wq保存退出
下面介绍一下ddos.conf的基本配置#为注释部分不用理会关键配置项有:

C#代码
  1. PROGDIR="/usr/local/ddos" #文件存放目录  
  2. PROG="/usr/local/ddos/ddos.sh" #主要功能脚本  
  3. IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list" #可以设置IP白名单  
  4. CRON="/etc/cron.d/ddos.cron" #crond定时任务脚本  
  5. APF="/etc/apf/apf"          #这两项应该分别对应使用APF或者iptables配置目录不过笔者  
  6. IPT="/sbin/iptables"        #尝试打开文件里边是乱码,有哪位大牛知道是干嘛的欢迎留言  
  7.   
  8. FREQ=1 #间隔多久检查一次,默认1分钟  
  9.   
  10. NO_OF_CONNECTIONS=150 #最大连接数设置,超过这个数字的IP就会被屏蔽  
  11.   
  12. APF_BAN=0 #1:使用APF,0:使用iptables,推荐使用iptables  
  13.   
  14. KILL=1    #是否屏蔽IP 1:屏蔽,0:不屏蔽  
  15.   
  16. EMAIL_TO="root" #发送电子邮件报警的邮箱地址,换成自己使用的邮箱  
  17.   
  18. BAN_PERIOD=600  #禁用IP时间,可根据情况调整,默认单位:秒  

如果/usr/local/ddos/ddos.sh 统计不正确,可能是启用ipv6的缘故

vi /usr/local/ddos/ddos.sh  修改/usr/local/ddos/ddos.sh

117行的内容是这样的netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST

修改为以下代码即可!

C#代码
  1. netstat -ntu | awk '{print $5}' | cut -d: -f1 | sed -n '/[0-9]/p' | sort | uniq -c | sort -nr > $BAD_IP_LIST  

CentOS7默认为Firewall为了配合使用DoS Deflate建议停用Firewall启用iptables,不会用iptables的朋友,百度一下有很多

如何确认是否受到DDOS攻击?

登录到你的服务器以root用户执行下面的命令,使用它你可以检查你的服务器是在DDOS攻击与否:

C#代码
  1. netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n  

执行后,将会显示服务器上所有的每个IP多少个连接数。每个IP几个、十几个或几十个连接数都还算比较正常,如果像上面成百上千肯定就不正常了,该命令将显示已登录的是连接到服务器的最大数量的IP的列表

另外还有其他情况,使DDOS变得更为复杂,因为攻击者在使用更少的连接,更多数量IP的攻击服务器的情况下,你得到的连接数量较少,即使你的服务器被攻击了。有一点很重要,你应该检查当前你的服务器活跃的连接信息,执行以下命令:

C#代码
  1. netstat -n | grep :80 |wc –l  

上面的命令将显示所有打开你的服务器的活跃连接。

 

您也可以使用如下命令:

C#代码
  1. netstat -n | grep :80 | grep SYN |wc –l  

从第一个命令有效连接的结果会有所不同,但如果它显示连接超过500,那么将肯定有问题。

如果第二个命令的结果是100或以上,那么服务器可能被同步攻击。

一旦你获得了攻击你的服务器的IP列表,你可以很容易地阻止它。

遇到个很幼稚的问题,用json_encode把数组转换为json时,发现转化的值为null。怎么回事呢?查找手册:发现了下面的话:

该函数只能接受 UTF-8 编码的数据(译注:指字符/字符串类型的数据)
 
原来数组中有中文,需要转码哦,写个转换字符编码的函数吧:
PHP代码
  1. function encodeConvert($str,$fromCode,$toCode)  
  2. {  
  3. if (strtoupper($toCode) == strtoupper($fromCode)) return $str;  
  4. if (is_string($str)) {  
  5. if (function_exists('mb_convert_encoding')) {  
  6. return mb_convert_encoding($str, $toCode, $fromCode);  
  7. } else {  
  8. return iconv($fromCode, $toCode, $str);  
  9. }  
  10. } elseif (is_array($str)) {  
  11. foreach ($str as $k => $v) {  
  12. $str[$k] = encodeConvert($v, $fromCode, $toCode);  
  13. }  
  14. return $str;  
  15. }  
  16. return $str;  
  17. }  
对于数组,通过下面方式json_encode调用,一切ok。
PHP代码
  1. $json_api=json_encode(encodeConvert($json_api,'gb2312','utf-8'));  
  2. $json_api=json_decode(json_decode($json_api));  

今天数组json_encode转json的时候,输出一片空白,难道是数据量太大了?导致输出空白了?
后来检查下php程序似乎没有出错,就是json_encode的时候出现了问题,那到底是什么问题呢?

我们先来说下json_encode这个函数

C#代码
  1. (PHP 5 >= 5.2.0, PECL json >= 1.2.0, PHP 7)  
  2. json_encode — 对变量进行 JSON 编码  
  3.   
  4. 说明  
  5. -----------------------------------------------------------  
  6. string json_encode ( mixed $value [, int $options = 0 [, int $depth = 512 ]] )  
  7.   
  8. 参数  
  9. -----------------------------------------------------------  
  10. value  
  11. 待编码的 value ,除了resource 类型之外,可以为任何数据类型。  
  12. 所有字符串数据的编码必须是 UTF-8。  
  13.   
  14. options  
  15. 由以下常量组成的二进制掩码: JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR。  
  16.   
  17. depth  
  18. 设置最大深度。 必须大于0。  
  19.   
  20. 返回值  
  21. -----------------------------------------------------------  
  22. 成功则返回 JSON 编码的 string 或者在失败时返回 FALSE 。  

注意:上面对参数明确说明(所有字符串数据的编码必须是 UTF-8)

可能正是因为这一点导致我输出错误,但是我怎么知道,会是这个错误呢?因为我发现有一个这个函数json_last_error

我们看下这个函数

C#代码
  1. (PHP 5 >= 5.3.0, PHP 7)  
  2. json_last_error — 返回最后发生的错误  
  3.   
  4. 说明  
  5. -----------------------------------------------------------  
  6. int json_last_error ( void )  
  7. 如果有,返回 JSON 编码解码时最后发生的错误。  
  8.   
  9. 参数  
  10. -----------------------------------------------------------  
  11. 此函数没有参数。  
  12.   
  13. 返回值  
  14. -----------------------------------------------------------  
  15. 返回一个整型(integer),这个值会是以下的常量之一:  
C#代码
  1. 例如:  
  2. echo json_encode(array('error' => '0''message' => '没有错误'));  
  3. var_dump(json_last_error());  
  4. //这里也可以是json_decode  
  5.   
  6. //错误码对照  
  7. 0 JSON_ERROR_NONE  
  8. 1 JSON_ERROR_DEPTH  
  9. 2 JSON_ERROR_STATE_MISMATCH  
  10. 3 JSON_ERROR_CTRL_CHAR  
  11. 4 JSON_ERROR_SYNTAX  
  12. 5 JSON_ERROR_UTF8  
  13. 6 JSON_ERROR_RECURSION  
  14. 7 JSON_ERROR_INF_OR_NAN  
  15. 8 JSON_ERROR_UNSUPPORTED_TYPE  

我返回的是 int 5,对照返回错误码,自然而然就是(异常的 UTF-8 字符,也许是因为不正确的编码)这个错误了,知道错误后,然后检查你要返回的数据,再做下处理就OK了。

XSS已经成为非常流行的网站攻击方式,为了安全起见,尽量避免用户的输入。可是有些情况下不仅不避免,反而要求鼓励输入,比如写博客。博客园开放性很高,可以运行手写的JS。之前比较著名的例子就是,凡是看到某一篇文章的,都自动关注他。

如果避免跨站攻击的话,我们就得对用户的输入,进行转义。例如<script type='text/javascript'>alert('hello world')</script>。如果直接保存这个字符串的话,然后再输出的话,就会运行JS了。我们需要将这个字符串转义成"&lt;script type='text/javascript'&gt;alert('hello world')&lt;/script&gt;"。

转义,就是一个个字符的匹配,然后转换。看着不难,但是需要转义的字符也不少。另外当字符数量大的时候,效率成为一个问题。下面我写一个函数,让浏览器底层帮我们做到。

JavaScript代码
  1. function stringEncode(str){  
  2.        var div=document.createElement('div');  
  3.        if(div.innerText){  
  4.            div.innerText=str;  
  5.        }else{  
  6.            div.textContent=str;//Support firefox  
  7.        }  
  8.        return div.innerHTML;  
  9. }  

xss漏洞以及防御实现

[不指定 2020/05/22 18:44 | by 刘新修 ]

XSS三种类型

  • 存储型XSS:数据库中存在XSS攻击的数据,若数据未经过任何转义,返回给客户端。被浏览器渲染,就可能导致XSS攻击
  • 反射型XSS:将用户输入的存在XSS攻击的数据,发送给服务端,服务端并未对数据进行存储,也未经过任何转义,直接返回给客户端。被浏览器渲染。就可能导致XSS攻击
  • 纯粹发生在客户端的XSS攻击

XSS攻击演示

假设用户输入的参数为:

JavaScript代码
  1. <script>alert(xss)</script>  

如果后台没有对该数据做任何过滤直接显示到前端<div>标签中的话,源代码就变成了这样:

JavaScript代码
  1. <div><script>alert(xss)</script><div>  

那么在前端显示出来的是一个写着xss的弹窗,就发生了xss攻击

防御方案

我在项目中的主要的防御方案是对数据的过滤,对于数据中的危险字符进行相应的转义:

XML/HTML代码
  1. &----->&  
  2. <-----><  
  3. >----->>  
  4. "----->"  
  5. '----->'  
  6. /----->/  
手机型号尺寸(对角线)物理点宽长比例像素点倍数状态栏高度底部安全距离导航栏高度tabbar高度
iPhone 4/4S3.5英寸320x4800.667640x960@2x20-4449
iPhone 5/5S/5C4英寸320x5680.563640x1136@2x20-4449
iPhone SE4英寸320x5680.563640x1136@2x20-4449
iPhone 64.7英寸375x6670.562750x1334@2x20-4449
iPhone 6 Plus5.5英寸414x7360.5631242x2208@3x20-4449
iPhone 6S4.7英寸375x6670.562750x1334@2x20-4449
iPhone 6S Plus5.5英寸414x7360.5631242x2208@3x20-4449
iPhone 74.7英寸375x6670.562750x1334@2x20-4449
iPhone 7 Plus5.5英寸414x7360.5631242x2208@3x20-4449
iPhone 84.7英寸375x6670.562750x1334@2x20-4449
iPhone 8 Plus5.5英寸414x7360.5631242x2208@3x20-4449
iPhone X5.8英寸375x8120.4621125x2436@3x44344483
iPhone XS5.8英寸375x8120.4621125x2436@3x44344483
iPhone XS Max6.5英寸414x8960.4621242x2688@3x44344483
iPhone XR6.1英寸414x8960.462828x1792@2x44344483
iPhone 116.1英寸414x8960.462828x1792@2x44344483
iPhone 11 Pro5.8英寸375x8120.4621125x2436@3x44344483
iPhone 11 Pro Max6.5英寸414x8960.4621242x2688@3x44344483
iPhone SE 2020款4.7英寸375x6670.562750x1334@2x20-4449

 

 

Mac 键盘符号说明

  • == Command
  • == Shift
  • == Caps Lock
  • == Option
  • == Control
  • == Return/Enter
  • == Delete
  • == 向前删除键(Fn+Delete)
  • == 上箭头
  • == 下箭头
  • == 左箭头
  • == 右箭头
  • == Page Up(Fn+↑)
  • == Page Down(Fn+↓)
  • Home == Fn + ←
  • End == Fn + →
  • == 右制表符(Tab键)
  • == 左制表符(Shift+Tab)
  • == Escape (Esc)
  • == 电源开关键
  • 俗话说得好,工欲善其事必先利其器,要想工作效率高,码代码的工具用的好是必须的,这里主要说一下 Mac 上 VScode 的快捷键,帮助大家快速搭建良好的开发工具。

    必备插件

常用

Mac 快捷键介绍
⇧⌘P, F1显示命令面板
⌘P快速打开
⇧⌘N新建 窗口/实例
⌘W关闭 窗口/实例

基本编辑

Mac 快捷键介绍
⌘X剪切
⌘C复制
⌥↓ / ⌥↑移动当前行向 下/上
⇧⌥↓ / ⇧⌥↑复制当前行向 下/上
⇧⌘K删除当前行
⌘Enter / ⇧⌘Enter在下/上 插入一行
⇧⌘\跳转到匹配的括号
⌘] / ⌘[向左/向右 缩进当前行
Home / End跳到当前行的头部,尾部
⌘↑ / ⌘↓跳到当前行的开始,结束
⌃PgUp滚动到
⌃PgDown滚动到行头/行尾
⌘PgUp /⌘PgDown滚动到页头/页尾
⇧⌘[ / ⇧⌘]折叠/展开区域
⌘K ⌘[ / ⌘K ⌘]折叠/展开所有子区域
⌘K ⌘0 / ⌘K ⌘J折叠/展开所有区域
⌘K ⌘C添加行注释
⌘K ⌘U删除行注释
⌘/切换行注释
⇧⌥A切换块注释
⌥Z切换文字换行

多光标和选择

Mac 快捷键介绍
Alt+Click插入光标
⌥⌘↑在上面插入光标
⌥⌘↓在下面插入光标
⌘U撤消上一个光标操作
⇧⌥I在所选每行的末尾插入光标
⌘I选择当前行
⇧⌘L选择当前选择的所有事件
⌘F2选择当前单词的所有出现
⌃⇧⌘→展开选择
⌃⇧⌘←收缩选择
Shift+Alt + drag mouse(拖动鼠标)列(框)选择
⇧⌥⌘↑向上列(框)选择
⇧⌥⌘↓向下列(框)选择
⇧⌥⌘←向左列(框)选择
⇧⌥⌘→向右列(框)选择
⇧⌥⌘PgUp列(框)选择 向上一页
⇧⌥⌘PgDown列(框)选择 向下一页

搜索和替换

Mac 快捷键介绍
⌘F查找
⌥⌘F替换
⌘G / ⇧⌘G查找下一个/上一个
⌥Enter选择查找匹配的所有匹配项
⌘D将选择添加到下一个查找匹配
⌘K ⌘D将最后一个选择移至下一个查找匹配项

丰富的语言编辑

Mac 快捷键介绍
⌃Space触发建议
⇧⌘Space触发参数提示
TabEmmet扩展缩写
⇧⌥F格式化文档
⌘K ⌘F格式选择
F12转到定义
⌥F12Peek定义
⌘K F12打开定义到一边
⌘.快速修复
⇧F12显示引用
F2重命名符号
⇧⌘. / ⇧⌘,替换为下一个/上一个值
⌘K ⌘X修剪尾随空格
⌘K M更改文件语言

导航

Mac 快捷键介绍
⌘T显示所有符号
⌃G转到行...
⌘P转到文件...
⇧⌘O转到符号...
⇧⌘M显示问题“面板”
F8 / ⇧F8转到下一个/上一个错误或警告
⌃⇧Tab浏览编辑器组历史记录
⌃- / ⌃⇧-后退/前进
⌃⇧M切换选项卡移动焦点

编辑器管理

Mac 快捷键介绍
⌘W关闭编辑窗口
⌘K F关闭文件
⌘\拆分编辑窗口
⌘1 / ⌘2 / ⌘3聚焦到第1,第2,第3编辑器组中
⌘K ⌘← / ⌘K ⌘→聚焦到上一个/下一个编辑器组
⌘K ⇧⌘← / ⌘K ⇧⌘→向左/向右移动编辑器
⌘K ← / ⌘K →移动活动编辑器组

文件管理

Mac 快捷键介绍
⌘N新建文件
⌘O打开文件
⌘S保存
⇧⌘S保存为...
⌥⌘S保存所有
⌘W关闭
⌘K ⌘W关闭所有
⇧⌘T重新打开已关闭的编辑器
⌘K输入保持打开
⌃Tab / ⌃⇧选项卡打开下一个/上一个
⌘K P复制活动文件的路径
⌘K R在资源管理器中显示活动文件
⌘K O在新窗口/实例中显示活动文件

显示

Mac 快捷键介绍
⌃⌘F切换全屏
⌥⌘1切换编辑器布局
⌘= / ⇧⌘-放大/缩小
⌘B切换侧栏可见性
⇧⌘E显示资源管理器/切换焦点
⇧⌘F显示搜索
⌃⇧G显示Git
⇧⌘D显示Debug
⇧⌘X显示扩展名
⇧⌘H在文件中替换
⇧⌘J切换搜索详细信息
⇧⌘C打开新命令提示符/终端
⇧⌘U显示输出面板
⇧⌘V切换Markdown预览
⌘K V打开Markdown预览到一边

调试

Mac 快捷键介绍
F9切换断点
F5开始/继续
F11 / ⇧F11跳进/出
F10跳过
⇧F5暂停
⌘K ⌘I显示悬停

集成终端

Mac 快捷键介绍
⌃`显示集成终端
⌃⇧`创建新终端
unassigned(末分配)复制选择
unassigned(末分配)粘贴到活动终端
⌘↑向上滑动
⌘↓下身滑动
PgUp向上滚动页面
PgDown向下滚动页面
⌘Home滚动到顶部
⌘End滚动到尾部

Vue props用法详解

[不指定 2019/09/10 14:56 | by 刘新修 ]

Vue props用法详解

组件接受的选项之一 props 是 Vue 中非常重要的一个选项。父子组件的关系可以总结为:

props down, events up

父组件通过 props 向下传递数据给子组件;子组件通过 events 给父组件发送消息。

父子级组件

比如我们需要创建两个组件 parent 和 child。需要保证每个组件可以在相对隔离的环境中书写,这样也能提高组件的可维护性。

这里我们先定义父子两个组件和一个 Vue 对象:

XML/HTML代码
  1. <div id="example">  
  2.   <parent></parent>  
  3. </div>  
JavaScript代码
  1. var childNode = {  
  2.   template: `  
  3.         <div>childNode</div>  
  4.         `  
  5. };  
  6. var parentNode = {  
  7.   template: `  
  8.         <div>  
  9.           <child></child>  
  10.           <child></child>  
  11.         </div>  
  12.         `,  
  13.   components: {  
  14.     child: childNode  
  15.   }  
  16. };  
  17. new Vue({  
  18.   el: "#example",  
  19.   components: {  
  20.     parent: parentNode  
  21.   }  
  22. });  

这里的 childNode 定义的 template 是一个 div,并且内容是"childNode"字符串。
而在 parentNode 的 template 中定义了 div 的 class 名叫 parent 并且包含了两个 child 组件。

静态 props

组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板中直接饮用父组件的数据。要让子组件使用父组件的数据,需要通过子组件的 props 选项。

父组件向子组件传递数据分为两种方式:动态和静态,这里先介绍静态方式。

子组件要显示的用 props 声明它期望获得的数据

修改上例中的代码,给 childNode 添加一个 props 选项和需要的forChildMsg数据;
然后在父组件中的占位符添加特性的方式来传递数据。

JavaScript代码
  1. var childNode = {  
  2.   template: `  
  3.         <div>  
  4.           {{forChildMsg}}  
  5.         </div>  
  6.         `,  
  7.   props: ["for-child-msg"]  
  8. };  
  9. var parentNode = {  
  10.   template: `  
  11.         <div>  
  12.           <p>parentNode</p>  
  13.           <child for-child-msg="aaa"></child>  
  14.           <child for-child-msg="bbb"></child>  
  15.         </div>  
  16.         `,  
  17.   components: {  
  18.     child: childNode  
  19.   }  
  20. };  

命名规范
对于 props 声明的属性,在父组件的 template 模板中,属性名需要使用中划线写法;

子组件 props 属性声明时,使用小驼峰或者中划线写法都可以;而子组件的模板使用从父组件传来的变量时,需要使用对应的小驼峰写法。别担心,Vue 能够正确识别出小驼峰和下划线命名法混用的变量,如这里的forChildMsgfor-child-msg是同一值。

动态 props

在模板中,要动态地绑定父组件的数据到子组件模板的 props,和绑定 Html 标签特性一样,使用v-bind绑定;

基于上述静态 props 的代码,这次只需要改动父组件:

JavaScript代码
  1. var parentNode = {  
  2.   template: `  
  3.         <div>  
  4.           <p>parentNode</p>  
  5.           <child :for-child-msg="childMsg1"></child>  
  6.           <child :for-child-msg="childMsg2"></child>  
  7.         </div>  
  8.         `,  
  9.   components: {  
  10.     child: childNode  
  11.   },  
  12.   data: function() {  
  13.     return {  
  14.       childMsg1: "Dynamic props msg for child-1",  
  15.       childMsg2: "Dynamic props msg for child-2"  
  16.     };  
  17.   }  
  18. };  

在父组件的 data 的 return 数据中的 childMsg1 和 childMsg2 会被传入子组件中,

props 验证

验证传入的 props 参数的数据规格,如果不符合数据规格,Vue 会发出警告。

能判断的所有种类(也就是 type 值)有:
String, Number, Boolean, Function, Object, Array, Symbol

JavaScript代码
  1. Vue.component("example", {  
  2.   props: {  
  3.     // 基础类型检测, null意味着任何类型都行  
  4.     propA: Number,  
  5.     // 多种类型  
  6.     propB: [String, Number],  
  7.     // 必传且是String  
  8.     propC: {  
  9.       type: String,  
  10.       required: true  
  11.     },  
  12.     // 数字有默认值  
  13.     propD: {  
  14.       type: Number,  
  15.       default: 101  
  16.     },  
  17.     // 数组、默认值是一个工厂函数返回对象  
  18.     propE: {  
  19.       type: Object,  
  20.       default: function() {  
  21.         console.log("propE default invoked.");  
  22.         return { message: "I am from propE." };  
  23.       }  
  24.     },  
  25.     // 自定义验证函数  
  26.     propF: {  
  27.       isValid: function(value) {  
  28.         return value > 100;  
  29.       }  
  30.     }  
  31.   }  
  32. });  
  33. let childNode = {  
  34.   template: "<div>{{forChildMsg}}</div>",  
  35.   props: {  
  36.     "for-child-msg": Number  
  37.   }  
  38. };  
  39. let parentNode = {  
  40.   template: `  
  41.           <div class="parent">  
  42.             <child :for-child-msg="msg"></child>  
  43.           </div>  
  44.         `,  
  45.   components: {  
  46.     child: childNode  
  47.   },  
  48.   data() {  
  49.     return {  
  50.       // 当这里是字符串 "123456"时会报错  
  51.       msg: 123456  
  52.     };  
  53.   }  
  54. };  

还可以在 props 定义的数据中加入自定义验证函数,当函数返回 false 时,输出警告。

比如我们把上述例子中的 childNode 的for-child-msg修改成一个对象,并包含一个名叫validator的函数,该命名是规定叫validator的,自定义函数名不会生效。

JavaScript代码
  1. let childNode = {  
  2.   template: "<div>{{forChildMsg}}</div>",  
  3.   props: {  
  4.     "for-child-msg": {  
  5.       validator: function(value) {  
  6.         return value > 100;  
  7.       }  
  8.     }  
  9.   }  
  10. };  

在这里我们给for-child-msg变量设置了validator函数,并且要求传入的值必须大于 100,否则报出警告。

单向数据流

props 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件五一修改父组件的状态。

所以不应该在子组件中修改 props 中的值,Vue 会报出警告。

JavaScript代码
  1. let childNode = {  
  2.   template: `  
  3.           <div class="child">  
  4.             <div>  
  5.               <span>子组件数据</span>  
  6.               <input v-model="forChildMsg"/>  
  7.             </div>  
  8.             <p>{{forChildMsg}}</p>  
  9.           </div>`,  
  10.   props: {  
  11.     "for-child-msg": String  
  12.   }  
  13. };  
  14. let parentNode = {  
  15.   template: `  
  16.           <div class="parent">  
  17.             <div>  
  18.               <span>父组件数据</span>  
  19.               <input v-model="msg"/>  
  20.             </div>  
  21.             <p>{{msg}}</p>  
  22.             <child :for-child-msg="msg"></child>  
  23.           </div>  
  24.         `,  
  25.   components: {  
  26.     child: childNode  
  27.   },  
  28.   data() {  
  29.     return {  
  30.       msg: "default string."  
  31.     };  
  32.   }  
  33. };  

这里我们给父组件和子组件都有一个输入框,并且显示出父组件数据和子组件的数据。当我们在父组件的输入框输入新数据时,同步的子组件数据也被修改了;这就是 props 的向子组件传递数据。而当我们修改子组件的输入框时,浏览器的控制台则报出错误警告

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "forChildMsg"

修改 props 数据

通常有两种原因:

  1. prop 作为初始值传入后,子组件想把它当做局部数据来用
  2. prop 作为初始值传入后,由子组件处理成其他数据输出

应对办法是

  1. 定义一个局部变量,并用 prop 的值初始化它

但是由于定义的 ownChildMsg 只能接受 forChildMsg 的初始值,当父组件要传递的值变化发生时,ownChildMsg 无法收到更新。

JavaScript代码
  1. let childNode = {  
  2.   template: `  
  3.           <div class="child">  
  4.             <div>  
  5.               <span>子组件数据</span>  
  6.               <input v-model="forChildMsg"/>  
  7.             </div>  
  8.             <p>{{forChildMsg}}</p>  
  9.             <p>ownChildMsg : {{ownChildMsg}}</p>  
  10.           </div>`,  
  11.   props: {  
  12.     "for-child-msg": String  
  13.   },  
  14.   data() {  
  15.     return { ownChildMsg: this.forChildMsg };  
  16.   }  
  17. };  

这里我们加了一个<p>用于查看 ownChildMsg 数据是否变化,结果发现只有默认值传递给了 ownChildMsg,父组件改变只会变化到 forChildMsg,不会修改 ownChildMsg。

  1. 定义一个计算属性,处理 prop 的值并返回

由于是计算属性,所以只能显示值,不能设置值。我们这里设置的是一旦从父组件修改了 forChildMsg 数据,我们就把 forChildMsg 加上一个字符串"---ownChildMsg",然后显示在屏幕上。这时是可以每当父组件修改了新数据,都会更新 ownChildMsg 数据的。


JavaScript代码
  1. let childNode = {  
  2.   template: `  
  3.           <div class="child">  
  4.             <div>  
  5.               <span>子组件数据</span>  
  6.               <input v-model="forChildMsg"/>  
  7.             </div>  
  8.             <p>{{forChildMsg}}</p>  
  9.             <p>ownChildMsg : {{ownChildMsg}}</p>  
  10.           </div>`,  
  11.   props: {  
  12.     "for-child-msg": String  
  13.   },  
  14.   computed: {  
  15.     ownChildMsg() {  
  16.       return this.forChildMsg + "---ownChildMsg";  
  17.     }  
  18.   }  
  19. };  
  1. 更加妥帖的方式是使用变量存储 prop 的初始值,并用 watch 来观察 prop 值得变化。发生变化时,更新变量的值。
JavaScript代码
  1. let childNode = {  
  2.   template: `  
  3.           <div class="child">  
  4.             <div>  
  5.               <span>子组件数据</span>  
  6.               <input v-model="forChildMsg"/>  
  7.             </div>  
  8.             <p>{{forChildMsg}}</p>  
  9.             <p>ownChildMsg : {{ownChildMsg}}</p>  
  10.           </div>`,  
  11.   props: {  
  12.     "for-child-msg": String  
  13.   },  
  14.   data() {  
  15.     return {  
  16.       ownChildMsg: this.forChildMsg  
  17.     };  
  18.   },  
  19.   watch: {  
  20.     forChildMsg() {  
  21.       this.ownChildMsg = this.forChildMsg;  
  22.     }  
  23.   }  
  24. };  

 

 

1, npm install是帮助安装 vue,或React到本地,npm install也可以安装vue,React的开发工具。当然你完全可以像jQuery一样自己找网站下载下来,在页面中引入。
2,没有npm可以使用vue,vue只是一个前端框架。
3,4,node是js的服务执行环境,前端常常借助 node帮助前端实现工程化。很多工具是基于node的,比如说你说的webpack,grunt。
5,webpack,grunt是前端工程化的工具,可以帮助前端完成混淆压缩,校验等工作。
6,7,实战中没用过,请参考官方文档http://cn.vuejs.org/v2/guide/...
8,可以单纯的利用 php+vue或者php+react开发。
9,最后一个问题太大,可以写本书。而且老实讲,一切都需要实战中才能有更深的体会。
最后总结一下:
前端圈所谓得“乱”,一个是近些年前端框架层出不穷,工程化,解决方案越来越多,已经脱离了一般人认为的那个“好单纯好不做作”的前端。就像后端开发有很多工具协作开发一样,前端也需要越来越多的工作完成前端面临巨大的工作量。 前端的行业发展已经不是那种后端在php,jsp中写一些html,前端来写一些css来完成工作的阶段。老实讲,我现在80%的时间在写js。前端已经不是后端开发的最后一步甚至“附属品”,而成为真正意义的“客户端”。复杂度也就慢慢和app等客户端越来越接近。
总的来说,你还是可以按照原先的开发方式来开发自己的应用,当然考虑引进工具一些先进的理念方法来协助开发。node,webpack,vue这些概念不应该成为自己开发中的阻碍,而是在自己在面临一些问题时的利剑。这些概念的学习需要一天一天的来,毕竟一口吃不成个胖子 :)

 

什么是npm?
从事网站制作的小前端们都知道cdn的概念,也就是在网站制作中如果我们需要jquery或者bootstrap等文件支持的话,就可以通过cdn引入的方式来实现调用。由于node的使用日益广泛,也带动了其组件npm的使用,而npm就是这些jquery以及bootstrap这些文件包的组合管理器。现在只要使用了node环境进行web网站开发,你就可以直接用npm进行调用以前所有的cdn文件了。

什么是webpack?
webpack简单来说就是前端代码资源的包管理工具,他自动整理你的项目结构,结合javascript的模块化组件,机型解析并交给浏览器渲染使用,大大提高前端的开发效率。

什么是vue-cli?它与vue脚手架有什么关系?
其实vue-cli就是vue的脚手架,vue脚手架的作用是用来自动一键生成vue+webpack的项目模版,包括依赖库,免去你手动安装各种插件,寻找各种cdn并一个个引入的麻烦。

什么是node.js?它与vue具体有什么关系?
提到vue就不得不说node了,vue作为一个前端框架技术,主要负责了数据渲染,界面展示效果,由于其易用性及便捷的维护应用日益广泛。而node作为一个服务器端语言,它是以javascript语言为基础的服务端程序语言,在实际的项目开发中,前端人员只要实现了环境的搭建,其实就可以仅仅从后台拿api接口进行数据调用,从而全部完成整个前端项目的展示。

前端由于近两年web前端技术发展革新速度飞快,一旦错过了,可能重新学的速度是非常慢的,只要尽早入手才能获得最好的学习效果。全栈网络专业从事郑州网站制作,我们也有专业的网站制作团队,愿意为每一个前端人员提供最新的前端知识分享。

vue await fetch 使用

[不指定 2019/08/28 13:55 | by 刘新修 ]

 await/async 是 ES7 最重要特性之一,它是目前为止 JS 最佳的异步解决方案了。

 
先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行。
写一个async 函数
JavaScript代码
  1. async function timeout() {  
  2.   return 'hello world';  
  3. }  
语法很简单,就是在函数前面加上async 关键字,来表示它是异步的,那怎么调用呢?async 函数也是函数,平时我们怎么使用函数就怎么使用它,直接加括号调用就可以了,为了表示它没有阻塞它后面代码的执行,我们在async 函数调用之后加一句console.log;
 
JavaScript代码
  1. async function timeout() {  
  2.     return 'hello world'  
  3. }  
  4. timeout();  
  5. console.log('虽然在后面,但是我先执行');  

fetch 基本使用方法点击 这里

下边一个小例子说个基本的请求吧

JavaScript代码
  1. <template>  
  2.   <div id="app">  
  3.     <button @click="fetchData()" >fetch 获取数据</button>  
  4.     <p>{{text}}</p>  
  5.   </div>  
  6. </template>  
  7.   
  8. <script>  
  9. export default {  
  10.   name: 'app',  
  11.   data () {  
  12.     return {  
  13.       text:''  
  14.     }  
  15.   },  
  16.   methods:{  
  17.     fetchData(){  
  18.       // fetch是相对较新的技术,当然就会存在浏览器兼容性的问题,当前各个浏览器低版本的情况下都是不被支持的,因此为了在所有主流浏览器中使用fetch 需要考虑 fetch 的 polyfill 了  
  19.   
  20.       async function ff(){  
  21.         let data = await fetch('../static/data.json').then(res => res.json());  
  22.         console.log(data,'data');  
  23.         return data;  
  24.       }  
  25.       ff().then(res => {  
  26.         console.log(res,'res');  
  27.         this.text = 'name:'+res.name+',age:'+res.age+'sex:'+res.sex;  
  28.       }).catch(reason => console.log(reason.message));  
  29.   
  30.     }  
  31.   }  
  32. }  
  33. </script>  
  34.   
  35. <style lang="scss">  
  36.   
  37. </style>  

 

第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]