前端发展
1.前端发展史
1.1 HTML(5)+css(3)+JavaScript(ES5、ES6)---编写前端页面---后端(PHP/Python/go/Java)---后端通过模板语法将后端数据渲染---返回前端---在浏览器中查看
1.2 Ajax--后端发送异步请求 前端Render+Ajax混合模式展示
1.3 只有Ajax加载数据---DOM渲染--前后端分离的雏形
1.4 前端框架:Angular框架---出现了'前端工程化'概念
1.5 前端框架:React、Vue框架---当前最火(国人喜欢用Vue 国外喜欢用React)
1.6 (大)前端:移动开发(Android+ISO)+Web(web+微信小程序+支付宝小程序)+桌面开发(windows桌面)
1.7 大前端:一套代码在各个平台运行谷歌Flutter(Dart语言:和Java很像)可以运行在IOS、Android、PC端
1.8 在Vue框架的基础性上 uni-app:一套编码 编到10个平台
1.9 前端发展的介绍:https://zhuanlan.zhihu.com/p/337276087?
Vue的使用
1.Vue的介绍:
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合
2.Vue是渐进式框架
可以使用一部分也可以整个项目整体使用
3.网站:
官网:https://cn.vuejs.org/
文档:https://cn.vuejs.org/v2/guide/
4.Vue的特点:
4.1 易用
通过 HTML、CSS、JavaScript构建应用
4.2 灵活
不断繁荣的生态系统,可以在一个库和一套完整框架之间自如伸缩。
4.3 高效
20kB min+gzip 运行大小
超快虚拟 DOM
最省心的优化
5.M-V-VM思想
5.1 介绍:Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,是一种事件驱动编程方式
Model:Vue对象的data属性中的数据 显示在页面中的数据
view:Vue中数据要显示在HTML页面 在Vue中也称之为视图模板(HTML+CSS)
ViewModel:vue中编写代码时的vm对象,它是vue.js的核心,负责连接 View 和 Model数据的中转,保证视图和数据的一致性,所以前面代码中,data里面的数据被显示中p标签中就是vm对象自动完成的(双向数据绑定:JS中变量变了,HTML中数据也跟着改变)
https://tva1.sinaimg.cn/large/008i3skNgy1gprqsts5q2j321s09saan.jpg
5.2 特征:
低耦合
可复用
独立开发
可测试
5.3 逻辑:view双向数据绑定---ViewModel---发送Ajax请求---返回数据Model(逻辑编写--数据库)
6.开发:
单页开发:
只需要1个页面,结合组件化开发来替换页面中的内容 页面的切换只是组件的替换,页面还是只有1个index.html
组件化开发:类似于DTL中的include,每一个组件的内容都可以被替换和复用
7.版本:
1.X:使用较少
2.X:普遍使用
3.X:过渡阶段
8.引入方式:
CDN引入
下载导入--与js导入一致
网址:https://cdn.jsdelivr.net/npm/vue/dist/vue.js
9.语言:
js是解释性语言:解释器集成到了浏览器中
nodejs(一门后端语言):把chrome的v8引擎(解释器),安装到操作系统之上
10.Vue
<body>
<div id="d1">
姓名:{{name}}
年龄:{{age}}
</div>
</body>
<script>
var vm = new Vue({
el:'#d1',
data:{
name:'lili',
age: 18,
}
})
</script>
插值语法
1.字符串
2.数值
3.数组--字符串(索引取值)
4.对象--字符串
5.网址--字符串
注:当Vue的插值语法与模板语法共同存在时需要修改一方的 不然会导致错误
<body>
<div id="d1">
姓名:{{name}}
年龄:{{age}}
爱好:{{hobby}}
第一个爱好:{{hobby[1]}}
信息:{{info}}
网址:{{a}}
</div>
</body>
<script>
var vm = new Vue({
el:'#d1',
data:{
name:'lili',
age: 18,
hobby:['羽毛球', '乒乓球'],
info: {'name': 'lili', 'age': 18},
a:'https://cdn.jsdelivr.net/npm/vue/dist/vue.js'
}
})
指令系统
文本指令
1.写在[任意]标签上 以 v-xx 开头的,都是vue的指令
2.文本指令
v-text:把变量渲染到标签中,如果之前有数据,覆盖掉
v-html:如果是标签字符串,会把标签渲染到标签内
v-show:控制标签的显示与隐藏,但是它是通过style的display控制的:style="display: none;"
v-if:控制标签的显示与隐藏,但是它是通过dom的增加和删除
3.代码
<body>
<div id="d1">
<span v-text="name"></span>
<span v-html="a"></span>
<img v-show="img" src="https://img0.baidu.com/it/u=633778097,1034027030&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=27efede310a2bd944ca5eed92e58fe20" alt="">
<img v-if="img1" src="https://img1.baidu.com/it/u=665208686,3911335732&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=a89b1af11b58a2d1efd6babaf3321ce5" alt="">
</div>
</body>
<script>
var vm = new Vue({
el:'#d1',
data:{
name:'lili',
age: 18,
hobby:['羽毛球', '乒乓球'],
info: {'name': 'lili', 'age': 18},
a:'<a href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">点我</a>',
img: true,
img1: true,
}
})
事件指令
1.放在标签上:v-on:事件名='函数'
2.事件名可以写:click,dbclick, input标签:change,blur,input
3.补充:es6 对象写法
var name = 'lili'
var age = 18
// var obj={name:name,age:age}
var obj = {name, age, handleClick() {}}
4.v-on:事件名='函数' 简写成 @事件名='函数'
5.形参:不报错
多传--以实际传的实参为准
少传--以位置参数给与实参
不传--无实参显示
6.代码:
<div id="d1">
<!-- <button v-on:click="handledimg">点我</button>-->
<button @click="handledimg('123', 'lili')">点我</button>
<div v-show="img">
<img src="https://img0.baidu.com/it/u=633778097,1034027030&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=27efede310a2bd944ca5eed92e58fe20" alt="">-->
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#d1',
data:{
// name:'lili',
// age: 18,
// hobby:['羽毛球', '乒乓球'],
// info: {'name': 'lili', 'age': 18},
// a:'<a href="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">点我</a>',
img: true,
// img1: true,
},
methods:{
// handledimg:function () {
// this.img = !this.img
// }
// handledimg(){
// this.img = !this.img
// }
//
handledimg(a,b) {
this.img = !this.img
alert(a)
alert(b)
}
}
})
</script>
属性指令
1.写在标签上的 name,class,href,src,id.....属性
2.v-bind:属性名='变量' 简写成: :属性名="变量"
注:属性指令可以使标签中属性写变量名
3.图片切换代码
<body>
<div id="d1">
src="https://img0.baidu.com/it/u=633778097,1034027030&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=27efede310a2bd944ca5eed92e58fe20" alt="">–>-->
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#d1',
data:{
img: true, urlList:'https://img0.baidu.com/it/u=633778097,1034027030&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=27efede310a2bd944ca5eed92e58fe20',
urllist:[
'https://img2.baidu.com/it/u=1640158430,3788639612&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400', 'https://img1.baidu.com/it/u=84572721,2203711366&fm=253&fmt=auto&app=138&f=JPEG?w=360&h=360', 'https://img1.baidu.com/it/u=3766746561,140386798&fm=253&fmt=auto&app=138&f=JPEG?w=499&h=493', 'https://img2.baidu.com/it/u=1765478171,368549186&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500'
]
},
methods:{ this.url='https://img1.baidu.com/it/u=665208686,3911335732&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=a89b1af11b58a2d1efd6babaf3321ce5'
// }
handledimg() {
var i = Math.floor(Math.random() * this.urllist.length)
console.log(i)
this.urlList = this.urllist[i]
}
}
})
</script>
4.图片随机切换(定时装置)
<body>
<div id="d1">
src="https://img0.baidu.com/it/u=633778097,1034027030&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=27efede310a2bd944ca5eed92e58fe20" alt="">–>-->
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#d1',
data:{
img: true, urlList:'https://img0.baidu.com/it/u=633778097,1034027030&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=27efede310a2bd944ca5eed92e58fe20',
urllist:[
'https://img2.baidu.com/it/u=1640158430,3788639612&fm=253&fmt=auto&app=138&f=JPEG?w=400&h=400', 'https://img1.baidu.com/it/u=84572721,2203711366&fm=253&fmt=auto&app=138&f=JPEG?w=360&h=360', 'https://img1.baidu.com/it/u=3766746561,140386798&fm=253&fmt=auto&app=138&f=JPEG?w=499&h=493', 'https://img2.baidu.com/it/u=1765478171,368549186&fm=253&fmt=auto&app=138&f=JPEG?w=501&h=500'
]
},
methods:{ this.url='https://img1.baidu.com/it/u=665208686,3911335732&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1666717200&t=a89b1af11b58a2d1efd6babaf3321ce5'
// }
handledimg() {
handledimg() {
setInterval(() => {
var i = Math.floor(Math.random() * this.urllist.length)
this.urlList = this.urllist[i]
}, 1000)
}
}
})
</script>
属性
1.class属性:
通过vue属性v-bind:class='变量名'简写:class='变量名'
1.1 class属性字符串用法--已定义过的类
1.2 class属性数组用法--类本身就是多个 所以数组使用较多
1.3 class属性对象用法--针对是否显示(v布尔值)
2.style属性
通过vue属性v-bind:style='变量名'简写:style='变量名'
1.1 style属性字符串用法--styleObj:'background-color: green;',
1.2 style属性数组用法--styleObj:[{'background-color': 'green'}, {'font-size': '40px'}]
1.3 style属性对象用法--styleObj:{backgroundColor: 'green',fontSize: '40px'}
3.代码
<style>
.color{
background-color: green;
}
.size{
font-size: 40px;
}
</style>
<body>
<div id="app">
<div :class="classObj">
class的div
</div>
<div :style="styleObj">
style的div
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
// classObj:{color:true, size:false},
// styleObj: 'size'
//class字符串的用法
// classObj:'color',
//class数组用法
// classObj:['color', 'size']
//class对象的用法
classObj:{color:true, size:false},
//style字符串用法
// styleObj:'background-color: green;',
//style数组用法
// styleObj:[{'background-color': 'green'}, {'font-size': '40px'}]
//style对象用法
styleObj:{backgroundColor: 'green',fontSize: '40px'}
},
})
</script>
条件渲染
1.放在标签上控制标签的显示与不显示
v-if---条件成立走 结果是布尔值
v-else-if---if条件不成立走 结果是布尔值
v-else---条件都不成立走
2.代码
<body>
<div id="app">
<div v-if="score>=90">优秀</div>
<div v-else-if="score>=80 && score<90">良好</div>
<div v-else-if="score>=60 && score<80">及格</div>
<div v-else>不及格</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
score:100
},
})
</script>
列表渲染
1.放在标签上可以循环显示多个此标签
v-for
2.代码:购物车商品展示
<body>
<div id="app">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="text-center">购物车</h1>
<button @click="handleClick" class="btn btn-danger">加载购物车</button>
<div v-if="goods.length>0">
<table class="table">
<thead>
<tr>
<th>序号</th>
<th>商品</th>
<th>价格</th>
</tr>
</thead>
<tbody>
<tr v-for="good in goods">
<td>{{good.id}}</td>
<td>{{good.name}}</td>
<td>{{good.price}}</td>
</tr>
</tbody>
</table>
</div>
<div v-else>
购物车空空哒
</div>
</div>
</div>
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
goods:[]
},
methods: {
handleClick(){
this.goods=[{id:1,name:'滑板', price: 999},
{id:2, name:'📷', price:8888},
{id:3, name: '🎸', price: 9999}
]
}
}
})
</script>
3.循环不同数据类型
3.1 循环字符串---i字符 v索引
3.2 循环数组---i元素 v索引
3.3 循环数字---i从1开始的数字 v索引
3.4 循环对象---i是v值 v是k值
# 每次循环的标签上,一般都会带一个属性: :key='值必须唯一'
-key值得解释:为了加速虚拟dom的替换
3.5 代码:
<body>
<div id="app">
<div v-for="i,v in str" :key="v">
字符:{{i}}
索引:{{v}}
</div>
<div v-for="i,v in list" :key="v">
元素:{{i}}
索引:{{v}}
</div>
<div v-for="i,v in num" :key="v">
值:{{i}}
索引:{{v}}
</div>
<div v-for="i,v in dict">
v:{{i}}
k:{{v}}
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data:{
str:'hello word 你好',
list:['你好', '不好'],
dict:{name: 'lili', age:18}
},
4.数组的检测与跟新
4.1 数组添加单个数据用push
4.2 数组的更新:数组一次添加多个数据--生成新的数组使用concat不能直接渲染至页面
使用Vue.set(this.goods,0,'🏸')添加
4.3 对象中添加数据this.obj.height=168无法渲染至页面
4.4 对象的跟新:Vue.set(this.obj,'height',168)
<body>
<div id="app">
<button @click="handledClick" class="btn btn-danger">数组添加数据</button>
<button @click="handledClick1" class="btn btn-danger">数组中添加数组</button>
<button @click="handledClick2" class="btn btn-danger">数组更新</button>
<div v-for="i in goods">
{{i}}
</div>
<button @click="handledClick3" class="btn btn-danger">对象中添加数据</button>
<button @click="handledClick4" class="btn btn-danger">对象更新</button>
<div v-for="i,v in obj">
{{i}}
{{v}}
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data: {
goods:['🎸', '📱', '📷'],
obj:{'name': 'lili'}
},
methods:{
handledClick(){
this.goods.push('🏀')
},
handledClick1(){
var good = this.goods.concat(['🏸', '🏐'])
console.log(good) //添加生成新的数组
},
handledClick2(){
Vue.set(this.goods,0,'🏸')
},
handledClick3(){
this.obj.height=168
console.log(this.obj)
},
handledClick4(){
Vue.set(this.obj,'height',168)
},
}
})
</script>
双向数据绑定
- input标签,v-model:数据双向绑定
使用 属性指令绑定 :value='变量' 是数据的单向绑定
v-model="name" :数据双向绑定
2.代码
<body>
<div id="app">
<h1>数据的双向绑定</h1>
<div>用户名:
<input type="text" :value="username">
</div>
<div>密码:
<input type="password" v-model="password">
</div>
<div>
<button @click="headleClick">提交</button>{{err}}
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data: {
username:'',
password:'',
err:''
},
methods:{
headleClick(){
console.log(this.username, this.password)
this.error='用户名或密码错误'
}
}
})
</script>
事件处理
1.事件绑定 v-on:事件名='函数'简写 @事件名='函数'
blur:失去焦点触发
change:发生变化触发
input:输入触发
2.代码:
<body>
<div id="app">
<div>
<input type="text" v-model="info" v-on:input="handledInput">
</div>
<div>
<input type="text" v-model="info1" @change="handledChange">
</div>
<div>
<input type="text" v-model="info2" @blur="handledBlur">
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data: {
info:'',
info1:'',
info2:''
},
methods:{
handledInput(){
console.log('输入内容啦', this.info)
},
handledChange(){
console.log('内容变化啦', this.info1)
},
handledBlur(){
console.log('失去焦点啦', this.info2)
},
}
})
</script>
3.过滤案例:
3.1 filter:数组内置的过滤方法 需要传匿名函数 接收一个参数 会循环的从数组中取出值 传入匿名函数中执行 匿名函数返回true或false,如果返回true,该值保留,如果返回false该值丢弃
3.2 indexOf:判断子字符串是否在字符串中
3.3 箭头函数:es6写法
函数:
var vm=function(){
console.log('123')
}
无参数的箭头函数:
var vm=()=>{
console.log('123')
}
带有一个参数的箭头函数
var vm=name=>{
console.log('123')
}
多个参数 无返回值
var vm=(name, age)=>{
console.log('123')
}
带一个参数有返回值
var vm = function(name){
return name+'ll'
}
var vm = name => name+'ll'
注:箭头函数没有自己的this 会使用上一层的this
3.4 代码:
<body>
<div id="app">
<h1>过滤案例</h1>
<div>
<input type="text" v-model="info" placeholder="输入内容" @input="handledInput">
</div>
<div v-for="i in newlist">
{{i}}
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'#app',
data: {
info:'',
list:[
'a','ab','dd', 'cf', 'ae'
],
newlist:[
'a','ab','dd', 'cf', 'ae'
]
},
methods:{
handledInput(){
console.log('搜索的内容是:', this.info)
// var _this=this
// this.newlist =this.list.filter(i=>{console.log(this)})
// if(i.indexOf(this.info)>=0){
// return true
// }else{
// return false
// }
this.newlist=this.list.filter(i=>i.indexOf(this.info)>=0)
}
}
})
</script>
事件修饰符
1.事件修饰符
.stop 只处理自己的事件,不向父控件冒泡
.self 只处理自己的事件,子控件冒泡的事件不处理
.prevent 阻止a链接的跳转
.once 事件只会触发一次(适用于抽奖页面)
2.代码:
<body>
<div id="app">
<h1>事件修饰</h1>
<!-- <ul @click="handleF">-->
<!-- <li @click="handleS1">11</li>-->
<!-- <li @click="handleS2">22</li>-->
<!-- </ul>-->
<!-- <ul @click="handleF">-->
<!-- <li @click.stop="handleS1">11</li>-->
<!-- <li @click="handleS2">22</li>-->
<!-- </ul>-->
<ul @click.self="handleF">
<li @click="handleS1">11</li>
<li @click="handleS2">22</li>
</ul>
<h1>阻止页面跳转</h1>
<!-- <a href="www.baidu.com" @click="handleClick">点我</a>-->
<!-- <a href="http://www.baidu.com" @click.prevent="handleClick">点我</a>-->
<button @click.once="handleClick">点我</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {}
methods: {
handleF() {
console.log('ul被点了')
},
handleS1() {
console.log('s1被点了')
},
handleS2() {
console.log('s2被点了')
},
handleClick(){
console.log('a被点了')
},
}
})
</script>
按键修饰符
1.回车键
<body>
<div id="app">
<h1>案件修饰</h1>
<input type="text" v-model="info" placeholder="请输入搜索内容" @keyup.enter="handleUp">
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
info:''
}
methods: {
handleUp(event) {
// console.log('回车键被按了')
if (event.code == 'Enter') {
console.log('回车键被按了', event)
}
}
}
})
</script>
posted on
浙公网安备 33010602011771号