文章目录
前端技术类比(图)
es6
let与var的区别:
区别1:
// var 声明的变量往往会越域
// let 声明的变量有严格局部作用域
{
var a = 1;
let b = 2;
}
console.log(a);// 1
console.log(b);// ReferenceError: b is not defined
区别2:
// var 可以声明多次
// let 只能声明一次
var m =1;
var m =2;
let n = 3;
let n = 4;
console.log(m);
console.log(n);
区别3:
// var 会变量提升
// let 不存在变量提升
console.log(x)
var x = 10
console.log(y)
let y = 11
const
// 1. 声明之后不允许改变
// 2. 一但声明必须初始化,否则会报错
const a = 1;
a = 3; //Uncaught TypeError: Assignment to constant variable.
结构表达式
- 数组:
let arr = [1,2,3]
let [a,b,c] = arr;
console.log(a,b,c)//1 2 3
- 对象
const person = {
name:"aa",
pw:"bb",
like:[1,2,3]
}
const{name:n,pw,like} = person;
console.log(n,pw,like)//aa bb (3) [1, 2, 3]
- 字符串扩展
let str = "abcdefg.txt"
console.log(str.startsWith("abc"))
console.log(str.endsWith("abc"))
console.log(str.includes("abc"))
- 字符串模板
let a = 123
function fun(){
return 123
}
let str = `a=${a + 1}
${fun()}
c`
console.log(str)
// a=124
// 123
// c
函数优化
//给函数参数设置默认值
function fun(a,b=1){
return a + b;
}
console.log(fun(3))//4
//不定参数
function fun(...param){
console.log(param.length)
}
fun(1,2,3,4)//4
//箭头函数
var print = v => console.log(v)
print(123)//123
//箭头函数+解构
const p = {
name:11
}
var print2 = ({name}) => console.log(name)
print2(p)//11
对象优化
//Object
const p = {
name:1,
pw:2
}
console.log(Object.keys(p));//['name', 'pw']
console.log(Object.values(p));//[1, 2]
console.log(Object.entries(p));//[Array(2), Array(2)]
const target = {a:1}
const source1 = {b:1}
const source2 = {c:1}
Object.assign(target,source1,source2)
console.log(target);//{a: 1, b: 1, c: 1}
//声明对象简写
const name = 1
const pw = 2
const p = {name,pw}
console.log(p);//{name: 1, pw: 2}
//对象的函数属性简写
var p = {
name: "aa",
eat1 : function(food){
console.log(this.name + "吃" + food);
},
//eat2 : food => console.log(this.name + "吃" + food)//箭头函数this不能使用
eat2 : food => console.log(p.name + "吃" + food),
eat3(food){
console.log(this.name + "吃" + food)
}
}
p.eat1(11)
p.eat2(22)
p.eat2(33)
// aa吃11
// aa吃22
// aa吃33
//对象扩展运算符
//1、深拷贝
const p = {
n:1,
p:2
}
const p2 = {...p}
console.log(p2);//{n: 1, p: 2}
//2、合并对象
const a = {a:"aa"}
const b = {b:"bb"}
const c = {...a,...b}
console.log(c);//{a: 'aa', b: 'bb'}
map和reduce
//map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。类似y=f(x)
var x = [1,2,3,4]
var y = x.map(x => 2*x)
console.log(y);//[2, 4, 6, 8]
//reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,
//基本使用:reduce(callback,[initialValue]),
//其中:
// initialValue:是自定义初始值
// callback可包含以下参数
// 1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
// 2、currentValue (数组中当前被处理的元素)
// 3、index (当前元素在数组中的索引)
// 4、array (调用 reduce 的数组)
var a = [1,2,3,4]
var ans = a.reduce((p,c) => {
console.log("上一个:" + p);
console.log("当前:" + c);
return p + c;
},100)
//运行结果:
// console.log("ans:" + ans);
// 上一个:100
// 当前:1
// 上一个:101
// 当前:2
// 上一个:103
// 当前:3
// 上一个:106
// 当前:4
// ans:110
promise
存在跨域问题,无法进行测试
解决可看:https://blog.csdn.net/OrangeChenZ/article/details/86468239
- 存在如下需求:
//1、查出当前用户信息
//2、按照当前用户的id查出他的课程
//3、按照当前课程id查出分数
- 3个数据文件:(放在与html文件同级目录下的mock目录下)
- user.json
{
"id": 1,
"name": "zhangsan",
"password": "123456"
}
- user_corse_1.json
{
"id": 10,
"name": "chinese"
}
- corse_score_10.json
{
"id": 100,
"score": 90
}
- 实现需求的方法:(推荐第三种)
//1、传统方法实现:
$.ajax({
url: "mock/user.json",
success(data) {
console.log("查询用户:", data);
$.ajax({
url: `mock/user_corse_${data.id}.json`,
success(data) {
console.log("查询到课程:", data);
$.ajax({
url: `mock/corse_score_${data.id}.json`,
success(data) {
console.log("查询到分数:", data);
},
error(error) {
console.log("出现异常了:" + error);
}
});
},
error(error) {
console.log("出现异常了:" + error);
}
});
},
error(error) {
console.log("出现异常了:" + error);
}
});
//2、Promise可以封装异步操作:
let p = new Promise((resolve, reject) => {
//1、异步操作
$.ajax({
url: "mock/user.json",
success: function (data) {
console.log("查询用户成功:", data)
resolve(data);
},
error: function (err) {
reject(err);
}
});
});
p.then((obj) => {
return new Promise((resolve, reject) => {
$.ajax({
url: `mock/user_corse_${obj.id}.json`,
success: function (data) {
console.log("查询用户课程成功:", data)
resolve(data);
},
error: function (err) {
reject(err)
}
});
})
}).then((data) => {
console.log("上一步的结果", data)
$.ajax({
url: `mock/corse_score_${data.id}.json`,
success: function (data) {
console.log("查询课程得分成功:", data)
},
error: function (err) {
}
});
})
//3、定义一个函数
function get(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
data: data,
success: function (data) {
resolve(data);
},
error: function (err) {
reject(err)
}
})
});
}
get("mock/user.json")
.then((data) => {
console.log("用户查询成功~~~:", data)
return get(`mock/user_corse_${data.id}.json`);
})
.then((data) => {
console.log("课程查询成功~~~:", data)
return get(`mock/corse_score_${data.id}.json`);
})
.then((data)=>{
console.log("课程成绩查询成功~~~:", data)
})
.catch((err)=>{
console.log("出现异常"+err)
});
模块化
类似java中的导包
例如,存在如下两个js文件:
export
:导出:
- 批量导出(函数同理)
var a1 = 1 var a2 = 3 export{a1,a2}
- 声明并导出:(函数同理)
export var a3 = 2
- export default则import的时候可以任意指定名字
export default { a4:1 }
import
:导入
- 格式:import xx from “xx.js”(其中.js可以省略)
import a1 from "./a" //单个导入 import {a2,a3} from "./a" //批量导入 import aa from "./a" //aa在a文件中不存在,但存在default,所以可以自己指定名字
vue
MVVM思想
M:model,模型,包括数据和一些基本操作
V:view,页面渲染结果
VM:view-model,模型与视图的双向模型,然后同步到model中
快速使用vue
- npm 初始化项目(npm在本文后面)
npm init -y
- 安装vue
npm install vue@2.6.10
npm install vue是安装最新稳定版,但可能会出错或者没有vue.js文件
- script引入vue.js
<script src="./node_modules/vue/dist/vue.js"></script>
- 使用vue
<div id="app"> {{ message }} </div> <script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) </script>
- F12打开控制台可以改数据
例如:在控制台输入:app.message=123
,发现页面数据由"Hello Vue!“变成"123”
- F12打开控制台可以改数据
插件
VSCode插件
Vue 2 Snippets(语法提示)
- 语法提示:
Vue 2 Snippets
也可以安装vue 3的:
Vetur(后缀名为.vue
文件代码提示)
谷歌浏览器插件:devtools-chrome
-
到github:https://github.com/vuejs/vue-devtools下载zip文件
-
解压到一个目录
-
给谷歌浏览器添加扩展程序
把刚解压目录填过来即可
安装成功后,f12开发者模式:
指令
单向绑定 v-html、v-text、v-bind
-
v-html:以html显示
-
v-text:文本显示
-
{{表达式}}:表达式必须有返回值
-
v-bind:给标签属性绑定值;使用:v-bind:属性名=“属性值”
对class、style进行增强:
例如:{active:a,‘txt-danger’:b},其中a、b是从vue的date中取的
<script src="./node_modules/vue/dist/vue.js"></script>
<div id="app">
{{html1}}<br>
<span v-html="html1"></span><br>
<span v-text="html1"></span><br>
<a v-bind:href="link">超链接</a>
<div v-bind:class="{active:a,'txt-danger':b}">class</div>
<div v-bind:style="{color:c}">color</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
html1:"<h1>你好</h1>",
link:"http://www.baidu.com",
a:true,
b:true,
c:"red"
}
})
</script>
效果图:
双向绑定 v-model
官网:https://cn.vuejs.org/guide/essentials/forms.html
- v-model=“xx”,其中xx是data的属性
<script src="./node_modules/vue/dist/vue.js"></script>
<div id="app">
<input type="checkbox" value="a" v-model="like">a
<input type="checkbox" value="b" v-model="like">b
<input type="checkbox" value="c" v-model="like">c
</div>
<script>
var app = new Vue({
el: '#app',
data: {
like:[]
}
})
</script>
效果:
其他指令v-on、v-for、v-show、v-cloak、v-once、v-pre
官网: https://cn.vuejs.org/api/built-in-directives.html
-
v-on:例如:v-on:click,可简写为@click
v-on提供事件修饰符:.stop
:阻止冒泡到父元素(大小div都有click事件,小的被点击会影响到大div).prevent
:阻止默认事件发生(例如,阻止a标签跳转网页).capture
:使用事件捕获模式.self
:只有自身触发事件才执行.once
:只执行一次
-
v-for:
基本使用:- 遍历集合:
v-for="(item index) in items" :key="item.id"
其中,:key指定用什么区分 - 遍历对象:
v-for="(value,key,index) in user"
- 遍历集合:
-
v-if:判断结果为true则会被渲染
- v-else
- v-else-if
-
v-show:结果为true,才会显示,利用的是控制标签的
disable
属性 -
v-cloak:
例如:
css:[v-cloak] { display: none; }
<div>:
<div v-cloak> {{ message }} </div>
直到编译完成前,<div> 将不可见。
-
v-once:可用作显示初始值,只解析一次。
-
v-pre:跳过编译,加快解析。
缩写
v-bind 缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
v-on 缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
事件修饰符:
prevent
:阻止默认事件(常用);stop
:阻止事件冒泡(常用):once
:事件只触发一次(常用);capture
:使用事件的捕获模式;self
:只有event.target是当前操作的元素是才触发事件;passive
:事件的默认行为立即执行,无需等待事件回调执行完毕;
键盘事件
- Vue中常用的按键别名:
回车 =>enter
删除=>delete(捕获"删除”和“退格”键)
退出=>esc
空格=>space
换行=>tab
上=>up
下=>down
左=>left
右=>right
基本使用,如:
组合按键,如:ctrl + v
-
Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名),例如:caps-lock(切换大小写的按键)
-
系统修饰键(用法特殊):ctrl、alt、shift、meta(win)
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被
(2).配合keydown使用:正常触发事件。 -
也可以使用keyCode去指定具体的按健(不推荐)
-
Vue.config.keyCodes.自定义键名=键码,可以去定制按键别名
计算属性和侦听器
- vue对象里面有计算属性
computed
和侦听器watch
<script src="./node_modules/vue/dist/vue.js"></script>
<div id="app">
苹果:单价{{pgp}},数量<input type="number" value="a" v-model="pgn"><br>
西瓜:单价{{xgp}},数量<input type="number" value="b" v-model="xgn"><br>
总价格:{{total}}<br>
{{msg}}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
pgp:1,
xgp:100,
pgn:0,
xgn:0,
msg:""
},
computed: {
//计算总价格
total() {
return this.pgp*this.pgn + this.xgp*this.xgn;
},
},
watch: {
//监听苹果的数量是否大于等于3
pgn(newValue, oldValue){
if(newValue>=3){
this.msg="数量太多了"
this.pgn=3
}else{
this.msg=""
}
},
},
})
</script>
扩展
- 计算属性:
Vue对象的过滤器
<script src="./node_modules/vue/dist/vue.js"></script>
<div id="app">
<li v-for="num in nums">
filter1:{{num | filter1}}<br>
filter2:{{num | filter2}}
</li>
</div>
<script>
//全局过滤器(全局过滤器要写在前面,写在后面不可用)
Vue.filter("filter2", val => {
if (val > 3) {
return "比3大"
} else {
return "小于等于3"
}
});
var app = new Vue({
el: '#app',
data: {
nums: [1, 2, 3, 4, 5]
},
//局部过滤器
filters: {
filter1(val) {
if (val % 2 == 1) {
return "奇数"
} else {
return "偶数"
}
},
},
});
</script>
自定义指令
例如,实现一个可以将值放大10倍的v-big指令:
<div id="root">
<h2>当前的n值是:<span v-text="n"></span></h2>
<h2>当前的n值放大10倍之后是:<span v-big="n"></span></h2>
<button @click="n++">点我n+1</button>
</div>
<script>
new Vue({
el:"#root",
data:{
n:1
},
directives:{
big(elements,binding){
//console.log(elements,binding)
elements.innerText = binding.value * 10
}
}
})
</script>
第一个参数elements可以拿到标签信息,在这里就是:<span></span>
第二个参数binding的value对应于n的值
组件化
抽取组件,避免重复开发
非单文件组件
也就是所有组件写在一个文件里。
- 全局组件:
//1. 声明
Vue.component("name",{
template:`核心代码`,
data(){
return{
数据
}
}
})
//2. 使用,则直接写上标签名:
<name></name>
- 局部组件
//1. 声明:
const name = {
template:`核心代码`,
data(){
return{
数据
}
}
}
//其完整写法:如果我们写成对象,底层会帮我们完成转化。
//const name = Vue.extend({
// template:`核心代码`,
// data(){
// return{
// 数据
// }
// }
//})
//2. 在Vue实例中添加components属性,例如:
new Vue{
...
components{
'组件名字':name
}
}
- 例子:(声明 -> 引入 -> 使用)
<script src="./node_modules/vue/dist/vue.js"></script>
<div id="app">
<qjzj></qjzj>
<qjzj></qjzj>
<qjzj></qjzj><br>
<componet_1></componet_1>
</div>
<script>
// ----------全局组件----------
//可直接放在页面上用(页面需支持Vue,即,需写在被某个Vue实例管理的标签内)--
Vue.component("qjzj",{
template: '<button v-on:click="count_qjzj++">全局组件:{{count_qjzj}}</button>',
data() {
return {
count_qjzj: 1
};
},
});
// ----------局部组件----------
//需要定义在添加在Vue组件里
const jbzj = {
template:'<button v-on:click="count_jbzj++">局部组件:{{count_jbzj}}</button>',
data(){
return{
count_jbzj:1
}
}
}
var app = new Vue({
el: '#app',
//添加局部组件
components: {
"componet_1":jbzj
},
});
效果:
单文件组件
实际上就是把上面定义的一个一个组件,写成一个一个的.vue结尾的文件。
但是,.vue结尾的文件不能被浏览器成功解析,可采用vue提供的脚手架来完成单文件组件!
vue脚手架官网:https://cli.vuejs.org/zh/guide/
Vue脚手架如何安装,见后文。
先cd进入想要创建项目的目录,表示你的项目将要创建在这个目录下:
使用脚手架创建项目,执行vue create XXX
,其中XXX是指项目名。
使用上下键选择版本,这里,我选择Vue 2
这样,就帮你创建好了一个项目:
依次执行它给你的命令即可打开项目。
如果想把该项目放在其他目录下,直接剪切过去即可!此时启动该项目,也需要到指定的目录下执行上述命令。
生命周期钩子函数
-
beforeCreate:数据未加载,方法未加载,html模板未加载
-
created:数据已加载,方法已加载,html已加载,html未渲染(例如:{{msg}}没有被赋值)
-
beforeMount:挂载之前:html未渲染
-
mount:html已经渲染
-
beforeUpdate:数据已经更新,html未更新
-
updates:数据和html模板都更新
模块化开发
npm
常用命令
一定要--sava
,否则依赖中没有,只是下载
配置阿里云镜像
npm config set registry https://registry.npmmirror.com/
之后可以使用cnpm
替代npm
安装webpack、vue脚手架
npm config set registry https://registry.npm.taobao.org
配置淘宝镜像(不知道是否配置,可再配置一遍!)npm install webpack -g
全局安装webpack,可在cmd命令窗口运行
npm install -g @vue/cli
(请先配置淘宝镜像,否则可能慢死)
全局安装vue脚手架,默认是安装最新版本。
如果始终提示你安装的2.x版本的,可能是因为你为2.x版本的脚手架配置了环境变量,在环境变量中删除即可
如果安装2.x版本的vue脚手架,可使用命令:
npm install -g @vue/cli-init
,可能遇到报错:‘vue‘ 不是内部或外部命令,也不是可运行的程序或批处理文件
,可参考本文最后的附录。
初始化项目
使用vue -V
查看脚手架版本。
如果脚手架是2.x版本的:
- cd进入到想要创建项目的目录
- 运行:
vue init webpack appname
(注: appname为项目名,替换为自己的,例如:vue-demo;)
初始化vue项目;vue脚手架使用wevpack模板初始化一个appname项目
后面有两条启动命令:
如果脚手架是3.x及以上版本的:
- 使用命令
vue create 项目名
来初始化项目,项目vue的版本可以选2.x版本的。具体,可参考官网:https://cli.vuejs.org/zh/guide/creating-a-project
启动:
访问这个网址:
得到如下页面:
整合element
安装
两种方式:
- npm 安装:
推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用。
npm i element-ui -S
- CDN
目前可以通过 unpkg.com/element-ui 获取到最新版本的资源,在页面上引入 js 和 css 文件即可开始使用。<!-- 引入样式 --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> <!-- 引入组件库 --> <script src="https://unpkg.com/element-ui/lib/index.js"></script>
引入
在 main.js 中写入以下内容:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
然后使用它:
Vue.use(ElementUI)
其他常用组件库
移动端常用U组件库
- Vant: https://youzan.github.io/vant
- Cube Ul: https://didi.github.io/cube-ui
- Mint Ul: http://mint-ui.github.io
PC端常用U组件库
- Element Ul: https://element.eleme.cn
- lView Ul: https://www.iviewui.com
附录
生成vue模板
文件 ➡ 首选项 ➡ 用户片段 ➡ 点击新建全局代码片段文件… ➡ 取个名字 ➡ 注释或者删除原来的内容,复制下面的任意一个内容 ➡ ctrl + s保存
- vue
{
"生成vue模板": {
"prefix": "vue",
"body": [
"<!-- $1 -->",
"<template>",
"<div class='$2'>$5</div>",
"</template>",
"",
"<script>",
"//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)",
"//例如:import 《组件名称》 from '《组件路径》';",
"",
"export default {",
"//import引入的组件需要注入到对象中才能使用",
"components: {},",
"data() {",
"//这里存放数据",
"return {",
"",
"};",
"},",
"//监听属性 类似于data概念",
"computed: {},",
"//监控data中的数据变化",
"watch: {},",
"//方法集合",
"methods: {",
"",
"},",
"//生命周期 - 创建完成(可以访问当前this实例)",
"created() {",
"",
"},",
"//生命周期 - 挂载完成(可以访问DOM元素)",
"mounted() {",
"",
"},",
"beforeCreate() {}, //生命周期 - 创建之前",
"beforeMount() {}, //生命周期 - 挂载之前",
"beforeUpdate() {}, //生命周期 - 更新之前",
"updated() {}, //生命周期 - 更新之后",
"beforeDestroy() {}, //生命周期 - 销毁之前",
"destroyed() {}, //生命周期 - 销毁完成",
"activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发",
"}",
"</script>",
"<style scoped>",
"$4",
"</style>"
],
"description": "生成vue模板"
}
}
- vue、HTTP GET、HTTP POST
{
"生成vue模板": {
"prefix": "vue",
"body": [
"<!-- $1 -->",
"<template>",
"<div class='$2'>$5</div>",
"</template>",
"",
"<script>",
"//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)",
"//例如:import 《组件名称》 from '《组件路径》';",
"",
"export default {",
"//import引入的组件需要注入到对象中才能使用",
"components: {},",
"data() {",
"//这里存放数据",
"return {",
"",
"};",
"},",
"//监听属性 类似于data概念",
"computed: {},",
"//监控data中的数据变化",
"watch: {},",
"//方法集合",
"methods: {",
"",
"},",
"//生命周期 - 创建完成(可以访问当前this实例)",
"created() {",
"",
"},",
"//生命周期 - 挂载完成(可以访问DOM元素)",
"mounted() {",
"",
"},",
"beforeCreate() {}, //生命周期 - 创建之前",
"beforeMount() {}, //生命周期 - 挂载之前",
"beforeUpdate() {}, //生命周期 - 更新之前",
"updated() {}, //生命周期 - 更新之后",
"beforeDestroy() {}, //生命周期 - 销毁之前",
"destroyed() {}, //生命周期 - 销毁完成",
"activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发",
"}",
"</script>",
"<style scoped>",
"$4",
"</style>"
],
"description": "生成vue模板"
},
"http-get请求": {
"prefix": "httpget",
"body": [
"this.\\$http({",
"url: this.\\$http.adornUrl(''),",
"method: 'get',",
"params: this.\\$http.adornParams({})",
"}).then(({ data }) => {",
"})"
],
"description": "httpGET请求"
},
"http-post请求": {
"prefix": "httppost",
"body": [
"this.\\$http({",
"url: this.\\$http.adornUrl(''),",
"method: 'post',",
"data: this.\\$http.adornData(data, false)",
"}).then(({ data }) => { });"
],
"description": "httpPOST请求"
}
}
解决:‘vue‘ 不是内部或外部命令,也不是可运行的程序或批处理文件
- 运行
vue -V
发现:(如果你能显示版本号,请忽略该部分)
npm config list
- 进入改目录,注:手动删除多余的"\"
- 进入到
.bin
目录
发现有vue.cmd
命令 - 复制该目录添加环境变量:
把刚刚的.bin
完整路径复制过来
- 再次
vue -V
发现可以了