一个完整的网页加载流程: (1)解析HTML结构 (2)加载外部脚本script和样式表文件link //页面中的多个脚本文件采用同步的方式加载 会产生“线程等待” (3)解析并执行脚本代码 (4)构建HTML DOM模型 (5)加载图片等外部资源文件 //图片等文件以异步线程的方式加载 不会产生等待 (6)页面加载完毕 css加载不会阻塞DOM树的解析 css加载会阻塞DOM树的渲染 css加载会阻塞后面js语句的执行
面试官:有使用过vue吗?说说你对vue的理解 | web前端面试 - 面试官系列
刘亦枫 - 个人中心 - 云+社区 - 腾讯云
#+空格 显示几级标题
ctrl + 数字 显示几级标题
ctrl + f 搜索页面内容
-+ 空格生成 无序列表
tab 对无序列表降级,shift+tab 对无序列表什级,按两下 enter 去除 无序列表
三个反引号 建立代码块片段
[toc] 建立目录
1.react 2.canvas 3.uniapp 4.ts+vue3
1.生成唯一的id
npm i nanoid import {nanoid} from "nanoid"//采用分别暴露,是一个函数,生成唯一的id id:nanoid()
2.退出登录,vuex处理昵称,vuex数据刷新页面数据丢失
退出登录 1.删除token localStorage.removeItem("qf-token") 2.跳转到登录页 this.$router.push("/login")
3.配置淘宝镜像
一、NPM设置淘宝镜像 1.查询当前配置的镜像 npm get registry 2.设置成淘宝镜像 npm config set registry http://registry.npm.taobao.org/ 3.换成原来的 npm config set registry https://registry.npmjs.org/ 二、Yarn 设置淘宝镜像 1.查询当前配置的镜像 yarn config get registry 2.设置成淘宝镜像 yarn config set registry http://registry.npm.taobao.org/ 3.换成原来的 yarn config set registry http://registry.npmjs.org/
4.nvm
nvm install stable ## 安装最新稳定版 node nvm install## 安装指定版本 nvm uninstall ## 删除已安装的指定版本 nvm use ## 切换使用指定的版本node nvm ls ## 列出所有安装的版本 nvm ls-remote ## 列出所有远程服务器的版本 nvm current ## 显示当前的版本 nvm alias ## 给不同的版本号添加别名 nvm unalias ## 删除已定义的别名 nvm reinstall-packages ## 在当前版本 node 环境下,重新 全局安装指定版本号的 npm 包 nvm alias default [node版本号] ##设置默认版本
5.echarts
安装
npm install echarts --save
引入echarts
import * as echarts from 'echarts';
练习
import * as echarts from 'echarts'; //echarts创建出来是没有高度的,所以需要手动给dom容器加上高度) // 基于准备好的dom,初始化echarts实例 let myChart = echarts.init(document.getElementById('main')); // 绘制图表 myChart.setOption({ title: { text: 'ECharts 入门示例' }, tooltip: {}, xAxis: { data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] });
开启loading动画
如果数据加载时间较长,一个空的坐标轴放在画布上也会让用户觉得是不是产生 bug 了,因此需要一个 loading 的动画来提示用户数据正在加载。
ECharts 默认有提供了一个简单的加载动画。只需要调用 showLoading 方法显示。数据加载完成后再调用 hideLoading 方法隐藏加载动画。
myChart.showLoading(); $.get('data.json').done(function (data) { myChart.hideLoading(); myChart.setOption(...); });
异步加载
入门示例中的数据是在初始化后setOption
中直接填入的,但是很多时候可能数据需要异步加载后再 填入。ECharts
中实现异步数据的更新非常简单,在图表初始化后不管任何时候只要通过axios等工具 异步获取数据后通过 setOption
填入数据和配置项就行。 获取的数据不符合自己想要的,通过map 数组方法,对数据进行处理。
自适应宽度
可以监听浏览器的resize事件,然后调用echarts中的resize方法
window.onresize = function () { myChart.resize() },然后将此方法写在mounted中
数据接口
折线图数据 https://chst.vip/data/rate.json
任务概况饼图 https://chst.vip/data/tarsk.json
期望课程饼图数据 https://chst.vip/data/expect.json
总结
文档里面有个配置项,对所有的setOption配置项进行配置,注意一定要给容器加高度!
正在上传…重新上传取消
事件 bind+事件名 例如 bindtab
正在上传…重新上传取消
事件传参
正在上传…重新上传取消
上传图片
正在上传…重新上传取消
正在上传…重新上传取消
1.设置父元素为相对定位, 子元素移动自身50%实现水平垂直居中
2.利用定位+transform
translate(-50%, -50%)
将会将元素位移自己宽度和高度的-50%
这种方法其实和最上面被否定掉的margin负值用法一样,可以说是margin
负值的替代方案,并不需要知道自身元素的宽高
3.定位 加上 margin :auto
4.flex布局
style> .father { display: flex; justify-content: center; align-items: center; width: 200px; height: 200px; background: skyblue; } .son { width: 100px; height: 100px; background: red; }
5.grid布局
浅拷贝:数组的slice(),concat(), 展开运算符
深拷贝:JSON.parse(JSON.stringify()) 对象里面不能有函数
lodash库中的_.cloneDeep()
JQuery.extend()
手写递归循环
正在上传…重新上传取消
正在上传…重新上传取消
BFC---Block Formatting context---块级格式化上下文 BFC页面里一块独立的渲染区域,有自己独立的渲染规则。 BFC决定了其子元素将如何定位,以及和其它元素的关系和相互作用 BFC布局规则: 1.内部的Box会在垂直方向,一个接一个地放置。 2.Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生重叠(两个盒子在不同的BFC内,就不会发生重叠)。 3.每个box的左边与包含块(父元素)的左边相接触(对于从左往右的格式化,否则相反);即使存在浮动也是如此。 4.BFC的区域不会与float box重叠(两栏布局)。 5.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素;反之也如此。 6.计算BFC的高度时,浮动元素也参与计算。 出发BFC---哪些元素默认是BFC?哪些属性可以让元素变成BFC? 1.根元素 html 2.float属性不为none(left,right) 3.position为absolute或fixed(脱离正常文档流) 4.display为inline-block, table-cell(td,th), table-caption(caption), flex, inline-flex,inline-table 5.overflow不为visible(auto,hidden,scroll)
闭包如何产生的:两个函数嵌套,内部函数引用了外部函数的值或者方法!
优点 1.可以读取函数内部的变量 2.可以让这些局部变量保存在内存中,实现变量数据共享。
缺点 1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
用途场景
匿名自执行函数 我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在函数执行完后会立刻释放资源,关键是不污染全局对象。 代码如下: (function() { var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], today = new Date(), msg = 'Today is ' + days[today.getDay()] + ', ' + today.getDate(); alert(msg); } ());
结果缓存
我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。 var CachedSearchBox = (function(){ var cache = {}, count = []; return { attachSearchBox : function(dsid){ if(dsid in cache){//如果结果在缓存中 return cache[dsid];//直接返回缓存中的对象 } var fsb = new uikit.webctrl.SearchBox(dsid);//新建 cache[dsid] = fsb;//更新缓存 if(count.length > 100){//保正缓存的大小<=100 delete cache[count.shift()]; } return fsb; },
clearSearchBox : function(dsid){ if(dsid in cache){ cache[dsid].clearSelection(); } } }; })();
封装 var person = function(){ //变量作用域为函数内部,外部无法访问 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }();
实现类和继承 function Person(){ var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } };
var p = new Person(); p.setName("Tom"); alert(p.getName());//Tom var Jack = function(){}; //继承自Person Jack.prototype = new Person(); //添加私有方法 Jack.prototype.Say = function(){ alert("Hello,my name is Jack"); }; var j = new Jack(); j.setName("Jack"); j.Say(); alert(j.getName());//Jack
1. 在高度塌陷元素最后面添加一个块级元素,给这个块级元素添加 claer:both ;属性 定义万能的清除浮动类(利用伪元素::after) 2 .clear::after{ content:""; display:black; clear:both; overflow:hiddent;(当不小心给这个conten添加了内容时候,高度设为0,再溢出隐藏) height:0; }
opacity 规定元素的不透明级别----针对ie8以上版本ie浏览器和其他浏览器支持 属性值: 接受0-1之间数字书写,默认值为1 0表示完全透明,1表示完全不透明 0-1之间的数字就表示半透明的效果 在IE8及以下版本的ie浏览器中实现透明需要通过以下方法 filter:alpha(opacity=value); value取值为 0-100 0表示完全透明,100表示完全不透明 0-100之间的数字就表示半透明的效果 visibility 规定元素是否可见 visible 默认值,可见 hidden 不可见 元素不可见的区别 不可见后 占据空间 (隐身不可见) opacity: 0; visibility: hidden; 不可见后 不占据空间 (消失不可见) display: none;
cursor 属性规定要显示的光标的类型(形状)。
该属性定义了鼠标指针放在一个元素边界范围内时所用的光标形状
正在上传…重新上传取消
一个常用的针对移动网页优化过的页面的 viewport meta 标签大致如下: width:控制 viewport 的大小,可以指定的一个值,如 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)。 height:和 width 相对应,指定高度。 initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。 maximum-scale:允许用户缩放到的最大比例。 minimum-scale:允许用户缩放到的最小比例。 user-scalable:用户是否可以手动缩放。
在HTML5中,为input元素新增了以下一些type属性值: color:用于指定颜色的控件。 date:用于输入日期的控件(年,月,日,不包括时间)。 month:用于输入年月的控件,不带时区。 week:用于输入一个由星期-年组成的日期,日期不包括时区 time:用于输入不含时区的时间控件。 datetime:基于UTC时区的日期时间输入控件(时,分,秒及几分之一秒)。 datetime-local:用于输入日期时间控件,不包含时区。 email:用于应该包含 e-mail 地址的输入域。在提交表单时,会自动验证 email 域的值。 number: 用于应该包含数值的输入域。只能输入数字 range:用于应该包含一定范围内数字值的输入域。range 类型显示为滑动条。 search:用于输入搜索字符串的单行文本字段。换行会被从输入的值中自动移除。 tel:用于输入电话号码的控件。在移动端输入会显示数字键盘,PC端无效果 url:用于编辑URL的字段。
正在上传…重新上传取消
新多媒体元素有: audio, video, source(定义多媒体资源) embed(定义嵌入的内容,比如插件) track(为
正在上传…重新上传取消
正在上传…重新上传取消
内联元素是不可以控制宽和高、margin等;并且在同一行显示,不换行。 块级元素时可以控制宽和高、margin等,并且会换行。 1. inline : 使用此属性后,元素会被显示为内联元素,元素则不会换行 inline是行内元素,同行可以显示,像span、font、em、b这些默认都是行内元素,不会换行,无法设置宽度、高度、margin、border 2. block : 使用此属性后,元素会被现实为块级元素,元素会进行换行。 block,块元素,div、p、ul、li等这些默认都是块元素,会换行,除非设置float 3. inline-block : 是使元素以块级元素的形式呈现在行内。意思就是说,让这个元素显示在同一行不换行,但是又可以控制高度和宽度,这相当于内敛元素的增强。(IE6不支持) inline-block,可以同行显示的block,想input、img这些默认就是inline-block,出了可以同行显示,其他基本block一样
table 表格 tr 行 th 表头单元格 (会加粗字体 会居中) td 单元格 caption 元素定义表格标题。 caption 标签必须紧随 table 标签之后。您只能对每个表格定义一个标题。通常这个标题会被居中于表格之上。 # 一般情况下 tr只能包含 td 和th , td和th 可以 包含其他标签前。
表格属性
正在上传…重新上传取消
正在上传…重新上传取消
表单元素
正在上传…重新上传取消
//文本框 //密码框 //单选框,多个相同单选框,name属性的值要一样,checked属性标识默认选中 // 多选框 name 属性值也要一样 // 提交按钮,value 可以更改按钮的值 // 重置按钮,value 可以更改按钮的值 // 上传文件按钮
下拉框
正在上传…重新上传取消
label标签
增加用户体验,使表单元素获取焦点,必须要有一个for 属性,对应的表单元素要有一个id属性,且两者值相同
正在上传…重新上传取消
color 规定元素内文字的颜色
属性值:英文单词颜色 十六进制颜色
font-size 规定元素内的文字大小
属性值:length(数值+单位) 浏览器中默认的文字大小为16px
font-family 规定元素内文字字体
属性值:"字体名称" "字体名称1","字体名称2","字体名称3","..."
文字字体规定可以设定备用字体,使用逗号分隔的方式实现
优先执行第一个字体,如果不能执行则忽略执行第二个字体
如果规定的所有字体都不能执行,最终会执行默认字体
书写字体名称时,如果字体名称是由中文或由多个单词组成则需要用双引号包含,如果是一个单词 组成的则不用双引号
一般为了方便或者防止出错,不论什么情况都是加双引号
Windows中文版本操作系统下,中文默认字体为宋体或者新宋体,英文字体默认为Arial.
font-weight 规定元素内文字是否加粗
属性值:normal 默认值,不加粗 bold 加粗 === bolder 更粗
100-500 600-900
font-style 规定元素内文字是否倾斜
属性值:normal 默认值,不倾斜 italic 倾斜 === oblique 倾斜度更大
line-height 行高,规定文字在一行内占据的高度
属性值:length(数值+单位) 数字(根据文字大小计算的倍数值) %(根据文字大小计算的百分比值)
行高具有垂直居中性:文字会显示在文字行高的空间内的垂直居中的位置显示
文字的行高 与 元素的高度 之间的关系
A)当单行文本的行高等于元素高时,可实现单行文本在元素中垂直方向居中对齐;
B) 当单行文本的行高小于元素高时,可实现单行文本在元素中垂直中间以上任意位置的定位;
C) 当单行文本的行高大于元素高时,可实现单行文本在元素中垂直中间以下任意位置的定位。
文本属性的简写:
font: 是否倾斜 是否加粗 文字大小/行高 "字体";
例:font: italic bold 30px/50px "楷体";
简写时属性值顺序部分先后,但是针对文字大小和行高必须是 斜杠前为文字大小,斜杠后为行高
简写时某个属性值取默认值时,可以省略不写
但是在简写中只要保证 规定了 文字大小 和 字体 font: 文字大小 "字体"
即使连文字字体都是不需要设置,也至少要写上双引号 font: 文字大小 ""
text-align 规定元素内文本的水平对齐方式
属性值:left 默认值,左对齐 center 居中对齐 right 右对齐 justify 分散对齐
text-indent 规定元素内文本首行缩进
属性值:length(数值+单位) 接受负值书写
仅针对元素内的第一行文字有效
text-decoration 规定元素内文本的修饰
属性值: none 默认值,没有修饰 overline 添加上划线
underline 添加下划线 line-through 添加删除线
letter-spacing 规定调整汉字和字母间距的属性
属性值:length(数值+单位) 正值间距扩大,负值间距缩小
word-spacing 规定调整单词间距的属性
属性值:length(数值+单位) 正值间距扩大,负值间距缩小
em单位 相对单位 相对于当前元素的文字大小值计算的单位
1em === 当前元素的文字大小值
默认情况下 1em == 16px
1.background-color 规定元素的背景颜色
属性值:transparent 默认值,透明 英文单词颜色 十六进制颜色
2.background-image 规定图片作为元素的背景
属性值:url(引入作为背景显示的图片路径以及全称--使用相对路径)
背景图片的显示原则:
1)元素的背景区域尺寸等于背景图片尺寸,背景图片正好显示在元素的背景区域中
2)元素的背景区域尺寸大于背景图片尺寸,背景图片将默认平铺,直至铺满元素
3)元素的背景区域尺寸小于背景图片尺寸,只显示元素范围以内的背景图
网页上有两种图片形式:插入图片、背景图;
插入图片:属于网页内容,也就是结构。
背景图:属于对元素的修饰,也就是表现。background-image: ;
background-repeat 规定背景图片的平铺方式
属性值:repeat 默认值,平铺 repeat-x 横向平铺 repeat-y 纵向平铺 no-repeat 不平铺
background-position 规定背景图片的显示位置
默认值:left top === 0px 0px === 0% 0%
value1(水平位置):left center right length(数值+单位)
%(根据背景区域的宽和背景图的宽的差值计算百分比值)
value2(垂直位置):top center bottom length(数值+单位)
%(根据背景区域的高和背景图的高的差值计算百分比值)
通过length(数值+单位)规定背景图片的位置
水平的值是在设定背景图的左边距离元素背景区域的左边的距离,正值背景图向右,负值向左
垂直的值是在设定背景图的上边距离元素背景区域的上边的距离,正值背景图向下,负值向上
通过百分比规定背景图片的位置
如果背景区域大小 大于 背景图大小
水平百分比正值背景图向右,负值向左
垂直百分比正值背景图向下,负值向上
如果背景区域大小 小于 背景图大小
水平百分比正值背景图向左,负值向右
垂直百分比正值背景图向上,负值向下
scroll 默认值,滚动,背景图片的位置规定是根据元素的背景区域的左边和上边作为参照位置存在的
fixed 固定,将背景图位置偏移的参照位置改为了浏览器的显示窗口的左边和上边
规定背景图片的大小
background-size :cover (图片比例大小不变,将元素铺满,如果图片大于元素,图片不会完全示)
contain (图片比例不变,图片大于元素时,图片会变小,会完全展示在元素部)
100px(宽) 200px(高)
100% 100%
100% auto (宽度百分百,高度自适应)
背景属性的简写:
background: 颜色 url(图片路径) 平铺方式 背景图状态 水平位置 垂直位置;
例子:background: url(./练习/1.gif) no-repeat 237px 113px;
简写中属性值顺序不分先后,但是水平位置和垂直位置必须有先后,水平位置在前,垂直位置在后
简写中某个属性值采用默认值时,可以省略不写,自动按照默认值书写
注意:
在css的设定中,一个元素是可以拥有多张背景图的,
但是为了在初期更好学习,我们暂时先认为一个元素只可以写一张背景图
参考阮一峰 Flex 布局教程:语法篇 - 阮一峰的网络日志
flex 布局案例 Flex 布局教程:实例篇 - 阮一峰的网络日志
写在容器上的属性
display : flex / inline-flex 行内块级弹性盒 (为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。元素成为弹性盒后,子元素会产生块级框,不论任何类型元素都可以设置宽高了)
flex-direction:row / column / row-reverse / column-reverse (规定主轴的方向,默认横向row )
flex-wrap : nowrap / wrap / wrap-reverse 调整互换了侧轴起点和终点的位置(规定元素是否可以换行 默认值wrap 不可以换行)
flex-flow:row nowrap (简写 规定主轴方向,以及换不换行)
justify-content: 规定调整伸缩项目在主轴上的对齐方式
flex-start 默认值,起点对齐
flex-end 终点对齐
center 居中对齐
space-around 分开边距对齐(相当于给每一个伸缩项,添加一个相同的外边距)
space-between 分开两边对齐(一个靠左边,一个靠右边,中间平均分配)
space-evenly 每个伸缩项中间的距离绝对相等
align-items:规定单行伸缩项目在侧轴方向对齐方式
stretch 默认值,拉伸对齐 flex-start 起点对齐 flex-end 终点对齐 center 居中对齐 baseline 基线对齐(文本的下边缘对齐)
7.align-content 规定调整多行伸缩项目在侧轴上的对齐方式 stretch 默认值,拉伸对齐 flex-start 起点对齐 flex-end 终点对齐 center 居中对齐 space-around 分开边距对齐 space-between 分开两边对齐
写在伸缩项上的属性
1、 align-self 规定调整单行伸缩项目在侧轴上的对齐方式 auto 默认值,自动按照伸缩容器上设置align-items规定的值执行 stretch 拉伸对齐 flex-start 起点对齐 flex-end 终点对齐 center 居中对齐 baseline 基线对齐
2、order 规定调整伸缩项目在伸缩容器中的排列位置 属性值为number数字,默认值为0,值越大越靠后,值越小越靠前,值一样时按照结构的 顺序排列
3、flex-grow 规定设置伸缩项目在主轴方向的大小的放大比例 当伸缩项目在主轴方向的大小相加之和 小于 伸缩容器的主轴长度时 在主轴方向上就会有 剩余空间存在 可以通过 flex-grow 指定 伸缩项目主轴方向的大小 扩大 占据剩余空间的比例 flex-grow的默认值为0,表示在主轴方向存在剩余空间时不让伸缩项目扩大 属性值可以指定number数字,指定伸缩项目占据剩余空间的份数比例
4、flex-shrink 规定设置伸缩项目在主轴方向的大小的缩小比例 当伸缩项目在主轴方向的大小相加之和 大于 伸缩容器的主轴长度时 在主轴方向上就会有 溢出空间存在 可以通过 flex-shrink 指定 伸缩项目主轴方向的大小 缩小 占据溢出空间的比例 flex-shrink的默认值为1,表示在主轴方向存在溢出空间时让伸缩项目缩小溢出空间的1份 使其不溢出 属性值可以指定number数字,指定伸缩项目占据溢出空间的份数比例 如果需要使用此属性必须保证伸缩项目是不允许换行的,并且伸缩项目主轴方向大小相加 大于主轴长度
5、flex-basis 规定设置弹性盒伸缩基准值---伸缩项目在主轴方向的大小值 单位px 例如px auto 默认值,自动,横向主轴时按照width值执行,纵向主轴时按照height值执行
6、flex 用于指定 flex-grow 、flex-shrink 和 flex-basis 属性的简写属性 默认值为 0 1 auto 如果给 flex 只给到一个属性值,一般给值为1,则此属性值表示 flex-grow:1;
flex-shrink:1 一般使用的是 flex:1; ===== flex-grow: 1;
参考阮一峰文章(CSS Grid 网格布局教程 - 阮一峰的网络日志)
容器属性:
1.使容器成为一个网格布局
display : grid / inline-grid (行内元素);
2.定义列和行
grid-template-coumns:100px 200px 300px ;
grid-template-rows : 1fr 3fr 5fr ;
属性值有 :
px
fr关键字
百分比 33% 33% 33% 占容器的宽高
auto 自动填充 grid-template-coumns:100px auto 300px ;
repeat() 函数
repeat()
接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。
repeat()
重复某种模式也是可以的。
grid-template-columns: repeat(3, 33.33%);
grid-template-columns: repeat(2, 100px 20px 80px);
3.定义行和列之间的间距
grid-row-gap :10px ;
grid-column-gap : 10px ;
简写 grid-gap :grid-row-gap grid-column-gap ;
grid-gap: 10px 10px
4.伸缩项在单元格中的对齐方式
水平 justify-items:stretch(默认值占满整个单元格) / start / center / end ;
垂直 align-items:stretch(默认值占满整个单元格) / start / center / end ;
简写 place-items : 垂直 水平
5.整个伸缩项在容器中对其方式
水平 justify-content :start / center / end / space-around /space-between /space-evenly
垂直 align-content :start / center / end / space-around /space-between /space-evenly
简写 place -content : 垂直 水平
给单元格 命名区域
grid-template-areas : "a b ."
"d e f"
"g . h"
对于不需要命名的区域 用 .代替
项目属性
1.给伸缩项指定在 容器中的指定区域
grid-area : a ;
2.规定单个伸缩项在网格中的对其方式
align-self: start /end / center ;
justify-self: start /end / center ;
简写 place-self : 垂直 水平 ;
7.划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行
grid-auto-flow: row(默认值)
:column
属性 (position)
固定定位 position : fixed;
固定定位使元素脱离文档流,在父元素中 不占据空间。以浏览器窗口作为位置偏移的参照。
通过 left right top bottom 调整在浏览器窗口的位置。
length 可以写成百分比,例:right:100%,距离浏览器窗口右侧宽度100%
固定元素 产生块级框,可以使行内元素 (例如span),写宽和高。
固定元素没写宽高时,宽高 由内容撑开。
固定元素 没有设置指定位置时,会默认固定在初始位置。
2.相对定位 position :relative
相对定位元素不会使元素脱离文档流,在父元素中占据空间。
以自身初始作为位置偏移的参照,通过 left right top bottom 调整位置。
length 可以写成百分比,例:right:100%,距离父元素右侧宽度100%
相对定位元素 不会产生块级框,不可以使行内元素 (例如span),写宽和高。
绝对定位 position : absolue;
绝对定位使元素脱离文档流,在父元素中 不占据空间。以包含快作为位置偏移的参照。
包含块:有定位的,最近的父级元素,如果父级元素都没有定位,则以html为包含快
通过 left right top bottom 调整在包含快中的位置。
length 可以写成百分比,例:right:100%,距离包含块右侧宽度100%,以包含块为标准。
绝对定位元素 产生块级框,可以使行内元素 (例如span),写宽和高。
绝对定位元素没写宽高时,宽高 由内容撑开。
绝对定位元素 没有设置指定位置时,会默认固定在初始位置。
总结:一般情况 ,给父级元素设定 相对定位(relative)使其不脱离文档流,给子元素 设定 绝对 定位
z-index 值越大 ,元素就越在上层
第一种方法
将选中的图标加入到项目中,下载代码,里面有个demo_index.html文件,浏览器打开运行一下,里面介绍有三种方法,记住里面对应的路劲记得修改!
盒模型 :标准盒模型 / 怪异盒模型
box-sizing=boder-box//怪异盒模型
box-sizing=content-box//标准盒模型
元素占据空间的计算
水平方向:width + 左右padding + 左右border + 左右margin
垂直方向:height + 上下padding + 上下border + 上下margin
标准盒模型:给元素书写的width和height属性仅表示元素的内容区的大小
怪异盒模型(ie盒子模型):给元素书写的width和height属性表示包含 内容区+内边距+边框 的区域的总大小
padding
padding 是元素的内容 和 border 直接的空白区域
padding 没有负值
行内元素 只有左右padding 和margin 没有上下
padding的区域也是元素的背景区域
padding 可以调整子元素在父元素中的位置
padding可以调整内容在容器中的位置
margin
margin 是元素的外边距 可以调整同级元素之间的关系
margin 可以有负值
第一个子元素的margin-top 会向上传递给父元素,会一直传递, 给父元素添加 overflow: hidden 来解决
相邻的两个元素的margin 会重叠,触发bfc之后则不会重叠(浮动元素margin不重叠)
margin: 10px (上下左右)
margin:10px 20px (上下 左右)
margin:10px 20px 30px (上 左右 下)
margin:10px 20px 30px 40px (上 右 下 左)
边距在所选元素及其周围的所有元素之间添加空白空间,并且不会影响元素内容的大小。现在有个巧妙的小秘密,从边框的外边缘开始,margin-top 将选定的元素向下推动而不移动其他元素,而 margin-bottom 将所述元素保持在原位并向下推动其他元素。margin-left 将所选元素推到右侧,并且不移动其他元素,而 margin-right 将所述元素保持在原位并将其他元素推到右侧。
第一步 在头标签里面,定义视口,检测到真实的屏幕宽度,否则都是980px
@media screen and (max-width:800px){ div{ background:red; } } 注意:max-width:800px ,当屏幕小于等于800px时候生效 min-width:900px ,当屏幕大于等于900px时候生效
伪元素选择符 (两个冒号,和类名没有空格)
#box::after{content:"666",display:block} 插入的是一个行内元素 伪元素选择符/伪对象选择符 权重:0001 被选元素::after{content: "插入的内容";display: 属性值;属性: 属性值;属性: 属性值;} 定义在被选元素的内部的最后面插入内容 插入内容是通过content属性实现,content属性的属性值就是插入的内容,属性值需要用双引号包含 说是插入了内容,其实是在被选元素内部的最后面插入了一个行内元素,在行内元素中包含着内容 既然是插入了一个元素,那就可以给这个元素改变元素类型,可以给元素修饰样式,以及内部文本修饰样式 被选元素::before{content: "插入的内容";} 定义在被选元素的内部的最前面插入内容 插入内容是通过content属性实现,content属性的属性值就是插入的内容,属性值需要用双引号包含 说是插入了内容,其实是在被选元素内部的最前面插入了一个行内元素,在行内元素中包含着内容 既然是插入了一个元素,那就可以给这个元素改变元素类型,可以给元素修饰样式,以及内部文本修饰样式 被选元素::first-letter{属性: 属性值;属性: 属性值;} 定义被选元素内第一个字符的样式 只能定义文字属性的样式,不能改变类型等其他操作 被选元素只能是一个块级元素 被选元素::first-line{属性: 属性值;属性: 属性值;} 定义被选元素内第一行字符的样式 只能定义文字属性的样式,不能改变类型等其他操作 被选元素只能是一个块级元素 被选元素::selection{background-color: 属性值;color: 属性值;} 定义被选元素内文本被鼠标选中后的样式 只能定义 背景颜色 和 文字颜色 属性
伪类选择符
/* 未访问的链接 */ a:link { color: #FF0000; } /* 已访问的链接 */ a:visited { color: #00FF00; } /* 鼠标悬停链接 */ a:hover { color: #FF00FF; } /* 已选择的链接 */ a:active { color: #0000FF; }
语法 sass 变量* $变量名: CSS属性值; 嵌套*:在大括号中写选择器即可 会自动加父前缀 选择器{ 子选择器{ ... } } 继承*:%名称 {} @extend %名称 混入*:@mixin 名称($变量:默认值) {属性:$变量} @include 名称 函数:@function 函数名() { @return ceil() } 调用 CSS属性名: 函数名() 其他(了解) less 变量:之前$ 现在@ @变量名: CSS属性值; CSS属性名: @变量名; 嵌套:相同sass 继承: 选择器:extend(选择器) { 当前样式 } eg .center {color:red} main类名要继承center类 .main:(.center) {这里面就拥有了 color:red 这个样式} &:last-child { //&:代表父级 border-right: 1px solid #ccc; }
在项目中使用less
npm i less npm i less-loader // scoped 避免样式被污染
computed:{ reverseMsg(){ return this.msg.split("").reverse().join("") } }
reverseMsg会自动保存在data模型数据中 可用{{reverseMsg}} 在模板实例中展示
计算属性get,set方法
conputed:{ reverseMsg:{ get(){ return this.Msg.split("").reverse().join("") }, set(input){ this.Msg = input } } }
主要侦听模型数据的变化 函数名就是模型数据中的变量名
普通监听 watch:{ num (newData,oldData){ console.log(newData) console.log(oldData) } }
深度监听 监听对象里面数据变化 watch:{ obj:{ immediate:true,//默认是false 初始化就让handler调用一下 deep:true, handler(newData,oldData){} } } // obj 是要监听的模型数据中对象名字,处理函数必须是handler 这个名字
当监听的数据非常深层次时,可用字符串函数来监听 watch:{ "obj1.obj2.obj3.name"(new,old){} } 注意 可以监听数组,但是不能监听操作 数组的length和索引,只能监听数组的内置方法引起的变化
对模板实例中 复杂的逻辑进行处理,例如美元转人民币
局部过滤器
{{dolor | toRmb}}
filters: { toRmb (input) { return input*6 } } toRmb 是过滤器的名称,input 是接受 dolor 传过来的值,return 返回值给dolor
全局过滤器
Vue.filter ("toRmb",(input)=>{ return return input*6 })
正在上传…重新上传取消
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
mounted() { console.log(document.getElementById("pp").innerText); this.msg = "值发生改变了" nextTick用于获取更新之后的dom元素 this.$nextTick(function () { console.log(document.getElementById("pp").innerText); }) v2.6 nextTick原理:setTimeout setTimeout(function () { console.log(document.getElementById("pp").innerText); }, 20) }
作用:缓存组件的状态,然后避免重复渲染导致的性能问题
正在上传…重新上传取消
//keep-alive 里面包含的是组件名,要被缓存的组件
两个属性:include(缓存) exclude(不缓存) , 要缓存多个组件,可用数组
//keep-alive 里面包含的是组件名,要被缓存的组件
两个钩子函数 (都写在组件实例中)
当组件被缓存的时候,如果组件里面有定时器,需要用这个钩子函数deactivated(),进行销毁
destroyed(){} ,这个声明周期钩子函数不能销毁定时器,因为组件被缓存了。
activated(){},被 keep-alive 缓存的组件激活时调用 ,例如tab被点击时
deactivated(){},被 keep-alive 缓存的组件停用时调用。
props 接收到的数据是在自己写的数据之前,如果要修改接受过来的数据,可以写一个数据=接受的数据,在更改自己定义的数据 例如 myName=this.name ,这个name,props是接受过来的.
正在上传…重新上传取消
在子组件标签名上,动态添加一个属性,属性值是要传过去的模型数据
在子组件vue实例里面 添加一个props:[] 属性接受 这个动态属性,会自动保存在子组件的模型数据中
在子组件实例中 用props:[val],来接受msg
props校验
一般情况用用 props:[],进行接收数据不安全,而改用数组 props:{ val:{ type:String, // 限制传过来的数据类型 required:true, // 规定必须要出传val 数据过来 default(){ return "孝宏"} ,// 当没有传val 过来的时候,默认值为孝宏,一般 情况,有了required,就不需要默认值了 validator(value){ reyurn true // 校验成功 reyurn false // 校验失败 } } }
发布订阅者模式 v-on (订阅)$emit (发布)
自定义事件不要用驼峰命名法
v-on 是接受数据 ,$emit 是发送数据
methods:{ handel(input){ //input 接受从子组件传过来数据 } } 在子组件实例中 mounted:{ this.$emit("zdy",this.msg) // 这里的zdy 对应这上面自定义的zdy事件,msg 传过去给 input 接受
子传父第二种
父组件向子组件传送一个方法,子组件通过props接受,调用这个方法,通过参数的形式数据传给父组件 父组件模板实例中写上 methods:{ receive(x){ console.log("我从子组件接收到数据了") } } 子组件模板实例上写 props:["rexeive"] 随便在一个方法里面调用接收到的receive方法 this.receive(this.name)//this.name 就是要传过去的数据
新建一个单独的js文件,里面的内容如下 import Vue from "vue" export const eventBus = new Vue() 再在两个兄弟组件中引入这个新建的文件 import {eventBus} from "路径" 订阅 eventBus.$on("receive",(input)=>{ this.msg=input; // input 接收 this.gift 传过来的值 }) 发布 eventBus.$emit("receive",this.gift ) 对事件解绑 (在只传值一次的情况下) eventBus.$off("receive" )
默认插槽
1.组件以双标签的形式编写 双标签中间写入需要分发的内容 2.在组件模板结构中,在相应的位置通过slot标签来接收
如花 凤姐 芙蓉姐姐 这是father组件的结构
// 这里的slot 会接受father组件里面的li标签,放在这里
具名插槽
当使用具名插槽的时候,需要将原有的标签用template 包起来,在template上写v-slot
具名插槽 不用template的时候 可以 直接slot="rh"、slot="fj" 如果用v-slot 就要用template 并且v-slot:rh 后面值没有冒号 如花 凤姐 芙蓉姐姐 这是father组件的结构
作用域插槽
当是默认插槽时 用 scope="",来接受传过来的数据,当是作用域插槽时 用 v-slot:name = "" ,来接收数据
作用域插槽 就是为了在使用组件名中,遍历组件结构中的数据,默认遍历的数据是对象结构
用= 来接受传过来的值,默认是对象,所以用{},来结构赋值 {{item}} const vm =new Vue({ data(){ return (){ arr:["如花","凤姐","芙蓉姐姐"] } } })这是father组件的结构
添加一个动态属性name ,来接受这个arr里面值
正在上传…重新上传取消
正在上传…重新上传取消
默认插槽用scope接受
具名插槽 直接在v-slot:name="" , 这样来接收
在父组件中 必须用scope="",去接受子组件中传过来的数据 ,默认是一个对象,可以结构赋值出来
也可以用slot-scope="",来接收。
在子组件中的slot标签上随便添加一个动态的属性将要传的数据发出去,例如 :name="arr"
注意:
#用scope 报错时 就这样用用= 来接受传过来的值,默认是对象,所以用{},来结构赋值 {{item}}
正在上传…重新上传取消
正在上传…重新上传取消
ref(可以进行 父子通信)
$root, $parent ,可以获取到根组件实例,以及获取到父组件实例,进行子父传参,支持链式调用
用法: $refs.ref值
如果在普通的 DOM 元素上使用,获取到的就是 DOM 元素;
如果用在子组件上,获取到的就是组件实例, 相当于获取到组件的vm实例;
// 使input 标签获取到焦点 mounted { console.log(this.$refs); this.$refs.ipt.focus() }
可以实现跨组件传数据(爷孙通信)
在一个组件实例中写 provide(){ return {gift:this.msgG} }, 在另一个组件实例中写 inject:["gift"],会自动保存到模型数据中 provide:{ gift:"传过去的数据" // 对象这种方式好像不可以传data中的数据 } 在另一个组件实例中写 inject:["gift"],会自动保存到模型数据中
可以获取到根组件的实例,并且可以修改 this.$root.msg = "跟组件的信息被修改了"
可以获取到都父组件的实例 可支持链式调用! thi.$parent.$parent.mag = "被修改了"
安装 :npm i vue-router@3 //默认安装会安装4 版本,只适用于vue3版本 router文件夹下index.js文件下写入以下代码 import VueRouter from "vue-router" import About from "../components/About.vue" const router = new VueRouter({ routes:[ { path:"/about", component:About, children:[ { path:'child', //子级路由不需要加 / 路径 ,但在router-link to="/about/child" 补全 component:()=>ipmort("") } ] }, { path:"/home", component:()=>import("../components/Home.vue") } ], }) export default router main.js文件写入 import VueRouter from "vue-router" Vue.use(VueRouter) import router from "./router/index" app.vue文件里面要展示路由内容的地方写下
router-link
{{item.title}}
this.$router.push
// 字符串 router.push('/home') // 对象 router.push({ path: '/home' }) // 命名的路由 router.push({ name: 'user', params: { userId: '123' }}) // 带查询参数,变成 /register?plan=private router.push({ path: '/register', query: { plan: 'private' }}) this.$router.replace()// 不会记录历史记录栈 this.$router.back() //后退 this.$router.forward() //前进 this.$router.go(4) // 里面接整数,
keep-alive
缓存组件< keep-alive/> 缓存多个组件 < keep-alive/> 两个钩子函数 (都写在组件实例中) 当组件被缓存的时候,如果组件里面有定时器,需要用这个钩子函数deactivated(),进行销毁 destroyed(){} ,这个声明周期钩子函数不能销毁定时器,因为组件被缓存了。 activated(){},被 keep-alive 缓存的组件激活时调用 ,例如tab被点击时 deactivated(){},被 keep-alive 缓存的组件停用时调用。
路由传参
query传参数this.$route.query来接收 params传参数 this.$route.params来接收 params 传参数时,路由要写占位符 例如 在路由文件里写上 path:'/detail/:title/:id'
props接收 传送参数
三种方式 1.对象 在对应的组件路由里面写上 props:{title:"苹果",id:"001"} 在对应的组件里面写上props:["title","id"] 来接收,就不需要this.$route来接收了,这可以在模板中展示 2.布尔值 在对应的组件路由里面写上 props:true // 这种情况只对于params传参数 占位符 有效 在对应的组件里面写上props:["title","id"] 来接收 3.函数 props($route){ return {$route.query.title,$route.query.id} } props:["title","id"]
路由守卫
1.全局路由守卫 (全局前置路由守卫) router.beforeEach router.beforeEach( (to,from,next) => { to//表示跳转到哪个路径, to.path//要跳转的路径 from//表示当前路径 console.log(to,from) next() //表示放行 next({path:"/login"}) //表示跳转到其他页面 }) (全局后置后置守卫) router.afterEach router.afterEach((to,from)=>{ 在路由元信息里面配置每个页签名字 document.tittle = "管理系统" }) // 只有两个参数 ,没有next() 2.(独享路由守卫,只对某一个路由进行限制,写在路由配置项里面) berofreEnter((to,from,next)=>{}) 3.组件内路由守卫(写在组件实例里面) beforeRouterEnter(to,from,next){} // 根据路由规则,进入组件之前 beforeRouterLeave(to,from,next){} // 根据路由规则,离开组件之后
//路由要做的就是 将组件映射到routes //使用路由的步骤 //1.创建页面组件 //2.在router=>index.js引入页面组件 //3.配置routes,一个path对应一个component //4.告诉router需要渲染在哪里(router-view)
在main.js文件里,引入 router import router from "路径",将router 挂载在,main.js ,vue实例里面 src路径下,建立router文件夹,里面建立index.js文件,写入以下内容 import Vue from "vue" impore VueRouter from "vue-router" Vue.use(VueRouter) // 将路由注册到每一个子组件 import Home from "路径" // 将Home 组件引入进来 const routes = [ { path:"/", redirect:"/home" //路由重定向 }, //配置路由,就在routes 这里面配置 { // 一般情况下我们只需要 path 和 component 两个字段 path: "/home", compontnt:Home mata:{}//路由元信息,自己配置字段信息,可以和路由守卫进行结合使用 }, ] export default new VueRouter({ ruotes, mode:"history" //更改路由模式 })
// 一般这种情况的配置需要引入对应的组件路径,而且不利于页面渲染 const routes = [ { path: "/home", compontnt:Home }, ] // 路由懒加载 首屏加载速度非常快 const routes = [ { path: "/home", compontnt:()=>import("对应的组件路径") }, ]
const routes = [ { name:"home", //给路由加一个name字段 path: "/home", compontnt:Home }, ] // 将里面的 to 变成动态的home组件
路由配置里面添加 children 字段
注意:子集路由router-view 写在父级路由对应的组件里,另外子集路由一级path,不需要加 “/”
正在上传…重新上传取消
子集路由组件建立在父级路由对应的组件下
discover 是父级,下面都是对应的子路由组件
正在上传…重新上传取消
// 写在组件的结构中,匹配相对应的路由,展示对应组件的内容
// 和 a 类似 ,有一个 to 属性,跳转到对应的、路由路径发现组件
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
正在上传…重新上传取消
除了使用
创建 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
router.push(location, onComplete?, onAbort?)
注意:在 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push。
想要导航到不同的 URL,则使用 router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
当你点击
时,这个方法会在内部调用,所以说,点击
等同于调用 router.push(...)
。
声明式 | 编程式 |
---|---|
|
router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。例如:
// 字符串 router.push('/home') // 对象 router.push({ path: '/home' }) // 命名的路由 router.push({ name: 'user', params: { userId: '123' }}) // 带查询参数,变成 /register?plan=private router.push({ path: '/register', query: { plan: 'private' }})
注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = '123' router.push({ name: 'user', params: { userId }}) // -> /user/123 router.push({ path: `/user/${userId}` }) // -> /user/123 // 这里的 params 不生效 router.push({ path: '/user', params: { userId }}) // -> /user
同样的规则也适用于 router-link
组件的 to
属性。
路由props也叫路由解耦合
一般情况 query传参数接收 this.$route.query.id this.$route.query.name 一般情况 params 传参数 params 传参直接将参数值写在路由后面,然后路由配置相对应的动态路由 params 要开启动态路由,配置要重改 { path;"/details/:id/:name", name:"details" } 接收 this.$route.params.id this.$route.params.name
#props接收参数 不需要在this.$route.query或者this.$route.params 直接用props发送,props接收
正在上传…重新上传取消
这三种props 写完之后,还需要在对应的组件实例里面写上props:["id","title"]
案例 (商品列表跳详情)
正在上传…重新上传取消
在要跳转的商品详情路由配置里面 开启 动态路由
const routes = [ { path: "/home", compontnt:()=>import("对应的组件路径") }, { path: "/detail/:id" // 开启了动态路由, id接收传过来的值 component:()=>("") } ]
在商品详情组件代码如下
通过this.$route.params 来接收,商品列表传过来的id
正在上传…重新上传取消
一个“路径参数”使用冒号 :
标记。当匹配到一个路由时,参数值会被设置到 this.$route.params
,可以在每个组件内使用。于是,我们可以更新 User
的模板,输出当前用户的 ID:
const User = { template: 'User {{ $route.params.id }}' }
你可以看看这个在线例子。
你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params
中。例如:
模式 | 匹配路径 | $route.params |
---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: '123' } |
除了 $route.params
外,$route
对象还提供了其它有用的信息,例如,$route.query
(如果 URL 中有查询参数)、$route.hash
等等。你可以查看 API 文档 的详细说明。
const routes = [ //配置路由,就在routes 这里面配置 { path: "*", redirect:"/" 路由重定向到"/"路劲下 compontnt:()=>import("404页面路径") }, ]
全局前置路由守卫 (写在main.js里或者router.js里)
初始化的时候被调用,每次路由跳转之前被调用 router.beforeEach( (to,from,next) => { to//表示跳转到哪个路径, to.path//要跳转的路径 from//表示当前路径 console.log(to,from) next() //表示放行 })
正在上传…重新上传取消
全局后置路由守卫(在更改页签名的时候用到)
router.afterEach((to,from)=>{}) // 只有两个参数 ,没有next() 在路由元信息里面配置每个页签名字 document.tittle = ""
独享路由守卫 beforeEnter()
对某一个路由单独的进行限制,写在该路由的配置项里面 beforeEnter:(to,from,next)=>{}
组件内路由守卫
写在某个组件mounted里面 beforeRouterEnter(to,from,next){} // 进入组件之后 beforeRouterLeave(to,from,next){} // 离开组件之后
为什么要使用vuex ,当多个组件都要使用共同数据时,就将数据放到 vuex 里面进行数据管理。
安装 yarn add vuex@3
下载npm i vuex@3 (默认4版本,搭配vue3使用,vue2使用3版本)
首先在src平级目录下建立文件夹 vuex 或 store ,在文件夹里面建立 index.js文件,在index.js文件写入以下代码
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export default new Vuex.Store({ //Store s必须大写 strict:true, //告诉开发者,只能使用moutation 更改state 数据 // 五大核心 state:{}, // getters 相当于 vue 里面的计算属性 getters:{}, // 存储变更状态的方法 mutations:{}, actions:{}, // 模块化 modules:{} })
然后在main.js 里面 导入 import store from 'vuex的相对路径' , 最后在main.js 文件里vue实例里面 注册store
export default new Vuex.Store({ state:{ age:18, name: "裴孝宏" }, })
如何在其他的组件中获取,vuex 中的 state 的值呢 ?
普通方法 在组件结构中 {{$store.state.num}} ,组件实例中 this.$store.state.num
辅助函数 mapState 映射在computed中,在组件中script 标签里面引入 import {mapState} from "vuex",
在组件实例中 computed 属性里,来接受 vuex.state的数据,然后就直接{{age}} 来表示了
是用来更改state 里面的数据
每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
编写mutations中的类型的时候,我们会大写类型名字(就是函数名)
export default new Vuex.Store({ state:{ age:18, name: "裴孝宏" }, mutations:{ ADD(state,payload){ state.age++ }, REDUCE(state,payload){ state.age-- } } }) 在需要接收vuex中的数据组件中,普通方法触发mutations中的定义方法 a
用辅助函数来触发mutations 中的方法,映射在methods
相当于computed, 对vuex里面数据进行复杂的逻辑处理
export default new Vuex.Store({ state:{ age:18, name: "裴孝宏" msg: "我在边界做前端" }, getters:{ reverseMsg(stase){ return state.msg.split("").reverse().join("") } } }) 普通方法调用{{$store.getters.reverseMsg}}
辅助函数方法 ,映射在computed中{{reverseMsg}}
在state中定义一个空数据,发送异步获取请求,请求到数据,,给mutation将请求的数据,赋值给state中的空数据。
export default new Vuex.Store({ state:{ age:18, name: "裴孝宏", msg: "我在边界做前端", product:[], }, mutations:{ SETDATA (state,payload){ state.product=payload; } }, actions:{ GETDATA (content,payload){ // content 对象包含vuex实例,含有state,commit方法 console.log(content) } // 结构赋值一下 GETDATA ({commit,state},payload){ axios("chst.vip/data/index.json") .then(res=>{ console.log(res) commit("SETDATA",res) }) } } }) 调用 用dispatch方法 this.$store.dispatch("GETDATA","一些数据")
一定要开启命名空间!!!
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state mutation、action、getter.
import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); import user from "./user" // user 是新建的模块化名称 export default new Vuex.Store({ modules:{ user } }) 在store里面建立一个user文件夹,里面建立一个index文件,写入以下代码 export default { namespaced:true, //开启命名空间 state:{ name:"裴孝宏" }, getters:{}, mutations:{}, actions:{}, } 如何获取模块化中的数据信息{{$store.state.user.name}}
一定要加上模块化的名字
通过辅助函数映射state,mutation,action,getters
import {mapState,mapMutations,mapActions,mapGetters} from "vuex" { computed:{ ...mapState('模块化名字',['映射的属性']), ...mapGetters('模块化名字',['映射的属性']) }, methods:{ ...mapMutations('模块化名字',['映射的属性']), ...mapActions('模块化名字',['映射的属性']) } }
1.正在上传…重新上传取消
在项目根目录建一个vue.config.js 和 src 目录同级
配置完设置之后,一定要重启项目 配置完设置之后,一定要重启项目 配置完设置之后,一定要重启项目!!!!!
// module.exports = { devServer: { port:3000,//设置项目端口号 host:"0.0.0.0", //允许所有的主机访问当前项目 proxy:{ '/api':{ // 一个标识正则匹配到以这个开头的时候 就用代理 target:"http:chst.vip:8081", //指向的是目标服务器 pathRewrite:{ // 路径重写 '^/api':"" } } } } } //发请求的时候 原地址 http:chst.vip:8081/data/index.json //改成 /api/data/index.json
默认有两个环境,开发环境和产品环境
.env.development 开发环境
.env.production 产品环境
NODE_ENV 配置当前环境的字段,NODE_ENV = 开发环境
outputDir:打包生成的文件夹名称,默认是'dist'
process.env 可以获取当前环境中所有的配置
process.env.NODE_ENV
在环境文件中配置字段 要以VUE_APP开头
在.env.development 文件中 配置字段 VUE_APP_NAME = CRM系统 VUE_APP_BASE_URL = http://chst.vip NODE_ENV = 开发环境
在.env.production 文件中 配置字段 VUE_APP_NAME = APP系统 VUE_APP_BASE_URL = https://chst.vip:8080 NODE_ENV = 测试环境
test 测试环境
留心 :打包测试环境主要加 --mode test
在进行build 的时候,要在vue.config.js 文件中,module.exports 中要添加 publicPath: "./",
为了配置静态资源路径
"test": "vue-cli-service build --mode test"
所谓的环境就,通俗的讲就是代码运行在不同的环境下,配置不一样,最常见的就是服务器的地址不一样,下面让我们来配置一些环境
1.可以在根目录下新建一些文件,如下
2.配置字段
NODE_ENV
配置当前环境字段 可以通过process.env.NODE_ENV
outputDir
:打包生成的文件夹名称,默认是'dist'
2.修改vue.config.js
中的打包输入目录
修改package.json
文件
--mode表示指定加载那种环境的文件,默认development,production
4.在代码中修改判断
项目环境:开发环境(development),产品环境(production);不同的环境就是配置不同的服务器地址
axios.defaults.baseURL= ""
定义默认携带认证,这句话开启之后,才可以将浏览器的cookie携带给服务器,服务器也可以对浏览器进行cookie设置
axios.defaults.withCredentials = true
安装axios yarn add axios
总结
axios.get()方法里面有两个参数,axios.get("url",{配置项 params:{},headers:{},timeout:1000 }) axios.post()方法里面有三个参数,第一个是url ,第二个传参数,第三配置项 axios.post("url",{age:30,name:"张三"},{headers:xxx-xxx,timeout:1000})
axios.get() 请求
方法1
// 使用axios发送一个get请求 axios.get("http://chst.vip:1902/students/getstulist") .then(res => { console.log(res) })
方法2 (传参)
axios.get("http://chst.vip:1902/positions/getlist", { //get请求传递query参数的方法 //1.直接在url后面拼接 //2.在config属性里的params:{}进行传递 //参数列表 params:{ name:"裴孝宏"} //请求头配置 headers:{ token: token } }) .then(res => { console.log(res) })
axios.post()请求
axios.post("http://chst.vip:1902/users/login", { //传递数据 username: "lbw", password: "555, },{ //把请求头 设置为传递json的方式 // headers: { // "Content-type": "application/json;charset=UTF-8" //}, }) .then(res => { console.log(res) }) .catch(err => { console.log(err ) })
axios config用法
axios({ url: "http://chst.vip:1902/users/login", //请求地址 method: "post", //请求方式 data: { //post传递的参数 如果是get请求 使用params username: "lbw", password: "555" }, params: { // get 传递参数 name: "裴孝宏" }, headers: { //请求头 "Content-type": "application/json" } timeout:1000 //请求的时间 在请求时间内得不到结果 就进入catch }) .then(res => { console.log(res) }) .catch(err => { console.log(err) })
请求拦截器
//请求拦截器 http.interceptors.request.use(function (config) { nprogress.start() //由于请求数据的时候需要携带token //但是 登入 获取验证码 校验验证码不需要token let rowPaths = ["/users/getCaptcha", "/users/login", "/users/verifyCaptcha"]; // config.url 可以获取当前被拦截的请求的请求地址 // console.log(config) if (rowPaths.includes(config.url)) { return config //放行 } else { //从本地存储把token取出来,携带给其它请求 let token = localStorage.getItem("qf-token") || ""; config.headers['authorization'] = token; return config; //放行 } }) //请求拦截器,可以拦截所有的请求,然后添加我们需要的逻辑层
响应拦截器
axios.interceptors.response.use(function (config) { console.log(config) nprogress.done() //进行响应拦截 //当响应回来的状态码 是10022 或者 1004的时候 需要跳转到登入页,清除token // console.log(config) if (config.data.code === "10022" || config.data.code === "1004") { //router打哪儿来? router.push("/login"); localStorage.removeItem("qf-token"); //刷新页面 location.reload(); //提示用户登入过期 elementUI.Message.error("登入过期,请重新登入") return } if (config.data.code === "10026") { elementUI.Message.error("没有权限") return } if (!config.data.state && !config.data.img && config.config.url !== "/order/query_order_status") { // console.log(config) // console.log(123) elementUI.MessageBox.alert(config.data.msg, "提示", { type: "error" }) return config } return config; })
目录
牛客网知识点
参考学习
介绍
待学习
项目总结
小程序
零散小知识
子元素在父元素实现水平垂直居中
深浅拷贝
BFC
闭包
清除浮动
透明度(opacity)
cursou 属性
html
meta
h5标签
块级元素、行内元素
表格
表单
css
文本相关属性
背景相关属性
弹性盒
网格布局grid
定位
阿里图标库的使用
盒模型(padding margin)
媒体查询
伪元素选择符 伪类选择符
sass/less
css3新特性
盒子阴影(box-shadow)
圆角(border-radius)
渐变(linear-gradient)
过度(transition)
转换(transform)
动画(animation)
rgba(颜色)
javascript
window对象
js内置对象
Git命令
字符串
数组相关
promise
async await
原型
Math对象
Data对象
对象相关
函数
事件
ES6
new一个对象做个啥
this指向场景
call apply bind 函数方法
函数扩展
let const
解构赋值
模板字符串
模块化导入导出
新增数据结构Set Map
class类
H5存储
正则表达式
vue2
原理
mvvm模型
Objdefine.defineProperty()
Vue.set() 以及vm.$set()
vue-cli(重点)
minins(混入)
plugins.js插件
vue指令
自定义指令
v-model
v-bind
v-on
v-for
深度选择器
计算属性
侦听器(watch)
过滤器 (filters)
Vue.nextTick
keep-alive (缓存组件)
组件
父传子
子传父
兄弟通信
插槽slot
插槽(第二遍理解)
ref
provide( 传数据) inject(接受数据)
this.$root
this.$parent
路由
路由
配置路由
路由懒加载
具名路由
嵌套路由 子集路由
router-view
router-link(声明式导航)
编程式导航
路由传参数(props接收)
动态路由和参数
配置404页面
路由守卫
vuex状态管理工具
配置vuex
state
mutations
getters
actions
modules
vue项目总结
反向跨域代理
配置环境
axios