1. 前端的发展史
1. HTML(5) CSS(3) JavaScript(ES5ES6): 编写一个个的页面 -> 给后端(Python) ->
后端嵌入模板语法 -> 后端渲染完数据 -> 返回数据给前端 -> 在浏览器中查看
2. Ajax的出现 -> 后台发送异步请求, Render+Ajax混合
3. 单用Ajax(加载数据, DOM渲染页面): 前后端分离的雏形
4. Angular框架的出现(JS的框架): 出现了前端工程化的概念(前端也是1个工程或1个项目)
5. React Vue: 当下最火的2个前端框架(Vue:国人喜欢用, React:外国人喜欢用)
6. 移动开发(Android+IOS) + Web(Web+微信小程序+支付宝小程序) + 桌面开发(Windows桌面):前端 -> 大前端
7. 一套代码在各个平台运行(大前端): 谷歌Flutter(Dart语言:和Java很像)可以运行在IOS Android PC端
8. uni-app(在Vue框架的基础性上): 一套编码 编到10个平台
详细的发展史:
https://zhuanlan.zhihu.com/p/337276087?utm_source=wechat_session&utm_medium=social&utm_oi=41967790587904
2. js/node.js
js 与 node.js
js: 就是一门解释型语言, 解释型的语言是需要解释器的, 只不过js解释器被集成到了浏览器中
node.js 一门后端语言把chrome的v8引擎(解释器), 安装到操作系统之上
js解释器在浏览器的开发者工具中
node.js 需要下载安装到本地系统中
2.1 es6新特性
1. 模板语法
模板语法的使用
var name = 'kid'
console.log(`我的名字叫${name}`)
2. 箭头函数
箭头函数, 没有自己的this
var 函数名 =('参数')=>{函数体}
var f = () => { console.log('hello word!') }
f()
var f = (text) => { console.log(text) }
f('hello word!')
var 函数名 =参数=>{函数体} (一个参数时可以不省略括号)
var f = text=> { console.log(text) }
f('hello word!')
var 函数名 =参数=> 函数体 (函数体只有一句代码)
var f =()=>console.log('hello word!')
f()
var 函数名 =参数=> 参数 (直接返回参数的话可以这样下)
var f = text=> text
var str = f('hello')
console.log(str) // hello
3. 对象的定义
自定义对象的写法key可以加'', 也可以不加'':
var name = 'kid'
var age = 18
var obj = {'name': name, 'age': age}
console.log(obj)
var obj = {name: name, age: age}
console.log(obj)
var obj = {f: function(){console.log('xx')}}
obj.f()
新特性, 将变量名作为key, 变量值作为value
var obj = {name, age}
console.log(obj)
var obj = {f(){console.log('xx')}}
obj.f()
2.2 遍历/循环取值
1. 基于索引循环
var array1 = [1, 2, 3, 4]
for(let i=0; i<array1.length; i++){
console.log(array1[i])
}
结果:
1
2
3
4
2. 迭代in
var array1 = [1, 2, 3, 4]
for (i in array1){console.log(array1[i])}
结果:
1
2
3
4
var obj = {name: 'kid', age: 18, gender: 'male'}
for(key in obj){
console.log(key)
}
结果:
name
age
gender
3. 迭代of
对象无法使用
var array1 = [1, 2, 3, 4]
for (i of array1){console.log(i)}
结果:
1
2
3
4
4. 数组迭代方法
var array1 = [1, 2, 3, 4]
array1.forEach(function(value, index){
console.log(value, array1[index])
})
array1.forEach(a=(value, index)=>{
console.log(value, array1[index])
})
结果:
1 1
2 2
3 3
4 4
3. Vue介绍
Vue是js的一个框架.
Vue: 读音/vjuː/, 类似于view, 是一套用于构建用户界面的渐进式框架.
与其它大型框架不同的是, Vue被设计为可以自底向上逐层应用.
Vue的核心库只关注视图层, 不仅易于上手, 还便于与第三方库或既有项目整合.
渐进式框架: 可以一点一点地使用它, 只用一部分, 也可以整个工程都使用它.
官网: https://cn.vuejs.org/
文档: https://cn.vuejs.org/v2/guide/
版本:
1.X:使用得较少
2.X:普遍使用
3.X:刚出没多久, 只有Beta版
4. M-V-VM思想
MVVM 是Model-View-ViewModel的缩写, 它是一种基于前端开发的架构模式, 是一种事件驱动编程方式.
Model : vue对象的data属性的数据, 这里的数据要显示到页面中.
View : vue中数据要显示的HTML页面, 在vue中, 也称之为视图模板(HTML+CSS).
ViewModel: vue中编写代码时的vm对象, 它是vue.js的核心, 负责连接 View 和 Model数据的中转, 保证视图和数据的一致性.
代码中, data里面的数据与显示在标签中值以是一种双向数据绑定关系.
双向数据绑定: JS中变量变了, HTML中数据也跟着改变, HTML中数据改变, JS中变量也跟着改变.
这个操作是vm对象自动完成的.
5. 组件化开发/单页面开发
5.1 组件化开发
类似与Django中使用的DTL模板语言的include机制,每一个组件的内容都可以被替换和复用.
整个页面是一个组件, 页面中可划分多个小组件, 小组件中还可以使用组件.
5.2 单页面开发
只需要1个页面, 结合组件化开发来替换页面中的内容.
页面的切换只是组件的替换, 页面还是只有1个index.html文件.
6. Vue引入方式
6.1 CDN引入
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
<script src="https://cdn.jsdelivr.net/npm/vue@2">script>
6.2 文件引用
浏览器中打开cnd提供的地址 https://cdn.jsdelivr.net/npm/vue/dist/vue.js, 看到vue.js的所有代码
然后Ctrl+a全选, Ctrl+v复制, 在本地电脑上新建一个vue.js文件, 将复制的代码粘贴到改文件中.
<script src="文件存放地址"></script>
6.3 本地文件引用提示问题
将文件放在js下, 名字是小写的vue.js.
7. 声明式渲染
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统.
声明变量:
在引入Vue之后, 页面就有了一个Vue函数.
js 定义对象需要加上关键字 new.
定义对象时传入参数,
el: 元素, 指定data中变量作用的标签,
data: 数据, 定义变量,
methods: 方法, 定义函数.
var app3 = new Vue({参数..}) 得到一个ViewModel对象
模板语法插值语法: {{变量名}}
使用变量: 在el指定的标签中使用插值语法使用变量.
7.1 简单使用
* 1. 新建一个Python项目, 在项目下新建一个html文件
* 2. 引用vue文件, 写入测试代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>声明式渲染title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
head>
<body>
<div id="app">
{{ message }}
{{ func()}}
div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello word!'
},
methods: {
func() {
console.log('hello word!')
}
}
})
script>
body>
html>
7.2 数据的双向绑定
双向数据绑定: JS中变量变了, HTML中数据也跟着改变, HTML中数据改变, JS中变量也跟着改变.
这个操作是vm对象自动完成的.
v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定, 后面详细说.
vm对象._data 获取data属性, data属性的值是一个自定义对象.
vm对象._data['属性'] 或 vm对象._data.属性 获取自定义对象中的属性值.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插值语法title>
<script src="Vue.js">script>
head>
<body>
<div id="app">
<input type="text" v-model="str">
<p>input中输入的值:{{str}}p>
div>
<script>
var app = new Vue({
el: '#app',
data: {
str: ''
}
})
script>
body>
html>
8. 模板语法
8.1 插值语法
插值是在标签内使用的, 值可以是一个变量, 也可是是一个函数.
<xx> {{变量}} </xx>
插值语法中可以简单的使用js的代码.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>插值语法title>
<script src="Vue.js">script>
head>
<body>
<div id="app">
<ul>
<li>{{ num }}li>
<li>{{ str }}li>
<li>{{ array1[0] }}li>
<li>{{ obj.name }}li>
<li>数学运算:{{ 1 + 2 }}li>
<li>三目运算符: {{ 10 > 20 ? '是' : '否' }}li>
ul>
div>
<script>
var app = new Vue({
el: '#app',
data: {
num: 11,
str: 'hello word!',
array1: [1, 2, 3],
obj: {'name': 'kid'}
}
})
script>
body>
html>
8.2 文本指令
指令 |
释义 |
v-html |
让HTML渲染成页面(可以渲染字符中的html代码) |
v-text |
标签内容显示js变量对应的值(不可以渲染字符中的html代码, 原样展示字符串) |
v-show |
放1个布尔值:为真 标签就显示.为假 标签就不显示(使用display:none, 标签存在, 占位子, 不显示) |
v-if |
放1个布尔值:为真 标签就显示.为假 标签就不显示(直接操作DOM,删除/插入 标签) |
1. 显示值
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue的简单使用title>
<script src="Vue.js">script>
head>
<body>
<div id="div">
<ul>
<li v-html="link">li>
<li v-text="link">li>
ul>
div>
<script>
var app = new Vue({
el: '#div',
data: {
link: '百度一下 你就知道'
}
})
script>
body>
html>
2.隐藏标签
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue的简单使用title>
<script src="Vue.js">script>
head>
<body>
<div id="div">
<ul>
<li v-show="is_show">123li>
<li v-if="is_if">456li>
ul>
div>
<script>
var app = new Vue({
el: '#div',
data: {
is_show: false,
is_if: false,
}
})
script>
body>
html>
8.3 事件指令
指令 |
释义 |
v-on |
触发事件(不推荐) |
@ |
触发事件(推荐 v-on: 简写–> @) |
@[event] |
触发event事件(可以是其他任意事件) |
Event 对象代表事件的状态, 比如事件在其中发生的元素, 键盘按键的状态, 鼠标的位置, 鼠标按钮的状态.
在实例ViewModel对象时, 为methods参数提供一个函数. 在函数中写事假触发之后执行的代码!
在methods中写的第一层函数不需要写function关键字.
1.触发实践(不带参数)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击事假(函数不带参数)title>
<script src="Vue.js">script>
head>
<body>
<div id="div">
<button v-on:click="handleClick1">按键1button>
<button @click="handleClick1">按键2button>
div>
<script>
var app = new Vue({
el: '#div',
methods: {
handleClick1() {
console.log('点击事件1')
}
}
})
script>
body>
html>
两个按键都可以触发点击事件.
2.触发实践(带参数)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>点击事假(函数带参数)title>
<script src="Vue.js">script>
head>
<body>
<div id="div">
<button @click="handleClick1(1, 2)">计算1+2button>
div>
<script>
var app = new Vue({
el: '#div',
methods: {
handleClick1(x, y) {
console.log(x + y)
}
}
})
script>
body>
html>
3.this参数
在Vue对象中methods中定义的第一层函数使用this, 代指的是Vue对象.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue的简单使用title>
<script src="Vue.js">script>
head>
<body>
<div id="div">
<button @click="handleClick">按键button>
<p v-show="is_show">点击按键, 看这一行的变化!p>
div>
<script>
var app = new Vue({
el: '#div',
data: {
is_show: true
},
methods: {
handleClick() {
this.is_show = !this.is_show
}
}
})
script>
body>
html>
8.4 属性指令
属性指令: 是给标签的属性设置值时使用的.
属性指令中可以使用简单js代码, eg: 三目运算符...
指令 |
释义 |
v-bind |
直接写js的变量或语法(不推荐) |
: |
直接写js的变量或语法(推荐) |
v-bind:class='js变量'可以缩写成::class='js变量'
1. 使用实例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>属性指令title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<img v-bind:src="url" alt="百度.png" height="100">
<img :src="url" alt="百度.png" height="100">
div>
<script>
var app = new Vue({
el: '#d1',
data: {
url: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=205441424,1768829584&fm=26&gp=0.jpg'
}
})
script>
body>
html>
2. 属性切换实例
定义两个样式, 通过按键切换样式.
:class="is_true? 'red' : 'orange' "
is_true为真 class='red'
is_true为假 class='orange'
* "变量" --> 得到的值需要是一个字符串, class="". 下节详情说明!
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>属性指令title>
<script src="Vue.js">script>
<style>
.red {
background-color: red;
}
.orange {
background-color: orange;
}
style>
head>
<body>
<div id="d1">
<button @click="ClickEvent">换颜色button>
<div style="width: 100px; height: 100px;" :class="is_true?'red':'orange'">div>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
is_true: true,
},
methods: {
ClickEvent(){
this.is_true = !this.is_true
}
}
})
script>
body>
html>
9. Class 与 Style 样式操作
:属性名="js变量"
:class= "js变量"-->得到的值 字符串 / 数组 /对象{red: true}
:style= "js变量"-->得到的值 字符串 / 数组[{color: 'red'},] / 对象{color: 'red'}
推荐使用对象, 对象可以指定需要的开关的属性, 数组无法指定元素名删除 , 所有不方便, 字符串更加难添加删除值.
9. 1 Class
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>classtitle>
<script src="Vue.js">script>
<style>
.color {
color: orange;
}
.red {
background-color: red;
}
.font {
font-size: 60px;
}
style>
head>
<body>
<div id="d1">
<p :class="Attributes1">p1p>
<p :class="Attributes2">p2p>
<p :class="Attributes3">p3p>
<p>p2的操作按键: p>
<p>
<button @click="DelColor">去掉字体颜色button>
<button @click="DelRed">去掉背景颜色button>
<button @click="DelFont">去掉字体设置button>
p>
<p>
<button @click="AddColor">字体颜色button>
<button @click="AddRed">背景颜色button>
<button @click="AddFont">字体设置button>
p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
Attributes1: 'color red font',
Attributes2: ['color', 'red', 'font'],
Attributes3: {'color': true, 'red': true, 'font': true}
},
methods:{
DelColor(){
this.Attributes3.color = false
},
DelRed(){
this.Attributes3.red = false
},
DelFont(){
this.Attributes3.font = false
},
AddColor(){
this.Attributes3.color = true
},
AddRed(){
this.Attributes3.red = true
},
AddFont(){
this.Attributes3.font = true
}
}
})
script>
body>
html>
9.2 style
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>classtitle>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<p :style="Attributes1">p1p>
<p :style="Attributes2">p2p>
<p :style="Attributes3">p3p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
Attributes1: 'color: orange; background: red; font-size: 60px;',
Attributes2: [{color: 'orange'}, {background: 'red'}, {fontSize: '60px'}],
Attributes3: {color: 'orange', background: 'red', fontSize: '60px'}
}
})
script>
body>
html>
10. 条件渲染
指令 |
释义 |
v-if |
相当于: if |
v-else |
相当于:else |
v-else-if |
相当于:else if |
条件渲染在标签属性中使用, 当满足条件时才渲染标签.
v-if="条件"
10.1 实例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if判断title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<p>你的成绩是{{num}}, 评价为:
<span v-if="num >= 86">优秀span>
<span v-else-if="num >= 60">良好span>
<span v-else-if="num < 60">不及格span>
<span v-else>成绩录入值无法判断span>
p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
num: 'a'
},
})
script>
body>
html>
num的值为90: 你的成绩是90, 评价为: 优秀
num的值为80: 你的成绩是80, 评价为: 良好
num的值为59: 你的成绩是59, 评价为: 不及格
num的值为a: 你的成绩是a, 评价为: 成绩录入值无法判断
11. v-for遍历
v=for=" i in 可遍历的对象" 取一个值
v=for=" (x, y) in 可遍历的对象" 取两个值
11.1 遍历数字
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for遍历值title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<span v-for="i in num">{{i}}span>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
num: 5
}
})
script>
body>
html>
11.2 遍历字符串
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for遍历值title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<span v-for="i in str">{{i}}span>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
str: 'hello'
}
})
script>
body>
html>
11.3 遍历数组
取值:
v=for="i in 可遍历的对象"
取值和索引:
v=for=" (值, 索引) in 可遍历的对象" 值前, 索引后
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for遍历值title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<p v-for="(i, index) in array1">值:{{i}} 索引:{{index}}p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
array1: [1, 2, 3, 4, 5]
}
})
script>
body>
html>
在v-for循环数组对象时, 建议在控件/组件/标签写1个:key属性, 属性值唯一即可.
页面更新之后, 会加速DOM的替换(渲染)
:key="变量"
:key值 的解释
vue中使用的是虚拟DOM, 会和原生的DOM进行比较, 然后进行数据的更新, 提高数据的刷新速度(虚拟DOM用了diff算法)
不加:key时, 修改数组时会重新对整个数组重新渲染.
加:key时, 修改数组时只对修改部分重新渲染, 所以效率高.
11.4 遍历对象
取值:
v=for="i in 可遍历的对象"
取和键:
v=for=" (值, 键) in 可遍历的对象" 值前, 键后
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for遍历值title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<p v-for="(value, key) in obj">值:{{value}} 键:{{key}}p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
obj: {'name': 'kid', 'age': 18}
}
})
script>
body>
html>
11.5 数组套对象
先从数组中取出对象, 对象.属性取值.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>v-for遍历值title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<table border="1px">
<thead>
<tr>
<th>姓名th>
<th>年龄th>
<th>性别th>
tr>
thead>
<tbody>
<tr v-for="obj in array_obj">
<td>{{obj.name}}td>
<td>{{obj.age}}td>
<td>{{obj.gender}}td>
tr>
tbody>
table>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
array_obj: [
{'name': "kid", 'age': 18, 'gender': '男'},
{'name': "qq", 'age': 19, 'gender': '女'},
{'name': "qzq", 'age': 20, 'gender': '男'},
]
}
})
script>
body>
html>
11.6 表单渲染
v-if+v-for+v-else控制购物车商品的显示
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>购物车展示title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<h1>购物车h1>
<table border="1px">
<thead>
<tr>
<th>商品th>
<th>价格th>
tr>
thead>
<tbody v-if="shop.length==0">
<tr>
<td>暂无信息td>
<td>暂无信息td>
tr>
tbody>
<tbody v-else>
<tr v-for="obj in shop">
<td>{{ obj.name }}td>
<td>{{ obj.price }}td>
tr>
tbody>
table>
<br>
<button @click="show">一键添加button>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
shop: []
},
methods: {
show() {
this.shop = [
{'name': '苹果', 'price': '12'},
{'name': '芒果', 'price': '15'},
{'name': '西瓜', 'price': '30'},
]
},
}
})
script>
body>
html>
12. 数组的更新与检测
Vue作者重写数组的一些方法, 使得列表在变动只能被检测, 并更新渲染.
可以检测到的数组操作方法:
push:最后位置添加
pop:最后位置删除
shift:第一个位置删除
unshift:第一个位置添加
splice:切片
sort:排序
reverse:反转
检测不到变动的数组操作:
数组[索引]=改值
filter():过滤
concat():追加另一个数组
slice():
map():
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<p v-for="i in array1">第{{i}}行p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
array1: [1, 2, 3]
},
})
script>
body>
html>
值修改了, 没有重新渲染.
Vue中提供了一个set属性, 用于修改值, 并触发发渲染!
Vue.set(对象, index, value) 更新数组(数据会更新,页面也会发生改变)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<p v-for="i in array1">第{{i}}行p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
array1: [1, 2, 3]
},
})
script>
body>
html>
13. 输入框双向绑定数据
输入框中使用v-model='变量'的方式将 value属性的值绑定给变量.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数组title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<input type="text" v-model="text"> --> {{text}}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
text: ''
}
})
script>
body>
html>
14. 事件处理
事件 |
释义 |
input |
当输入框进行输入的时候 触发的事件 |
change |
当元素的值发生改变时 触发的事件 |
blur |
当输入框失去焦点的时候 触发的事件 |
change 和 blur 最本质的区别:
change值发生改变才触发,
如果输入框为空, 失去焦点后, change不会触发, 但是blur会触发.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>input事件title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
Input: <input type="text" v-model="text1" @input="Input">
<hr>
Change <input type="text" v-model="text2" @change="Change">
<hr>
Blur<input type="text" v-model="text3" @blur="Blur">
div>
<script>
var app = new Vue({
el: '#d1',
data: {
text1: '',
text2: '',
text3: '',
},
methods: {
Input() {
console.log('input触发器:', this.text1)
},
Change() {
console.log('change触发器:',this.text2)
},
Blur() {
console.log('blur触发器:',this.text3)
}
}
})
script>
body>
html>
每输入一个值触发一次
每次改变了值, 退出聚焦, 触发
每次退出聚焦, 触发, 展示款内的值
15 文本过滤
15.1 filter过滤
var array1 = ['a', 'ab', 'abc', 'abcd', 'abcde']
var array2 = array1.filter(function (item){
if (item.length>2){
return true
}
})
console.log(array2)
15.2 字符串包含字符串
indexOf 判断字符串是否包含某个字符串, 如果包含返回它最开始匹配所在的索引, 否则返回-1.
var str1 = 'abc'
str1.indexOf('ab')
str1.indexOf('bc')
str1.indexOf('ac')
15.3 输入联动过滤
注意点: Vue对象中定义的第一层函数的this是Vue, 第二层定义的函数使用的this就是Windows.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>输入联动过滤title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
在过滤框中输入值:
<input type="text" @input="in_filter" v-model="text">
<p>所有的数据:p>
<ul>
<li v-for="i in array2">{{i}}li>
ul>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
text: '',
array1: ['a', 'ab', 'abc', 'x', 'xy', 'xyz'],
array2: ['a', 'ab', 'abc', 'x', 'xy', 'xyz'],
},
methods: {
in_filter() {
var _this = this
this.array2 = this.array1.filter(function (item) {
if (item.indexOf(_this.text) > -1) {
return true
}
})
}
}
})
script>
body>
html>
15.4 箭头函数
es6中为了解决this的问题, 设计了一个箭头函数, 箭头函数, 没有自己的this. 那么会调用上层的this.
var app = new Vue({
methods: {
in_filter() {
console.log(this)
function f() {
console.log(this)
}
f()
}
}
})
app.in_filter()
var app = new Vue({
methods: {
in_filter() {
console.log(this)
var f =()=>{
console.log(this)
}
f()
}
}
})
app.in_filter()
16. 事件修饰符
事件修饰符 |
释义 |
.stop |
只处理自己的事件,父控件冒泡的事件不处理(阻止事件冒泡) |
.self |
只处理自己的事件,子控件冒泡的事件不处理 |
.prevent |
阻止a链接的跳转 |
.once |
事件只会触发一次(适用于抽奖页面) |
使用修饰符时,顺序很重要.相应的代码会以同样的顺序产生
用 v-on:click.prevent.self 会阻止所有的点击
而 v-on:click.self.prevent 只会阻止对元素自身的点击
16.1 冒泡
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<ul @click="clickA('父控件')">
父控件
<li @click="clickA('子控件1')">子控件1li>
<li @click="clickA('子控件2')">子控件2li>
<li @click="clickA('子控件3')">子控件3li>
ul>
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA(name) {
alert(`${name}被点击了`)
}
}
})
script>
body>
html>
子控件的事件触发之后, 父控件也被触发, 子控件在父控件的范围内. 这种情况被称之为冒泡.
16.2 阻止冒泡
方式1: 在父控件中使用事件后加上.self, 父控件不会被子控件触发.
@click.self
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<ul @click.self="clickA('父控件')">
父控件
<li @click="clickA('子控件1')">子控件1li>
<li @click="clickA('子控件2')">子控件2li>
<li @click="clickA('子控件3')">子控件3li>
ul>
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA(name) {
alert(`${name}被点击了`)
}
}
})
script>
body>
html>
方式2: 为子控件单独加上阻止事件冒泡.
@click.stop
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<ul @click="clickA('父控件')">
父控件
<li @click.stop="clickA('子控件1')">子控件1li>
<li @click="clickA('子控件2')">子控件2li>
<li @click="clickA('子控件3')">子控件3li>
ul>
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA(name) {
alert(`${name}被点击了`)
}
}
})
script>
body>
html>
16.3 阻止网页跳转
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>网页跳转title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<a href="https://www.baidu.com">会员入口a>
div>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>网页跳转title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<a href="https://www.baidu.com" @click.prevent="clickA">会员入口a>
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA() {
alert('网页不跳转')
}
}
})
script>
body>
html>
网页不跳转
vue的代码在前端是看不见的可以在函数中定义一些方法, 控件网页的跳转.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>网页跳转title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<a href="https://www.baidu.com" @click.prevent="clickA">会员入口a>
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA() {
alert('30s会员体验')
location.href='https://www.baidu.com'
}
}
})
script>
body>
html>
16.4 只触发一次
事件只会触发一次(适用于抽奖页面)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>商品秒杀 title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
<h1>限时秒杀活动h1>
<button @click.once="clickA">点击秒杀button>
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA() {
alert('秒杀成功!')
}
}
})
script>
body>
html>
17. 按键修饰符
修饰符 |
释义 |
.keyup |
按键被按下后弹起时触发一次. |
.keydown |
按键被按下后时触发(长按不弹起会连续触发) |
.keyup.部分按键名 |
指定某个按键被按下后弹起触发一次. |
部分按键名:
.alt
.ctrl
.delete
.dowm
.enter
.esc
.exact
.left
.meta
.right
.shift
.space
.tab
.up
.capture
$event,可以获取到该事件的事件对象.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按键触发title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
输入框:<input type="text" @keyup="clickA($event)">
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA(event) {
console.log(event)
}
}
})
script>
body>
html>
按下的键被存放在key属性中.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按键title>
<script src="Vue.js">script>
head>
<body>
<div id="d1">
输入框:<input type="text" @keyup="clickA($event)">
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA(event) {
console.log(`按键${event.key}被按下了`)
}
}
})
script>
body>
html>
通过对象.key取到被按下的按键.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按键title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
输入框:<input type="text" @keyup.enter="clickA($event)">
div>
<script>
var app = new Vue({
el: '#d1',
methods: {
clickA(event) {
console.log(`按键${event.key}被按下了`)
}
}
})
script>
body>
html>
指定按键按下弹起被触发.
18. v-model双向绑定
v-model指令可以在表单 input、textarea以及select元素上创建双向数据绑定.
v-model原理其实是背后有两个操作:
v-bind绑定value属性的值,
v-on绑定input事件监听到函数中, 函数会获取最新的值赋值到绑定的属性.
18.1 选择框
radio的值为布尔类型值.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>选择框title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
<input type="checkbox" v-model="radio">我已阅读xx协议!
<p>radio的值:{{radio}}p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
radio: true
}
})
script>
body>
html>
18.2 单选框
单选框是单个值, 可以是字符串可以是数字.
在选中值的时候, 会修改js变量的值为value设置的值.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单选框title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
<input type="radio" v-model="radio" value=1>男
<input type="radio" v-model="radio" value=2>女
<input type="radio" v-model="radio" value=3>保密
<p>你的选择:{{radio}}p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
radio: 3
}
})
script>
body>
html>
18.3 多选框
多选框的值是一个数组.
在选中值的时候, 会修改js变量的值为value设置的值.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单选框title>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
<input type="checkbox" v-model="radio" value='吃'>吃
<input type="checkbox" v-model="radio" value='喝'>喝
<input type="checkbox" v-model="radio" value='玩'>玩
<p>你的选择:{{radio}}p>
div>
<script>
var app = new Vue({
el: '#d1',
data: {
radio: []
}
})
script>
body>
html>
如果定义的值不是数组, 选中后会变成布尔值, 其他的选框被一起选中.
19. v-model进阶
以下修饰是为input输入框准备的. 装饰在v-model后面
修饰符 |
释义 |
.lazy |
等待input框 失去焦点之后再变化 |
.number |
数字开头, 只保留数字, 后面的字母不保留. 字母开头, 都保留. |
.trim |
去除首位的空格 |
19.1 lazy
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>lazytitle>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
<input type="text" v-model.lazy="text"> ---> {{text}}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
text: ''
}
})
script>
body>
html>
v-model双向绑定每次都直接更新, 这样太耗费资源, 使用lazylazy等待input框失去焦点之后再变化.
19.2 number
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>numbertitle>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
<input type="text" v-model.number="text"> ---> {{text}}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
text: ''
}
})
script>
body>
html>
数字开头, 只保留数字, 后面的字母不保留. 字母开头,都保留
19.3 trim
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>trimtitle>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js">script>
head>
<body>
<div id="d1">
<input type="text" v-model.trim="text"> ---> {{text}}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
text: ''
}
})
script>
body>
html>
去除首位的空格
20. 购物车练习
20.1 添加商品
利用多选框 + 实现添加商品,计算价格.
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>购物车练习1title>
<script src="js/vue.js">script>
head>
<body>
<div id="d1">
<h1>购物车h1>
<table border="1px">
<thead>
<tr>
<th>商品名称th>
<th>商品价格th>
<th>购买数量th>
<th>选中/取消th>
tr>
thead>
<tbody>
<tr v-for="obj in shopping_cart">
<td>{{ obj.name }}td>
<td>{{ obj.price }}td>
<td>{{ obj.number }}td>
<th><input type="checkbox" v-model="my_list" :value="obj">th>
tr>
tbody>
table>
<br>
选中的商品清单:{{ my_list }}
<br>
总价格: {{ TotalCost() }}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
shopping_cart: [
{name: '牙膏', price: 25, number: 2},
{name: '牙刷', price: 4.5, number: 2},
{name: '水杯', price: 6, number: 2},
{name: '毛巾', price: 6.5, number: 2},
{name: '洗发水', price: 35, number: 1},
{name: '沐浴露', price: 65, number: 1},
],
my_list: []
},
methods: {
TotalCost() {
var money = 0
for (i in this.my_list) {
obj = this.my_list[i]
money += obj.price * obj.number
}
return money
}
}
})
script>
body>
html>
20.2 全选
设计一个全选/取消全选的 选项
核心代码:(修改my_list的值)
if(this.all_check){
this.my_list = this.shopping_cart
}else{
this.my_list = []
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>购物车练习2title>
<script src="js/vue.js">script>
head>
<body>
<div id="d1">
<h1>购物车h1>
<table border="1px">
<thead>
<tr>
<th>商品名称th>
<th>商品价格th>
<th>购买数量th>
<th>选中/取消th>
tr>
thead>
<tbody>
<tr v-for="obj in shopping_cart">
<td>{{ obj.name }}td>
<td>{{ obj.price }}td>
<td>{{ obj.number }}td>
<th><input type="checkbox" v-model="my_list" :value="obj">th>
tr>
<tr>
<td colspan="3" align="center">全选/全不选td>
<td align="center"><input type="checkbox" v-model="all_check" @change="select_all">td>
tr>
tbody>
table>
<br>
是否全选: {{all_check}}
<br>
选中的商品清单:{{ my_list }}
<br>
总价格: {{ TotalCost() }}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
shopping_cart: [
{name: '牙膏', price: 25, number: 2},
{name: '牙刷', price: 4.5, number: 2},
{name: '水杯', price: 6, number: 2},
{name: '毛巾', price: 6.5, number: 2},
{name: '洗发水', price: 35, number: 1},
{name: '沐浴露', price: 65, number: 1},
],
my_list: [],
all_check: false,
},
methods: {
TotalCost() {
var money = 0
for (i in this.my_list) {
obj = this.my_list[i]
money += obj.price * obj.number
}
return money
},
select_all(){
if(this.all_check){
this.my_list = this.shopping_cart
}else{
this.my_list = []
}
}
}
})
script>
body>
html>
现在完成了一半了,
1. 全选后, 在单独取消, 取消全选.
2. 手动一个个选中, 变成全选.
核心代码:(改变this.all_check的值)
Manual_trigger() {
if (this.my_list.length === this.shopping_cart.length){
this.all_check = true
} else {
this.all_check = false
}
}
使用三目运算简化代码:
this.all_check = (this.my_list.length === this.shopping_cart.length)
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按键触发title>
<script src="js/vue.js">script>
head>
<body>
<div id="d1">
<h1>购物车h1>
<table border="1px">
<thead>
<tr>
<th>商品名称th>
<th>商品价格th>
<th>购买数量th>
<th>选中/取消th>
tr>
thead>
<tbody>
<tr v-for="obj in shopping_cart">
<td>{{ obj.name }}td>
<td>{{ obj.price }}td>
<td>{{ obj.number }}td>
<th><input type="checkbox" v-model="my_list" :value="obj" @change="Manual_trigger">th>
tr>
<tr>
<td colspan="3" align="center">全选/全不选td>
<td align="center"><input type="checkbox" v-model="all_check" @change="select_all">td>
tr>
tbody>
table>
<br>
是否全选: {{all_check}}
<br>
选中的商品清单:{{ my_list }}
<br>
总价格: {{ TotalCost() }}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
shopping_cart: [
{name: '牙膏', price: 25, number: 2},
{name: '牙刷', price: 4.5, number: 2},
{name: '水杯', price: 6, number: 2},
{name: '毛巾', price: 6.5, number: 2},
{name: '洗发水', price: 35, number: 1},
{name: '沐浴露', price: 65, number: 1},
],
my_list: [],
all_check: false,
},
methods: {
TotalCost() {
var money = 0
for (i in this.my_list) {
obj = this.my_list[i]
money += obj.price * obj.number
}
return money
},
select_all() {
if (this.all_check) {
this.my_list = this.shopping_cart
} else {
this.my_list = []
}
},
Manual_trigger() {
this.all_check = (this.my_list.length === this.shopping_cart.length)
}
}
})
script>
body>
html>
20.3 商品数量的加减
在购买数量的表单内添加 - +两个按键.
+ 没有上限, -不能最少为1.
核心代码:
<td>
<button @click="count(obj)">-button>
{{ obj.number }}
<button @click="obj.number++">+button>
td>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>按键触发title>
<script src="js/vue.js">script>
head>
<body>
<div id="d1">
<h1>购物车h1>
<table border="1px">
<thead>
<tr>
<th>商品名称th>
<th>商品价格th>
<th>购买数量th>
<th>选中/取消th>
tr>
thead>
<tbody>
<tr v-for="obj in shopping_cart">
<td>{{ obj.name }}td>
<td>{{ obj.price }}td>
<td> <button @click="count(obj)">-button> {{ obj.number }} <button @click="obj.number++">+button> td>
<th><input type="checkbox" v-model="my_list" :value="obj" @change="Manual_trigger">th>
tr>
<tr>
<td colspan="3" align="center">全选/全不选td>
<td align="center"><input type="checkbox" v-model="all_check" @change="select_all">td>
tr>
tbody>
table>
<br>
是否全选: {{all_check}}
<br>
选中的商品清单:{{ my_list }}
<br>
总价格: {{ TotalCost() }}
div>
<script>
var app = new Vue({
el: '#d1',
data: {
shopping_cart: [
{name: '牙膏', price: 25, number: 2},
{name: '牙刷', price: 4.5, number: 2},
{name: '水杯', price: 6, number: 2},
{name: '毛巾', price: 6.5, number: 2},
{name: '洗发水', price: 35, number: 1},
{name: '沐浴露', price: 65, number: 1},
],
my_list: [],
all_check: false,
},
methods: {
TotalCost() {
var money = 0
for (i in this.my_list) {
obj = this.my_list[i]
money += obj.price * obj.number
}
return money
},
select_all() {
if (this.all_check) {
this.my_list = this.shopping_cart
} else {
this.my_list = []
}
},
Manual_trigger() {
this.all_check = (this.my_list.length === this.shopping_cart.length)
},
count(obj){
if (obj.number === 1){
alert('不能再少了')
}else{
obj.number--
}
}
}
})
script>
body>
html>