全栈之前端
1、技术栈
技术栈介绍:前端主要是6部分
1、vscode:最好用的前端编程工具
2、es6:可理解为后端的jdk8新特性之类
3、node.js主要使用里面的npm
4、vue:前端框架
5、babel:javascript编译器。可以使用es最新的语法进行编程,而不用考虑浏览器兼容问题
6、webpack:打包前端项目工具
2、es6
#前端工程创建
1、文件->新建文件夹(es6)->打开文件夹
2、新建let.html
3、编写第一段前端代码
!+回车
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
4、let特性
跨域
<script>
// var 声明的变量往往会越域
// let 声明的变量有严格局部作用域
{
var a = 1;
let b = 2;
}
console.log(a); // 1
console.log(b); // ReferenceError: b is not defined
</script>
var声明的变量可以在代码块外使用。但是let声明在代码块外使用会报错
多行注释:alt+shift+a
声明变量
// var 可以声明多次
// let 只能声明一次
var m = 1
var m = 2
let n = 3
let n = 4
console.log(m) // 2
console.log(n) // Identifier 'n' has already been declared
live server插件安装之后保存vscode则页面不用每次打开
自己会更新页面内容
变量提升
// var 会变量提升
// let 不存在变量提升
console.log(x); // undefined
var x = 10;
console.log(y); //ReferenceError: y is not defined
let y = 20;
const
// 1. 声明之后不允许改变
// 2. 一但声明必须初始化,否则会报错
const a = 1;
a = 3; //Uncaught TypeError: Assignment to constant variable.
数组解构
以前
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let arr = [1,2,3];
let a = arr[0];
let b = arr[1];
let c = arr[2];
console.log(a,b,c);
</script>
</body>
</html>
现在
let arr = [1,2,3];
let [a,b,c] = arr;
console.log(a,b,c);
对象解构
以前
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
const name = person.name;
const age = person.age;
const language = person.language;
console.log(name,age,language);
现在:
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
const{name,age,language} = person
console.log(name,age,language);
const{name:abc,age,language} = person;
console.log(abc,age,language);
字符串扩展
let ss = `<div>
<span>hello world<span>
</div>`
console.log(ss);
字符串插入变量表达式
调用方法
function getSame(){
return `想说话`;
}
let info = `我是${name},今年${age + 20}了,我${getSame()}`;
console.log(info);
函数参数默认值传递
//在 ES6 以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
// 判断 b 是否为空,为空就给默认值 1
b = b || 1;
return a + b;
}
// 传一个参数
console.log(add(10));
//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
return a + b;
}
// 传一个参数
console.log(add2(10));
不定参数
function fun(...values) {
console.log(values.length)
}
fun(1, 2) //2
fun(1, 2, 3, 4) //4
箭头函数
一个参数:
// 箭头函数
//以前声明一个方法
// var print = function (obj) {
// console.log(obj);
// }
var print = obj => console.log(obj);
print("hello");
多个参数:
// 多个参数以前
var sum = function(a,b){
return a+b;
}
console.log(sum(1,2));
// 箭头函数
var sum2 = (a,b) => a+b;
console.log(sum2(20,30));
复杂方法体:
// 多个参数以前
var sum = function(a,b){
c = a+b
return a+c;
}
console.log(sum(1,2));
/* // 箭头函数
var sum2 = (a,b) => a+b;
console.log(sum2(20,30)); */
var sum3 = (a,b) => {
c = a+b;
return a+c;
}
console.log(sum3(10,20));
箭头函数结合解构表达式
//以前的方式:
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
function hello(person) {
console.log("hello," + person.name)
}
hello(person);
//箭头函数
const param = (param) => (console.log("hello,"+param.name));
param(person);
//箭头函数+解构
const param1 = ({name}) => (console.log("hello,"+name));
param1(person);
对象优化
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
}
console.log(Object.keys(person));//["name", "age", "language"]
console.log(Object.values(person));//["jack", 21, Array(3)]
console.log(Object.entries(person));//[Array(2), Array(2), Array(2)]
Object.keys获得对象的键
Object.values获得对象的值
Object.entries获得对象键值对
对象复制
Object.assgin方法
// 对象复制
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
//Object.assign 方法的第一个参数是目标对象,后面的参数都是源对象。
Object.assign(target, source1, source2);
console.log(target)//{a: 1, b: 2, c: 3}
声明对象简写
// 声明对象简写
const age = 23
const name = "张三"
// 传统
const person1 = { age: age, name: name }
console.log(person1)
// ES6:属性名和属性值变量名一样,可以省略
const person2 = { age, name }
console.log(person2) //{age: 23, name: "张三"}
对象的函数属性简写
let person = {
name: "jack",
// 以前:
eat: function (food) {
console.log(this.name + "在吃" + food);
},
// 箭头函数版:这里拿不到 this
eat2: food => console.log(person.name + "在吃" + food),
// 简写版:
eat3(food) {
console.log(this.name + "在吃" + food);
}
}
person.eat("apple");
person.eat2("banana");
person.eat3("pear");
简写版不用写function了
深拷贝
// 1、拷贝对象(深拷贝)
let person1 = { name: "Amy", age: 15 }
let someone = { ...person1 }
console.log(someone) //{name: "Amy", age: 15}
合并对象
// 2、合并对象
let age = { age: 15 }
let name = { name: "Amy" }
let person2 = { ...age, ...name } //如果两个对象的字段名重复,后面对象字段值会覆盖前面对象的字段值
console.log(person2) //{age: 15, name: "Amy"}
map和reduce方法
map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。
let arr = ['1', '20', '-5', '3'];
console.log(arr)
arr = arr.map(s => parseInt(s));
console.log(arr)
reduce():
语法:
arr.reduce(callback,[initialValue])
reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元
素,接受四个参数:
初始值(或者上一次回调函数的返回值),
当前元素值,
当前索引,
调用 reduce 的数组
const arr = [1,20,-5,3];
//没有初始值:
console.log(arr.reduce((a,b)=>a+b));//19
console.log(arr.reduce((a,b)=>a*b));//-300
//指定初始值:
console.log(arr.reduce((a,b)=>a+b,1));//20
console.log(arr.reduce((a,b)=>a*b,0));//-0
无初始值调用reduce方法则数组中所有元素从左到右进行函数运算
有初始值调用reduce方法则初始值与元素第一个值进行函数运算后,再从左到右进行函数运算
promise异步编排
user.json
{
"id": 1,
"name": "zhangsan"
}
user_corse_1.json
{
"id": 10,
"name": "chinese"
}
corse_score_10.json
{
"id": 100,
"score": 90
}
promise.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<script>
$.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);
}
});
</script>
</body>
</html>
但是这种嵌套方式太复杂
用企业进阶版封装
// promise异步处理
// 1、封装方法
let get = function(url,data){
return new Promise((resorve,reject) => {
$.ajax({
url:url,
data:data,
success:function(data){
resorve(data)
},
error:function(err){
reject(err)
}
})
})
}
// 2、发起请求
get(`mock/user.json`).then((data)=>{
// 1、获取用户信息
console.log("当前用户信息为:",data)
return get(`mock/user_corse_${data.id}.json`);
}).then((data) => {
// 2、获取课程信息
console.log("当前课程信息为:",data)
return get(`mock/corse_score_${data.id}.json`);
}).then((data) =>{
// 3、获取分数信息
console.log("当前分数信息为:",data)
}).catch(() => {
console.log("错误信息为:",err)
})
模块化
模块化就是把代码进行拆分,方便重复利用。类似 java 中的导包:要使用一个包,必须先
导包。而 JS 中没有包的概念,换来的是模块
user.js
var name = "jack"
var age = 21
export {name,age}
hello.js
export const util = {
sum(a, b) {
return a + b;
}
}
aaa.js
import util from `./hello.js`;
import {name,age} from `./user.js`;
console.log(name)
util.sum(1,2);
3、vue
https://v2.cn.vuejs.org/v2/guide/
根据官方文档学习vue2.0
1、新建一个文件夹
2、初始化项目
npm init -y
会生成一个
3、安装vue依赖
npm install vue@2
4、新建一个index.html测试
1、声明式渲染(new Vue({}))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<h1>{{name}},你好帅</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 1、vue的声明式渲染
let a1 = new Vue({
el: "#app",
data:{
name : '张三'
}
})
</script>
</body>
</html>
2、双向绑定 (v-model)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<h1>{{name}},你好帅,有{{num}}个人给他点赞</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 1、vue的声明式渲染
let a1 = new Vue({
el: "#app",
data:{
name : '张三',
num : 1
}
})
// 2、双向绑定,模型变化,视图变化
</script>
</body>
</html>
3、事件处理(v-on:)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<button v-on:click="num++">点赞</button>
<h1>{{name}},你好帅,有{{num}}个人给他点赞</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 1、vue的声明式渲染
let a1 = new Vue({
el: "#app",
data:{
name : '张三',
num : 1
}
})
// 2、双向绑定,模型变化,视图变化
// 3、事件处理
</script>
</body>
</html>
4、调用方法(methods)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="text" v-model="num">
<button v-on:click="num++">点赞</button>
<button v-on:click="cancel">取消</button>
<h1>{{name}},你好帅,有{{num}}个人给他点赞</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 1、vue的声明式渲染
let a1 = new Vue({
el: "#app",
data:{
name : '张三',
num : 1
},
methods:{
cancel(){
this.num--;
}
}
})
// 2、双向绑定,模型变化,视图变化
// 3、事件处理
// 4、调用方法
</script>
</body>
</html>
##可以装一个vue2的语法提示插件
##装一个浏览器插件
vue-devtool
5、指令
5.1、v-text v-html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id = 'app'>
{{msg}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'<h1>Hello</h1>'
}
})
</script>
</body>
</html>
<span v-html="msg"></span>
<span v-text="msg"></span>
v-html 和v-text与{{}}相比好处是:可以避免插值闪烁
5.2、插值表达式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id = 'app'>
{{msg}} {{1+11}} {{sayHello()}}<br/>
<span v-html="msg"></span>
<span v-text="msg"></span>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'<h1>Hello</h1>'
},
methods:{
sayHello(){
return 'hello';
}
}
})
</script>
</body>
</html>
###插值表达式只能写在标签体内。不能写在属性中
需要写到属性中必须使用v-bind
5.3、v-bind(单向绑定)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<a v-bind:href="link">gogogo</a>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
link:'http://www.baidu.com'
}
})
</script>
</body>
</html>
v-bind可以动态绑定class或者style
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id = 'app'>
<a v-bind:href="link">gogogo</a>
<span v-bind:class="{active:isActive,'text-danger':hasError}">你好</span>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data:{
link:'http://www.baidu.com',
isActive:true,
hasError:true
}
})
</script>
</body>
</html>
##以前的写法:
<span v-bind:class="{active:isActive,'text-danger':hasError}" style="color: red; font-size:90px">你好</span>
##绑定style写法
可以v-bind:style,也可以:style
5.4、v-model(双向绑定)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<input type="checkbox" v-model="check" value="Java">java <br/>
<input type="checkbox" v-model="check" value="PHP">php <br/>
<input type="checkbox" v-model="check" value="python">python <br/>
选中了
{{check.join(",")}}
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:'#app',
data:{
check:[]
}
})
</script>
</body>
</html>
5.5、事件修饰符
##阻止事件冒泡到父元素(click.stop)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!--事件中直接写js片段-->
<button v-on:click="num++">点赞</button>
<!--事件指定一个回调函数,必须是vue实例中的函数-->
<button v-on:click="cancel">取消</button>
<h1>有{{num}}个赞</h1>
<div style="border: 1px solid red;padding: 20px;" v-on:click="hello">
大div
<div style="border: 1px solid blue;padding: 20px;" @click="hello">
小div <br/>
<a href="https://www.baidu.com">去百度</a>
</div>
</div>
<!--按键修饰符:-->
<input type="text"><br/>
提示:
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
num:1
},
methods:{
cancel(){
return this.num--;
},
hello(){
alert("点击了");
}
}
})
</script>
</body>
</html>
点击小div会出现弹窗2次
加上click.stop以后
点击小div只弹窗一次
##阻止默认行为(@click.prevent)
点击小div中的去百度会先弹窗,再跳转去百度
@click.prevent
点击小div中的去百度会只弹窗,不跳转去百度。
@click.prevent=“hello”
点击小div中的去百度弹两次弹窗,不跳转去百度。
@click.prevent.stop=“hello”
点击小div中的去百度弹一次弹窗,不跳转去百度。
##只被点击一次(v-on:click.once)
v-on:click.once
只会被点击一次
5.6、按键修饰符
<input type="text" v-model="num" v-on:keyup.up="num+=2" @keyup.down="num-=2"><br/>
v-on:keyup.up :跟键盘上键绑定事件
@keyup.down:跟键盘下键绑定事件
@click.ctrl=“num=10” :绑定组合按键:ctrl+鼠标左键单击时触发num=10
5.7、v-for
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<ul>
<li v-for="user in users">
{{user.name}} ===> {{user.gender}} ===> {{user.age}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
users:[{
name:'柳岩',gender:'女',age:21},
{name:'张三',gender:'男',age:18},
{name:'范冰冰',gender:'女',age:24},
{name:'刘亦菲',gender:'女',age:18},
{name:'古力娜扎',gender:'女',age:25
}]
},
})
</script>
</body>
</html>
遍历:
遍历下标
遍历span
对一般数组的遍历:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='app'>
<ul>
<li v-for="(user,index) in users">
当前下标:{{index}} {{user.name}} ===> {{user.gender}} ===> {{user.age}}
<br/>
对象信息:
<span v-for="(v,k,i) in user">
{{k}} ===> {{v}} ===> {{i}}
</span>
</li>
</ul>
<ul>
<li v-for="(num,index) in nums" :key="index">
{{num}} ===> {{index}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
users:[{
name:'柳岩',gender:'女',age:21},
{name:'张三',gender:'男',age:18},
{name:'范冰冰',gender:'女',age:24},
{name:'刘亦菲',gender:'女',age:18},
{name:'古力娜扎',gender:'女',age:25
}],
nums:[1,2,3,4,4]
},
})
</script>
</body>
</html>
5.8、v-if v-show
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button @click="show = !show">点我呀</button>
<h1 v-if="show"> if=看到我</h1>
<h1 v-show="show"> show=看到我</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el : '#app',
data : {
show : true
}
})
</script>
</body>
</html>
==》
v-if整个标签消失了
v-show是加了隐藏的样式
5.9、v-else,v-else-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<button v-on:click="random = Math.random()">点我啊</button>
<span>{{random}}</span>
<h1 v-if="random >= 0.75">
>=0.75
</h1>
<h1 v-else-if="random >= 0.5">
>=0.5
</h1>
<h1 v-else-if="random >= 0.2">
>=0.2
</h1>
<h1 v-else="randow < 0.2">
<0.2
</h1>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el : '#app',
data : {
random : 1
}
})
</script>
</body>
</html>
5.10 v-if和v-for结合使用
过滤掉了张三男
6、计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!--某些结果是基于之前数据实时计算结果出来的,我们可以利用计算属性-->
<ul>
<li>西游记:价格:{{xyjPrice}} 数量:<input type="number" v-model="xyjNum"></li>
<li>水浒传:价格:{{sfzPrice}} 数量:<input type="number" v-model="sfzNum"></li>
<li>总价:{{totalPrice}}</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data : {
xyjPrice: 99.9,
sfzPrice: 98,
xyjNum:1,
sfzNum:1
},
// 计算属性
computed:{
totalPrice(){
return this.xyjPrice * this.xyjNum + this.sfzPrice * this.sfzNum
}
}
})
</script>
</body>
</html>
7、监听器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<!--某些结果是基于之前数据实时计算结果出来的,我们可以利用计算属性-->
<ul>
<li>西游记:价格:{{xyjPrice}} 数量:<input type="number" v-model="xyjNum"></li>
<li>水浒传:价格:{{sfzPrice}} 数量:<input type="number" v-model="sfzNum"></li>
<li>总价:{{totalPrice}}</li>
{{msg}}
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data : {
xyjPrice: 99.9,
sfzPrice: 98,
xyjNum:1,
sfzNum:1,
msg:""
},
// 计算属性
computed:{
totalPrice(){
return this.xyjPrice * this.xyjNum + this.sfzPrice * this.sfzNum
}
},
// 监听器
watch:{
xyjNum(newNum,oldNum){
// alert("newNum:"+newNum+"===>oldNum"+oldNum);
if (newNum >= 3){
this.msg= "超出库存";
this.xyjNum = 3;
}else{
this.msg = ""
}
}
}
})
</script>
</body>
</html>
8、过滤器
8.1、局部过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="user in userList">
{{user.id}}===>{{user.name}}===>{{user.gender == 1 ? '男' : '女'}} ===>{{user.gender | genderFilter}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el : '#app',
data:{
userList:[
{id:1,name:'zhangsan',gender:'1'},
{id:2,name:'lisi',gender:'2'}
]
},
filters:{
genderFilter(val){
if (val == 1){
return '男';
}else{
return '女';
}
}
}
})
</script>
</body>
</html>
8.2、全局过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="user in userList">
{{user.id}}===>{{user.name}}===>{{user.gender == 1 ? '男' : '女'}} ===>{{user.gender | genderFilter}}
===> {{user.gender | gFilter}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 全局filter
Vue.filter('gFilter', function (val) {
if (val == 1) {
return '男···';
} else {
return '女···';
}
})
new Vue({
el: '#app',
data: {
userList: [
{ id: 1, name: 'zhangsan', gender: '1' },
{ id: 2, name: 'lisi', gender: '2' }
]
},
filters: {
genderFilter(val) {
if (val == 1) {
return '男';
} else {
return '女';
}
}
}
})
</script>
</body>
</html>
9、组件化
9.1、全局申明组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id = 'app'>
<button @click="count++">我被点击了{{count}}次</button>
<counter></counter>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 全局申明组件
Vue.component("counter",{
template: `<button v-on:click="count++">我被点击了{{count}}次</button>`,
data(){
return{
count: 1
}
}
})
new Vue({
el : '#app',
data:{
count: 1
}
})
</script>
</body>
</html>
9.2、局部申明组件
// 局部申明组件
const buttonCounter = {
template: `<button v-on:click="count++">我被点击了{{count}}次~~~~</button>`,
data(){
return{
count: 1
}
}
}
new Vue({
el : '#app',
data:{
count: 1
},
components:{
'button-counter':buttonCounter
}
})
<div id = 'app'>
<button @click="count++">我被点击了{{count}}次</button>
<counter></counter>
<button-counter></button-counter>
</div>
10、生命周期和钩子函数
每个 Vue 实例在被创建时都要经过一系列的初始化过程 :创建实例,装载模板,渲染模
板等等。Vue 为生命周期中的每个状态都设置了钩子函数(监听函数)。每当 Vue 实例处于
不同的生命周期时,对应的函数就会被触发调用。
生命周期:你不需要立马弄明白所有的东西。
##钩子函数
beforeCreated:我们在用 Vue 时都要进行实例化,因此,该函数就是在 Vue 实例化时调
用,也可以将他理解为初始化函数比较方便一点,在 Vue1.0 时,这个函数的名字就是
init。
created:在创建实例之后进行调用。
beforeMount:页面加载完成,没有渲染。如:此时页面还是{{name}}
mounted:我们可以将他理解为原生 js 中的 window.οnlοad=function({.,.}),或许大家也在
用 jquery,所以也可以理解为 jquery 中的$(document).ready(function(){….}),他的功能就
是:在 dom 文档渲染完毕之后将要执行的函数,该函数在 Vue1.0 版本中名字为
compiled。 此时页面中的{{name}}已被渲染成张三
beforeDestroy:该函数将在销毁实例前进行调用 。
destroyed:改函数将在销毁实例时进行调用。
beforeUpdate:组件更新之前。
updated:组件更新之后。
<!DOCTYPE html>
<div lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
<span id="num">{{num}}</span>
<button v-on:click="num++">赞!</button>
<h2>
{{name}},非常帅!!!有{{num}}个人点赞。
</h2>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
name: "张三",
num: 100
},
methods: {
show() {
return this.name;
},
add() {
this.num++;
}
},
beforeCreate() {
console.log("=========beforeCreate=============");
console.log("数据模型未加载:" + this.name, this.num);
console.log("方法未加载:" + this.show());
console.log("html 模板未加载:" + document.getElementById("num"));
},
created: function () {
console.log("=========created=============");
console.log("数据模型已加载:" + this.name, this.num);
console.log("方法已加载:" + this.show());
console.log("html 模板已加载:" + document.getElementById("num"));
console.log("html 模板未渲染:" + document.getElementById("num").innerText);
},
beforeMount() {
console.log("=========beforeMount=============");
console.log("html 模板未渲染:" + document.getElementById("num").innerText);
},
mounted() {
console.log("=========mounted=============");
console.log("html 模板已渲染:" + document.getElementById("num").innerText);
},
beforeUpdate() {
console.log("=========beforeUpdate=============");
console.log("数据模型已更新:" + this.num);
console.log("html 模板未更新:" + document.getElementById("num").innerText);
},
updated() {
console.log("=========updated=============");
console.log("数据模型已更新:" + this.num);
console.log("html 模板已更新:" + document.getElementById("num").innerText);
}
});
</script>
</body>
</html>
#第一阶段:beforeCreate
#第二阶段:created
#第三阶段:beforeMount
#第四阶段:mounted
点击页面元素更新时:
#第一阶段:beforeUpdate
#第二阶段:updated
11、vue脚手架
#vue模块化开发
1、全局安装 webpack
npm install webpack -g
2、安装vue脚手架
npm install -g @vue/cli-init
3、初始化vue
创建一个vue-demo文件夹
执行vue init webpack vue-demo
#如果执行vue报错时
再执行以下命令即可
npm install -g vue
npm uninstall vue-cli -g
npm install -g @vue/cli
确定
确定
确定
选择第一个
是否做页面跳转:yes
是否eslint语法规范检查:no
是否单元测试:no
是否使用这个e2e单元测试:no
选择第一个
这样模块化环境就初始好了
启动项目
cd vue-demo
npm run dev
index.js
路由:当我路径为/时使用HelloWorld组件
##要求:自己编写组件然后跳转/hello路径如何实现?
1、编写组件
2、组件三要素
template、script、style
模板,脚本、风格
Hello.vue
<template>
<div>
<h1>你好,{{name}}</h1>
</div>
</template>
<script>
export default {
data () {
return {
name: '张三'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hello from '@/components/Hello'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path:'/hello',
name:'Hello',
component:Hello
}
]
})
##通过超链接跳转两个页面
App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
<router-link to="/">去首页</router-link>
<router-link to="/hello">去hello</router-link>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
12、vue整合ElementUI快速开发
1、安装elementUI
npm i element-ui
如果vue版本过高无法安装elementui,甚至报错可以尝试
npm i element-ui -S --legacy-peer-deps
2、使用elementUI
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
3、elementUI单选框
4、官方文档Container 布局容器
App.vue
<template>
<el-container style="height: 500px; border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>导航一</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-menu"></i>导航二</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="2-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="3">
<template slot="title"><i class="el-icon-setting"></i>导航三</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="3-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="3-4">
<template slot="title">选项4</template>
<el-menu-item index="3-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropdown-item>
<el-dropdown-item>新增</el-dropdown-item>
<el-dropdown-item>删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>王小虎</span>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140">
</el-table-column>
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
data() {
const item = {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
};
return {
tableData: Array(20).fill(item)
}
}
};
</script>
<style>
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
##需求:对分组一的布局进行调整,根据页面url访问路径不同,main区域显示:点击用户列表显示相关内容
1、app.vue
2、将el-table抽取
<router-view></router-view>
<!--<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140">
</el-table-column>
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
-->
3、新建组件
##使用代码片段生成vue文件
代码片段:
{
"生成 vue 模板": {
"prefix": "vue",
"body": [
"<template>",
"<div></div>",
"</template>",
"",
"<script>",
"//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)",
"//例如:import 《组件名称》 from '《组件路径》';",
"",
"export default {",
"//import 引入的组件需要注入到对象中才能使用",
"components: {},",
"props: {},",
"data() {",
"//这里存放数据",
"return {",
"",
"};",
"},",
"//计算属性 类似于 data 概念",
"computed: {},",
"//监控 data 中的数据变化",
"watch: {},",
"//方法集合",
"methods: {",
"",
"},",
"//生命周期 - 创建完成(可以访问当前 this 实例)",
"created() {",
"",
"},",
"//生命周期 - 挂载完成(可以访问 DOM 元素)",
"mounted() {",
"",
"},",
"beforeCreate() {}, //生命周期 - 创建之前",
"beforeMount() {}, //生命周期 - 挂载之前",
"beforeUpdate() {}, //生命周期 - 更新之前",
"updated() {}, //生命周期 - 更新之后",
"beforeDestroy() {}, //生命周期 - 销毁之前",
"destroyed() {}, //生命周期 - 销毁完成",
"activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发",
"}",
"</script>",
"<style scoped>",
"</style>"
],
"description": "生成 vue 模板"
}
}
#文件->首选项->配置用户代码片段->新建全局代码片段
#新建全局代码片段vue,回车
#将代码片段粘贴过来
#直接在vue文件中输入vue可以立马生成模板
MyTable.vue
<template>
<div></div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
//import 引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
//这里存放数据
return {
};
},
//计算属性 类似于 data 概念
computed: {},
//监控 data 中的数据变化
watch: {},
//方法集合
methods: {
},
//生命周期 - 创建完成(可以访问当前 this 实例)
created() {
},
//生命周期 - 挂载完成(可以访问 DOM 元素)
mounted() {
},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发
}
</script>
<style lang='scss' scoped>
//@import url(); 引入公共 css 类
</style>
4、将vue.app里的用户信息粘贴到myTable.vue里
MyTable.vue
<template>
<div>
<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140"> </el-table-column>
<el-table-column prop="name" label="姓名" width="120"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
//import 引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
const item = {
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
};
return {
tableData: Array(20).fill(item),
};
},
//计算属性 类似于 data 概念
computed: {},
//监控 data 中的数据变化
watch: {},
//方法集合
methods: {},
//生命周期 - 创建完成(可以访问当前 this 实例)
created() {},
//生命周期 - 挂载完成(可以访问 DOM 元素)
mounted() {},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发
};
</script>
<style lang='scss' scoped>
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
5、index.js配置路由
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hello from '@/components/Hello'
import MyTable from '@/components/MyTable'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path:'/hello',
name:'Hello',
component:Hello
},
{
path:'/table',
name:'MyTable',
component:MyTable
}
]
})
6、对App.vue进行调整
##1、el-menu router属性调整为true
##2、修改跳转路径
这里点击hello就会跳hello
点击用户列表会跳用户列表