拦截器
http://www.axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
// 开始做什么********************
let res = response.data;
let path = location.hash;
//根据接口文档 0是登录 10是未登录
if(res.status == 0){
return res.data;
}
else if(res.status == 10){
if(path!='#/index'){
window.location.href = '/#/login';
}
return Promise.reject(res);
}else{
Message.warning(res.msg);
return Promise.reject(res);
}
}, function (error) {
// 对响应错误做点什么
let res = error.response;
Message.warning(res.data.message);
return Promise.reject(error);
});
npm 安装时 --save --dev 和 --save区别
–save: 将保存配置信息到package.json, 默认为dependencies节点中
–dev: 将保存配置信息devDependencies节点中
dependencies: 运行时的依赖, 发布后, 即生成下需要用的模块
devDependencies: 开发时的依赖, 里面的模块是开发时用的, 发布时用不到它
//新建文件 plugins.js文件
//定义插件
对象.install = function (Vue,options) {
//添加全局过滤器
Vue.filter( ... )
//添加全局指令
Vue.directive( ... )
//配置全局混入( 合 )
Vue.mixin( ... )
//添加实例方法
Vue.prototype.$myMethods = function () { ... }
Vue.prototype.$myProperty = function () { ... }
}
//使用插件
//先引入
import plugins from './plugins' Vue.use(plugins)
ref属性
-
被用来给元素或子组件注册引用信息( id的替代者 )
-
应用在html标签上获取的是真实DOM元素, 应用在组件标签上是组件实例对象( vc )
-
使用方式:
//打标书 <h1 ref="xxx>....</h1> <school ref="xxx"></school> //获取 this.$refs.xxx
Vue和Vuecomponent
一个重要的内置关系:
VueComponent.prototype. _ proto _ === Vue.prototype
为什么要有这个关系: 让组件实例对象(vc)可以访问到Vue原型上的属性, 方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JNN209tF-1634980622721)(小知识点.assets\image-20210922110439027.png)]
匿名函数和回调函数
-
回调函数
咱们自己定义的函数, 却不由咱们自己亲自调用 而是交给别的函数去调用 比如: setTimeout(function(){},3000); 里的function虽然是咱们定义的, 但是调用是setTimeout等三秒后调用 比如: arr.every(function(elem,i,arr){}); 里的function虽然是咱们定义的, 但是调用几次咱们不知道, 每次传入是否实参也不知道 , 完全由every()在内部自己调用
-
匿名函数:如果只要一次使用, 匿名函数也有主动自调的情况, 就不属于回调
-
总结: 之所以大多数回调函数都是匿名函数, 只是因为多数回调函数只在一个位置使用一次
弹性布局
justify-content: space-evenly; 平均分布
align-self 属性定义flex子项单独在Y轴方向上的对齐方式
margin-right: auto
一些网站
https://code.fun => 设计稿一键导出vue/微信小程序代码
回调函数如何学习
- 通过打桩(输出调用次数和变量的值), 让回调函数的执行过程现出原型
- 通过打桩输出的结果, 推断出回调函数执行的过程
强行关闭端口
输入命令:netstat -ano;查看所有的进程及其对应的id;
去空格
str.trim();
去掉字符串两端的多余空格, 中间的那些空格不会被去掉
字符串都是不可变类型
- 什么是不可变类型:一旦创建, 值不可改变, 只能整体替换
所以: 所以字符串类型提供的函数, 都无权修改原字符串, 只能返回加工后的新字 符串, 再用变量接住
- 什么是可变类型:创建后, 值还可随时修改的数据类型
所以: 几乎所以数组类型提供的函数, 都可以直接修改原数组, 无需用变量接住
input标签
- 在元素中使用, 用来声明允许用户输入数据的input控件
- 使用
- checked 预先选定的input元素 => 只针对type=“checkbox” 或者 type=“radio”
- disabled 禁用
- maxlength 规定允许的最大字符
- name 元素的名称 提交时可以看到
- value 指定元素的值
git的使用
-
官网: https://gitee.com/
-
git status
-
git add .
-
git commit -m “提交内容说明”
-
git branch 查看所有分支
-
git branch 分支名称 => 创建新的分支
-
git checkout 分支名称 => 切换分支
-
git merge 分支名称
-
将本地仓库推送至远程仓库
-
git push 仓库的地址 分支名称
-
将一个远程仓库克隆到本地
-
git clone 仓库地址
-
将远程仓库拉取到本地(已有仓库的基础之上)
-
git pull 仓库地址 分支名称
栅格布局
声明容器
//块级元素
display: grid;
//行级元素
display:inline-grid;
划分行列
//属性
grid-template-columns //划分列数
grid-template-rows //划分函数
//列子1
grid-template-columns: 100px 100px 100px;//划分三列, 每列宽100px
grid-template-rows: 100px 100px; //划分两行, 每行高100px
//例子2
grid-template-columns: 25% 25% 25% 25%;
grid-template-rows:50% 50%;
重复设置
grid-template-rows:repeat(2,50%);两行 每行50%
grid-template-columns:repeat(2,50%);两列 每列50%
grid-template-columnsrepeat(2,100px 50px);第一列宽100px 第二列宽50px, 重复两次
grid-template-rows: repeat(2,1fr);
grid-template-columns: repeat(2,1fr 2fr);
自动填充
grid-template-rows:repeat(auto-fill,100px);
grid-template-rows:repeat(auto-fill,100px);
grid-template-columns: 20vw auto 30vw;
比例划分
fr单位设置元素在空间所占的比例, 下面按1份-2份 分成两组共四列
grid-template-rows:1fr 2fr;
grid-template-columns:100px 1fr 2fr;
简写
grid-template: rows / columns /areas
grid-template: repeat(2, 1fr) / repeat(3, 1fr);
mimax
grid-template-rows: 100px mimax(100px,1fr);
//第一行 高100px 第二行最小高100px 最大剩余空间全占
间距
row-gap: 10px;
columns-gap:20px;
gap: 20px 10px; //行 列
栅格命名
main>div:first-child{
grid-row-start: 1;
grid-column-start: 3;
grid-row-end: 4;
grid-column-end: 4;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zqEM0sJK-1634980622723)(小知识点.assets\image-20210910201822847.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UKfHReXs-1634980622724)(小知识点.assets\image-20210910201925675.png)]
根据偏移量:span
grid-row-end:span 1; //向下包含一行
grid-column-end: span 1;//向右包含1列
//简写
grid-row: 1 / span 3; //第一行开始 偏移3行
grid-column: 1 / span 1; //第一列开始 偏移1列
区域定位grid-area
grid-area:1/2/4/3; //行start / 列start / 行end / 列end;
命名定位
grid-template-columns: 60px 1fr;
grid-template-rows: 60px 1fr 60px;
grid-template-areas: "header header" "nav main" "footer footer"; //定义栅格区域
header{
grid-area: header;
}
footer{
grid-area:footer;
display: grid;
grid-template-columns: repeat(4,1fr)
}
区域占位
grid-template-columns: 60px 1fr;
grid-template-rows: 60px 1fr 60px;
grid-template-areas: "nav ." "nav ." "footer footer";
nav{
grid-area: nav;
}
对齐管理
justify-content
justify-items
上面两个的区别
align-content
align-items
------------
align-self //元素独立控制
justify-self
//简写
place-content: <align-content> <justity-content>
place-items:<align-items> <justify-items>
place-self:<align-self><justify-self>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O9PmF54R-1634980622725)(小知识点.assets\image-20210911120059621.png)]
r o u t e 和 route和 route和router的区别
$route
用来获取路由信息
route是路由器信息对象, 里面主要包含路由的一些基本信息
$route.name
当前路由的名称, 如果有的话
$route.meta
$route.path
字符串, 对应当前路由的路径, 总是解析为觉得路径, 如 “/foo/bar”
$route.hash
当前路由的hash值( 带 # ), 如果没有hash值, 则为空字符串
$route.query
类型: object
一个key/value对象, 表示URL查询参数,对于路径 /foo?user=1, 则有$route.query.user == 1, 如果没有查询参数, 则是空对象
$route.params
类型: object
一个key/value对象. 包含了动态片段和全匹配片段, 如果没有路由参数, 就是一个空对象
$route.fullPath
完成解析后的URL, 包含查询参数和hash的完整路径
$route.matched
一个数组, 包含当前路由的所有嵌套路径片段的路由记录. 路由记录就是 routes 配置数组中的对象副本( 还有在 children 数组 )
$route.redirectedFrom
如果存在重定向, 即为重定向来源的路由的名字
$router
用来操作路由
router是VueRouter的实例,包含了一些路由的跳转方法, 钩子函数等
$router.path
重定向
重定向就是通过各种方法将各种网络请求重新定个方向转到其他位置
如: 网页重定向 , 域名重定向, 路由选择的变化也是对数据报文由路径的一种重定向
路由重定向
如何路由重定向
const router = new VueRouter({
routes: [
{path: '/a', redirect: '/b'}
]
});
//重定向的目标可以是一个命名的路由
const router = new VueRouter({}
routes :[
{path: '/a', redirect: {name: 'foo'}}
]
);
const router = new VueRouter({
routes:[
{path: '/a', redirect: to => {
//方法介绍 目标路由 作为参数
//return 重定向 字符串路径 / 路径对象
}}
]
});
vue_apis
第一步: 定义基本路径
在config.js模块里定义一个基本路径
var baseURL = "http://localhost:5050"
export{ // 一个组件js对象, 想要抛出, 并让别人能够引用, 必须使用
baseURL
}
第二步: 新建文件
定义一个index.js在src/assets文件夹内新建文件夹apis,专门发送首页的请求
//首先引入axios
import axios from "axios"
//同时引入baseURL 不起名 直接用对象解构的方式 因为 '../config.js抛出的是对象'
import {baseURL} from "../config.js"
//定义函数getIndex
function getIndex(){
//返回promise
return new Promise(
function(resolve,reject){
//发送ajax请求
axios.get(baseURL+"/index")
.then(result=>{
resolve(result.data)
})
}
)
}
export{
getIndex
}
定义一个details.js
//首先引入axios
import axios from "axios"
//同时引入baseURL 不起名 直接用对象解构的方式 因为 '../config.js抛出的是对象'
import {baseURL} from "../config.js"
//定义函数getDetails
function getDetails(lid){
return new Promise(
function(resolve,reject){
axios.get(
baseURL+"/details",
{
params:{lid}
}
).then(result+>{
resolve(result.data)
})
}
)
}
export {
getDetails
}
第三步: 在界面使用
//在Index.vue中
//引入index.js 使用对象解构抛出里面的成员
import {getIndex} from "../assets/js/apis/index.js"
//使用
export default {
data(){},
methods{},
...
mounted(){
console.log("创建Index组件后,请求一次数据");
getIndex().then(
result=>{
var arr = result;
[this.p1,this.p2,this.p3] = arr;
this.others = arr.slice(-3);
}
);
}
}
//在Details.vue中
//引入
import {getDetails} from "../assets/js/apis/Details.js"
export default {
props:["lid"],
data(){},
....
methods(){
myload(){
getDetails(this.lid).then(result=>{
this.product = result.product;
this.specs = result.specs;
})
}
},
create(){
myload()
},
mounted(){
myload()
}
}
vue中使用less
下载less
npm i less-loader
然后报错, 兼容性问题 webpack的版本是4.46.0, 直接安装的less-loader是5版本最新版
查看webpack的所有版本号
npm view webpack versions
查看less-loader的所有版本号
npm view less-loader versions
安装7版本
npm i less-loader@6 /会自动下载6的最新版本
正则表达式(Regular Expression)
正则表达式
https://regexper.com/
-----------什么是:
专门描述字符串中字符出现规则的表达式
比如形容手机号:
第一位必须是1
第二位可以在3,4,5,6,7,8中选其一
后九位, 每一位都必须是一个数字
------------可用于:
- 验证字符串格式
- 查找敏感词
-------------如何:
字符集
只要规则中某一位字符上有多种备选字时, 就用字符集
只能匹配一位
如何1: [备选字列表]
//定义一个规则同时匹配 "我艹" "我草" "我槽" 三种敏感词
我[草艹槽]
//修改规则, 使其进一步匹配"卧槽"
[我卧][槽艹草]
如何2: 简写字符集
-----------如果[ ]中部分备选字符连续 , 可用 - 省略中间字符
备选字符连续 : ASCII
- 要匹配一位小写字母: [ a-z ] 共26个
- 要匹配一位大写字母: [ A-Z ] 共26个
- 要匹配一位字母: [ A-Za-z ] 共52个
- 要匹配一位字母或数字: [ 0-9A-Za-z ] 共62个
- 要匹配一位汉字: [ \u4e00-\u9fa5 ]
//手机号规则, 字符串连续, 简写
1[3-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
//车牌号规则 第一位汉字 第二位大写字母 第三位· 后五位: 一位大写字母或数字
[\u4e00-\u9fa5][A-Z]·[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]
如何3: 预定义字符集
------------正则表达式语法为四种最常用的字符集定义了最简化写法, 称为预定义字符集
-
-要匹配一位数字: \d => [ 0-9 ] digit(数字, 数位)
-
-要匹配一位字母, 数字或 _ : \w => [ 0-9A-Za-z_ ] 注意: 有下划线
能用简写用简写, 不能就不用
-
-要匹配一位空字符: \s 可匹配 空格, 制表符Tab等空白
-
要匹配所有文字( 任意字符 )通配符 : .
//手机号
1[3-9]\d\d\d\d\d\d\d\d\d
数量词
专门规定一个字符集出现次数的规则
------------数量词紧跟在其修饰的字符集之后, 默认修饰相邻的前一个字符集
如何1: 有明确数量边界
-
字符集{ n } 表示字符集必须重复n次, 不能多也不能少
-
字符集{ n,m } 表示字符集至少重复n次, 最多重复m次
{ n, } 至少n次, 多了不限制
//手机号
1[3-9]\d{9}
//车牌号
[\u4e00-\u9fa5][A-Z]·[0-9A-Z]{5}
//匹配手机短信中的验证码: 连续的4 ~ 6 位
\d{4,6}
如何2: 没有明确数量边界
- ***** 可有可无 , 多了不限制 大于等于0
- ? 可有可无, 最多一次 0 或 1
- **+ ** 至少一次, 多了不限 大于等于1
//匹配字符串中的一组连续空字符
\s+
选择和分租
---------问题: 字符集只认识单个字, 不认识一组拼音 wocao
选择
--------是指在多个子规则中选其一匹配
---------如何: 子规则1 | 子规则2 => 满足规则1 或 满足规则2
--------- " | " 选择符只分左右, 不考虑单个字符 => 草 | cao
//问题: 如果规则写成 "我草 | cao" 呢?
//希望是: 我草 或 我cao
//实际却是: 我草 | cao 满足 我草 或者 cao
分组
-------是指将多个子规则视为一组, 再和分组外的规则匹配
-------如何: 其他规则( 多个子规则 ) => 我( 草 | cao )
//❀❀❀❀❀❀同时验证同音字或拼音
我([草艹槽]|cao)
([我卧]|wo)([草艹槽]|cao)
//可能在中间夹不确定个数的空字符
([我卧]|wo)\s*([草艹槽]|cao)
//❀❀❀❀❀❀❀定义完整手机号规则:
//+86或0086 => +86 18717163354 / 0086 18717163354
//(\+86|0086) => +是正则有功能的特殊符号, 可是这里不希望+当做特殊功能使用, 只当做普通字符匹配, 所有用\+ 阻止正则解析 + 为数量词
//至少有一个空字符: \s+
//之前所有, 整体可有可无, 最多一次()?
((\+86|0086)\s+)?1[3-9]\d{9}
//❀❀❀❀❀❀❀定义完整身份证号规则
//15位数字: \d{15}
//2位数字: \d\d
//最后一位: 1位数字或X: [0-9X]
//最后三位 可有可无, 最多一次 (最后三位)
\d{15}(\d\d[0-9X])? =>测试 110102200012264 48520012551568444X
//❀❀❀❀❀❀❀定义正则, 防"微信" "weixin" "WX"
((微\s*)|(w\s*e\s*i\s*))(x\s*|信\s*)(i\s*n\s*)?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DSOykesf-1634980622727)(\小知识点.assets\image.png)]
指定匹配位置
一个字符串中三个位置比较特殊
- 字符串开头
- 字符串结尾
- 英文句子中的每个单词中间的空白位置
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DB9Dsz9a-1634980622728)(小知识点.assets\image-20210906142704762.png)]
如何
—如果只希望匹配特殊位置上的关键字时, 就可用特殊符号表示特殊位置
-
^ 表示 字符串开头
-
$ 表示字符串结尾
-
\b 表示单词边界, 可匹配: 空格, 标点符号, 字符串开头和结尾可将一个单词与其他单词分割开的符号
问题: 只写\b什么也匹配不到
原因: 其实\b是"零宽", 只匹配位置, 不匹配字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z11NSmzf-1634980622729)(小知识点.assets\image-20210906150237939.png)]
//匹配一组连续的空字符
//1: 匹配任意一组连续的空字符
no zuo no die => \s+
//2: 仅匹配开头的空字符
no zuo no die => ^\s+
//3: 仅匹配结尾的空字符
no zuo no die => \s+$
//4:匹配开头和结尾的空字符
no zuo no die => ^\s+|\s+$
//5:查找每个单词的首字母
you can you up =>\b[a-z]
//定义正则表达式验证电子邮件的格式:1957726268@qq.com
\w+ =>1个以上的合法字符
@ =>必须有一个@
\w+ =>1个以上的合法字符
\.必须有一个 . 但是 . 是通配符 要转义
\w+ +>后至少有一个后缀是一个以上的合法字符
\.cn 最后的.cn可有可无
所以 => \w+@\w+\.\w+(\.cn)?
js中字符串家提供的正则函数
i 忽略大小写 ignore(忽视)
g 全部 global(全局的)
console.log(str.search(/我草|卧槽|wocao/i));
查找敏感词
indexOf
-
查找一个固定不变的敏感词在字符串中出现的位置
回顾: var i = str.indexOf(“敏感词”,fromi)
=> 在字符串str中, 从fromi位置开始, 查找下一个"敏感词"出现的位置
=> fromi可以可省略 则默认从0位置(开头)开始查找第一个"敏感词"出现的位置
=>返回值:
如果找到敏感词, 则返回敏感词第一个字的下标位置i
如果没有找到敏感词,则返回-1
//检查用户输入的消息内容中是否包含敏感词"我草" <input type="text" id="a"> <p id="p"></p> <script> //检查用户输入的消息内容中是否包含敏感词"我草" var a = document.getElementById("a"); var p = document.getElementById("p"); a.oninput = function(){ var str = a.value; var i = str.indexOf("我草") if(i==-1){ p.innerHTML = "允许发送"; p.style.color = "green" }else{ p.innerHTML = "不允许发送"; p.style.color = "red" } } </script>
search-位置多种敏感
------存在问题: 只能查找敏感词的位置, 不能返回敏感词的内容
-------解决: 使用match
-
用正则表达式模糊查找多种敏感词的位置
var i = str.search(/正则/)
--------返回值:
找到返回下标, 没找到-1
var i = str.search(/[卧我|wo]([草艹槽]|cao)/i)
match-位置和内容
------存在问题: 默认只能查找第一个敏感词, 无法查找字符串中所有敏感词
-------解决:加/g, 但是就只能返回内容了
-
获取敏感词的内容极位置
var arr = str.match(/正则/i)
-------返回值:
找到 , 就返回数组包含这个敏感词的内容 和 敏感词的第一个字的位置
找不到, 返回null
-------数组结构:
[ “0”:“敏感词的内容”,“index”:“敏感词的第一个字的位置” ]
<input type="text" id="a"> <p id="p"></p> <script> var a = document.getElementById("a"); var p = document.getElementById("p"); a.oninput = function(){ var str = a.value; var arr = str.match(/([我卧]|wo)([草艹槽]|cao)/i); if(arr!=null){ p.innerHTML = `在位置${arr.index}发现敏感词${arr[0]}, 不允许发送` }else{ p.innerHTML = "允许发送" } } </script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8AeQn8Ag-1634980622729)(小知识点.assets\image-20210906170939493.png)]
替换敏感词
简单替换:
- 将所有找到的敏感词都替换为统一的新值
a.str.replace(/正则/ig,"新值");
//替换字符串str中所有符合正则要去的敏感词为统一的新值
<input type="text" id="a">
<p id="p"></p>
<script>
var a = document.getElementById("a");
var p = document.getElementById("p");
a.onblur = function(){
var str = a.value;
var i = str.replace(/([卧我]|wo)([草艹槽]|cao)/ig,"**")
a.value = i;
}
</script>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T63oK68y-1634980622730)(小知识点.assets\image-20210906174908574.png)]
高级替换:
-
根据每次找到的敏感词的不同, 动态选择不同的新值替换
str = str.replace(/正则/ig,function(k){ return 根据k不同, 返回不同的新值 });
原理:
-
replace会用正则去str中查找每个符合要求的敏感词
-
每找到一个关键词, 就自动调用一次回调函数
-
每次调用回调函数时, 都会自动将本次找到的敏感词传给函数的形参变量k
-
回调函数内部, 根据本次传入的keyword关键词不同, 动态选择不同的新值返回给replace
-
replace 会自动用回调函数返回的新值, 替换到字符串中本次找到的关键词位置
var str = "you can you up"; str = str.replace(/\b[a-z]/ig,function(k){ console.log(`调用了一次, 获得${k}, 替换为${k.toUpperCase()}`); return k.toUpperCase(); }); console.log(str);
-
-
删除关键词:
其实就是将找到的关键词替换为""
ES6/ES7 标准已经提供了trim等一系列去空格的函数
str.trimleft()
str.trimright()
str.trim()
//定义三个函数, //1: 可以只去掉字符串开头的空字符 function ltrim(str){ return str.replace(/^\s+/,function(k){ return ''; }); } var str = " no zuo no die "; console.log(ltrim(str)); //2:可以只去掉字符串结尾的空字符 function rtrim(str){ return str.replace(/\s+$/,function(k){ return ""; }); } console.log(rtrim(str)); //3:可以只去掉开头和字符串结尾的空字符 function trim(str){ return str.replace(/^\s+|\s+$/g,function(k){ return "" }); } console.log(trim(str));
切割字符串
简单切割
----分割符是一个固定不变得字符
var arr = str.split("分隔符");
复杂切割
-----切割符不是规定的, 但是却有规律
var arr = str.split(/正则/);
//意为: 按字符串str中所有符合正则要求的分隔符切割字符串为多段子字符串
//强调:不用加g, split也能找到所有的切割符切割
<ul id="score">
<li>98</li>
<li>55</li>
<li>68</li>
<li>75</li>
<li>788</li>
</ul>
<script>
// var lis = document.querySelectorAll("li");
// var arr = [];
// for(var li of lis){
// console.log(li);
// arr.push(li.innerHTML);
// }
// console.log(arr);
var ul = document.getElementById("score");
var html = ul.innerHTML;
//将html去掉开头的 "空字符<li>" 和 结尾的"</li>空字符"
html = html.replace(/^\s*<li>|<\/li>\s*$/ig,"");
console.log(html);
var arr = html.split(/<\/li>\s*<li>/);
console.log(arr);
</script>
RegExp对象
var reg = new RegExp("正则表达式","ig") //正则需动态生成
var reg = /正则/ig
test:验证
记得前后加 ^ $
var res = reg.test(str);
//返回值 boolean true/false
exec: 内容和位置
var arr = reg.exec(str);
//返回值 Array
//执行一次, 才会查找下一个, 需要用循环
字符串API
数组API
数组函数
数组.concat()
**–**连接一个或多个数组, 返回一个新数组
var arr1 = [1,2,3];
var arr2 = [4,5,7];
var arr3 = [11,21,22]
var arr4 = arr1.concat(arr2,arr3);
console.log(arr4);// [1, 2, 3, 4, 5, 7, 11, 21, 22]
数组.join()
**–**将数组元素拼接成字符串
var arr1 = [1,2,3];
var str = arr1.join('+');
console.log(str); //1+2+3
数组.reverse()
**–**将数组元素进行反转
var arr1 = [1,2,3];
var arr2 = arr1.reverse();
console.log(arr2);//[3, 2, 1]
数组.sort()
**–**数组元素排序
var arr1 = [1,21,31,22,78,2,3,11];
var arr2 = arr1.sort((a,b)=>a-b);
console.log(arr2); //[1, 2, 3, 11, 21, 22, 31, 78]
数组.push()
**–**向数组的最后面添加元素( 返回数组长度,会改变原数组 )
var arr1 = [1,2,3];
var arr2 = arr1.push('a');
console.log(`
arr1:${arr1}
arr2:${arr2}`);
// arr1:1,2,3,a
//arr2:4
数组.pop()
**–**删除数组的最后面的元素
var arr1 = [1,2,3];
var arr2 = arr1.pop();
console.log(arr1);// [1, 2]
console.log(arr2);//3
数组.unshift()
**–**在数组的最前面插入元素( 返回数组长度, 会改变原数组 )
var arr1 = [1,2,3];
var arr2 = arr1.unshift(2,3,'c');
console.log(arr1);//[2, 3, 'c', 1, 2, 3]
console.log(arr2);//6
数组.shift()
**–**删除数组的最前面的元素( 返回被删除的元素 )
var arr1 = [1,2,3];
var arr2 = arr1.shift();
console.log(arr1);//[2, 3]
console.log(arr2);//1
数组.splice()
**–**返回数组, 返回原数组的删除项目 会改变原数组
var arr1 = [1,2,3,4,5,7];
var arr2 = arr1.splice(1,2); //删除下标为1开始的两个元素(包括下标1)
console.log(arr1);//[1, 4, 5, 7]
console.log(arr2);//[2, 3]
//****************************
var arr1 = [1,2,3,4,5,7];
var arr2 = arr1.splice(1,2,'b');//删除下标为1开始的两位属性 , 并插入新元素
console.log(arr1);//[1, 'b', 4, 5, 7]
console.log(arr2);//[2, 3]
数组.slice()
**–**返回值为截取之后的数组, 不改变原数组 , 含头不含尾
var arr1 = [1,2,3,4,5,7];
var arr2 = arr1.slice(1,3);//截取下标1开始,下标2,不包含下标3
console.log(arr1);//[1, 2, 3, 4, 5, 7]
console.log(arr2);//[2, 3]
ES6数组新增函数
数组.every()
where—every
专门判断一个数组中是否***所有元素***都符合要求
How
var 判断结果 = 数组.every(
function(当前元素值, 当前数组的下标, 当前数组){
return 检查当前元素值是否符合要求, 并返回检查结果
}
)
//判断数组是否全由偶数组成
var arr1 = [2,4,6,8,10];
var res1 = arr1.every((n,i,arr)=>{
console.log(`当前元素值${n},当前下标${i},当前数组${arr},判断当前元素值是否为偶数${n%2==0}`);
return n%2==0;
});
数组.some()
where—some
专门检查一个数组中***是否包含***符合要求的元素
How
var 判断结果 = 数组.some(
function(当前元素值, 当前下标, 当前数组){
return 判断当前元素值是否符合要求
}
);
数组.map()
where
映射/对应
专门读取原数组中的每个元素值, 进行***修改**后(比如所有元素2), 生成一个新数组返回
How
var 新数组 = 原数组.map(
function(当前元素值, 当前下标, 当前数组){
return 当前元素值修改后的新值;
}
);
数组.foreach()
where
遍历
专门代替for循环来简化***遍历索引数组***的特殊函数
How
数组.forEach(
function(当前元素值, 当前下标, 当前数组){
对当前元素值执行操作;
//不需要返回值
}
);
var arr = ["亮亮","楠楠","东东"];
arr.forEach((n)=>{console.log(`${n}--到`)});
数组.filter()
where?
复制出数组中符合要求的个别元素, 放入新数组返回
How?
var 新数组 = 数组.fliter(
function(当前元素值, 当前下标, 当前数组){
return 判断当前元素值n是否符合要求;
}
);
数组.reduce()
where?
需要对数组中所有元素进行统计, 并放回统计结果的函数,允许设置初始值
How?
var 结果 = 数组.reduce(
function(捐款箱box, 当前元素值, 当前下标, 当前数组){
return 捐款箱+当前元素值
}
起始值 //必须写
);
//想统计数组中所有元素的和
var arr = [1, 3, 4, 6];
var res = arr.reduce((box, n, i, arr1) => {
console.log(`收到捐款箱变量:${box}, 当前元素值:${n}, 当前数组的下标:${i},当前数组: ${arr1}`);
return box + n;
},
2 //起始值设置为2
);
console.log(res);//16
Object.方法()
object.keys()
这个方法会返回一个由一个给定对象的自身可枚举属性组成的数组, 数组中属性名的排列顺序 和 正常循环遍历该对象时返回的顺序一致
Object.keys(obj)
//举例
let data = {
sname :"李雷",
address: "北京"
}
let arr = Object.keys(data)
console.log(arr);
//结果 ['sname', 'address']
//举例
let data = ['a','b','c']
let arr = Object.keys(data)
console.log(arr);
//结果 ['0', '1', '2']
JSON方法
JSON.stringify()
用于将JavaScript值转为json字符串
JSON.stringify(value)
JSON.parse()
JSON通常用于与服务器端交换数据
在接收到服务器数据时一般是字符串
使用这个方法将数据转换为JavaScript对象
JSON.parse(text)
浏览器本地存储
localStorage
什么时候会清除:
用户主动清空了缓存
使用户触发了清空的api
<title>localStorage</title>
<!-- 用户主动清空缓存 -->
<!-- 使用户触发了api -->
</head>
<body>
<h2>localStorage</h2>
<button onclick="saveData()">点我保存一个数据</button>
<button onclick="readData()">点我读取一个数据</button>
<button onclick="delData()">点我删除一个数据</button>
<button onclick="delAllData()">点我清空一个数据</button>
<script>
let p = {name:'张三',age:18}
function saveData(){
localStorage.setItem('msg','Hello');
localStorage.setItem('msg2',666);
localStorage.setItem('person',JSON.stringify(p));
}
function readData(){
console.log( localStorage.getItem('msg2'));
console.log( localStorage.getItem('msg'));
var res = localStorage.getItem('person');
console.log(JSON.parse(res));
}
function delData(){
localStorage.removeItem('msg2');
}
function delAllData(){
localStorage.clear();
}
</script>
sessionStronage
和localStronage的api一样
区别在于, 关闭浏览器就会自动清空缓存
实例
data(){
return {
//读取本地缓存的数据, 但是因为是json格式所有转为JavaScript对象格式
//用短路语句的作用是: 如果本地没有数据那么task就为null 那么后面对数组的操作就会报错
tasks:JSON.parse(localStorage.getItem('task')) || []
}
},
watch:{
//监视tasks数组
tasks:{
// 开启深度监视
deep:true,
handler(value){
localStorage.setItem('task',JSON.stringify(value));
}
}
},
组件的自定义事件
适用于 子vc===> 父vc
一种组件间的通信方式, 适用于 子组件 ===> 父组件
适用场景
a是父组件
b是子组件
b 想给 a 传数据 , 那么就要在 a 中给 b 绑定自定义事件 ( 事件在回调 a 中 )
绑定自定义事件
第一种方式
直接在子组件身上绑定
<school @getSchooName=“getSchoolName”/>
//父组件中
<template>
<div class="myapp">
<!-- 通过父组件给子组合绑定一个自定义事件实现 -->
<!-- 事件名 回调函数(事件处理函数)-->
<!-- ↓ ↓-->
<school @getSchoolName="getSchoolName"/>
<!-- .once表示只执行一次, 事件修饰符 -->
<!-- <school @getSchoolName.once="getSchoolName"/> -->
</div>
</template>
<script>
import School from './components/School.vue'
export default {
data(){
return {
myname:''
}
},
methods:{
// 接收子组件的值
// ↓
getSchoolName(params){
console.log(`收到了学校的名字: ${params}`);
//将子组件的值放到data里的myname上, 然后显示在页面
//插值语法只能读取 data props computed里的值
this.myname = params;
}
}
components:{Student,School}
}
</script>
//子组件中
<template>
<div class="school">
<h2>学校名 :{{schoolName}}</h2>
<!-- 子组件的回调函数(事件处理函数)-->
<!-- ↓ -->
<button @click="getSchoolName">获得学校的名字</button>
</div>
</template>
<script>
export default {
data(){
return {
schoolName:'翻斗小学',
}
},
methods:{
//子组件的事件处理函数
getSchoolName(){
// 父组件的自定义事件名 要传递的值(可以多个)
// ↓ ↓
this.$emit('getSchoolName',this.schoolName);
},
}
}
</script>
第二种
拿到了子组件实例对象再进行绑定
//给子组件一个ref属性, 方便拿到当前元素的元素对象(子组件的实例对象)
<school ref="school"/>
methods:{
// 接收子组件的值
// ↓
getSchoolName(params){
console.log(`收到了学校的名字: ${params}`);
//将子组件的值放到data里的myname上, 然后显示在页面
//插值语法只能读取 data props computed里的值
this.myname = params;
}
}
//给子组件绑定自定义事件
// 自定义事件名称 事件处理函数
// ↓ ↓
this.$refs.school.$on("getSchooName",this.getSchoolName);
想让事件只能触发一次, 可以使用once修饰符, 或$once方法
触发自定义事件
this.$emit("getSchoolName",数据);
解绑自定义事件
this.$off( ‘getSchooName’ )
this.$off() //清除所有
this.$off([“getSchoolName”,“demo”]); //解绑多个
组件绑定原生DOM事件
使用native修饰符
注意:
通过this. r e f s . x x x . refs.xxx. refs.xxx.on( ’ getScholName ',回调 ); 绑定自定义事件时, 回调要么配置在methods中, 要么用箭头函数, 否则this指向会出问题!
全局事件总线
—一种组件间通信的方式, 适用于任意组件间通信
安装全局事件总线
new Vue({
....
beforeCreate(){
Vue.prototype.$bus = this
//安装全局事件总线, $bus就是当前应用vm
}
.....
});
使用事件总线
- 接收数据:A组件想接收数据,则A组件中给$bus绑定自定义事件, 事件的回调留在A组件中
methods:{
//事件处理函数
demo(value){
console.log(`接收到了${value}`);
}
},
mounted(){
//给$bus绑定自定义事件
// 事件名
// ↓
this.$bus.$on('xxx',this.demo);
}
- 提供数据:
// 事件名
// ↓
this.$bus.$emit('xxx',要传递的数据);
解绑事件
最好在beforeDestroy钩子中, 用$off解绑当前组件所用到****的事件
原因: 绑定在$bus上的自定义事件是不能重名的
beforeDestroy(){
// 事件名
// ↓
this.$bus.$off('xxx');
}
总结: 父给子传 用props
子给父传 用函数 或者 自定义事件
其他( 兄弟 父传孙 ) 用全局事件总线
消息订阅与发布
----- 一种组件间通信的方式, 适用于任意组件间通信
- 订阅消息: 消息名
- 发布消息: 消息内容
需要用到第三方库 pubsub.js => publish ( 发布 ) subcribe ( 订阅 )
使用步骤:
安装pubsub:
npm i pubsub-js
引入
import pubsub from 'pubsub-js'
接收数据: A组件想接收数据, 则在A组件中订阅消息, 订阅的回调留在A组件自身
methods:{
// 消息名 传递回来的数据
// ↓ ↓
demo(msgName,data){
console.log(`接收到传递的数据${data}`);
}
},
mounted(){
// 用于取消订阅( 类似于清除定时器 )
// ↓ 消息名 事件处理函数(回调函数)
// ↓ ↓
this.pid = pubsub.subscribe('xxx',this.demo); //订阅消息}
提供数据
// 消息名 要传递的数据
// ↓ ↓
pubsub.publish('xxx',数据);
注意
最好在beforeDestroy钩子中, 取消订阅
Pubsub.unsubcribe( pid ) //取消订阅
for of 迭代器
注册用户: https://gitee.com/
babel
官网: https://www.babeljs.cn/docs/
babel是什么
是一个javascript编译器
是一个工具链, 主要将用于采用ECMAScript 2015+ 语法编写的代码转换为向后兼容的javascript语法. 以便能够运行在当前和旧版本的浏览器或其他环境中
-
语法转换
-
其他
…
});
#### 使用事件总线
- **接收数据:**A组件想接收数据,则A组件中给$bus绑定自定义事件**, 事件的回调**留在A组件中
````js
methods:{
//事件处理函数
demo(value){
console.log(`接收到了${value}`);
}
},
mounted(){
//给$bus绑定自定义事件
// 事件名
// ↓
this.$bus.$on('xxx',this.demo);
}
- 提供数据:
// 事件名
// ↓
this.$bus.$emit('xxx',要传递的数据);
解绑事件
最好在beforeDestroy钩子中, 用$off解绑当前组件所用到****的事件
原因: 绑定在$bus上的自定义事件是不能重名的
beforeDestroy(){
// 事件名
// ↓
this.$bus.$off('xxx');
}
总结: 父给子传 用props
子给父传 用函数 或者 自定义事件
其他( 兄弟 父传孙 ) 用全局事件总线
消息订阅与发布
----- 一种组件间通信的方式, 适用于任意组件间通信
- 订阅消息: 消息名
- 发布消息: 消息内容
需要用到第三方库 pubsub.js => publish ( 发布 ) subcribe ( 订阅 )
使用步骤:
安装pubsub:
npm i pubsub-js
引入
import pubsub from 'pubsub-js'
接收数据: A组件想接收数据, 则在A组件中订阅消息, 订阅的回调留在A组件自身
methods:{
// 消息名 传递回来的数据
// ↓ ↓
demo(msgName,data){
console.log(`接收到传递的数据${data}`);
}
},
mounted(){
// 用于取消订阅( 类似于清除定时器 )
// ↓ 消息名 事件处理函数(回调函数)
// ↓ ↓
this.pid = pubsub.subscribe('xxx',this.demo); //订阅消息}
提供数据
// 消息名 要传递的数据
// ↓ ↓
pubsub.publish('xxx',数据);
注意
最好在beforeDestroy钩子中, 取消订阅
Pubsub.unsubcribe( pid ) //取消订阅
for of 迭代器
注册用户: https://gitee.com/
babel
官网: https://www.babeljs.cn/docs/
babel是什么
是一个javascript编译器
是一个工具链, 主要将用于采用ECMAScript 2015+ 语法编写的代码转换为向后兼容的javascript语法. 以便能够运行在当前和旧版本的浏览器或其他环境中
- 语法转换
- 其他