Vue的相关背景:
vue2 => vue3 ===>vue实战
vue
Taylor otwell (程序员中的网红)
框架 库 (功能 方法)axios
框架 生态 引入第三方功能库 社区
Vue2
Vue3
需要准备的小工具
vscode : snipper
Vetur
浏览器需要准备
Vue Devtools
Vue 引入方式:
1、cdn 引入
2、 下载文件
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>
<div id="app">{{msg}} <br>
名字:{{person.name}}<br>
年龄:{{person.age}}<br>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
// console.log(Vue);
// 1.创建Vue的实例 {}配置对象
Vue.config.productionTip = false;
const vm = new Vue({
// 用于挂载到页面上的html标签
// css选择器的写法 关联上dom容器 内容 叫模板
el: '#app',
// 用于存放 页面上要用到的数据
data(){
return {
msg:'zz123456',
person:{
name:'zz',
age:15
},
}
},
})
console.log(vm);
</script>
</body>
</html>
对上面的代码进行解析
* 先解析 html #app
* vue实例 el ==》 #app挂载绑定 必不可少
* 识别#app内有没有 vue语法 {{msg}}是vue语法 ==》‘我是zz’
* 放在#app渲染页面中
* 对比·:
* 原生js 一步一步来
* 声明变量 接收 页面上的dom
* 声明变量 数据
* dom.innerHTML = 数据
* 数据发生了变化
* dom.innerHTML = 新数据
*
* el挂载的两种方式
* 1 在配置对象中挂载到el属性
* new Vue({
* el :'#app'
* })
*
* 2 实例对象挂载
* const vm = new Vue({
* data :{
* msg:'zz456'
* }
* })
* vm.$mount('#app')
*
* data的两种写法
* 1.
* data:{
数据写这里
* }
* 2 组件 内必须写这种写法
* data: function(){
* return {
* 数据
* }
* }
* 简写方式
* data(){
* return {
* 数据
* }
* }
*
*
* 挂载时更多的情况
* 1.没有被挂载的元素 不会被Vue解析
* 2.body html 不能作为Vue的绑定的元素 会报错
* 3.模板内使用实例中未 存在的数据 会报错
* 4.如果对象中存在的是复杂对象 按照js语法拿出来就可以了
*
*
* 了解一下
* MVVM
* M model 数据(数据层) ====>data
* V view 视图层 ===> dom层 ===> Vue模板
* VM viewModel vm ===> Vue 实例
*
* 1.model 数据层发生变化 通知vm vm通知view 进行渲染
* 2. view 上发生了变化 (input 内的内容发生了变化) 通知vm vm通知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'>
<!-- {{1+2}}<br>
{{msg}} -->
<!-- ${msg} -->
<span v-if="bool">我是一个加载中的图标</span>
<span v-else>我是加载好的数据</span>
<span v-if="num>80">优秀</span>
<span v-else-if="num>=60&&num<= 80">一般</span>
<span v-else>不及格</span>
<template v-if="bool">
<span>1</span>
<span >2</span>
<span >3</span>
<span >4</span>
<span >5</span>
</template>
</div>
<script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
<script>
Vue.config.productionTip = false
new Vue({
el: '#app',
data() {
return {
msg:'z534',
bool:false,
num:89,
}
},
</script>
</body>
</html>
对上面的代码进行解析
// 了解 修改插值语法写法{{}} ${}
// delimiters:['${','}']
})
/**
* 插值语法 标签内部使用 解析标签内容
* {{xxx}}
*
* xxx js的表达式(能生成一个结果)
* a
* 1+2
* fn()
* a>b ? 3:2
*
* 不能放js语句
* if for
*
* 一、内容渲染指令
* v-html
* 将值解析成 dom结构 放到指定的使用指令的节点中
* 覆盖节点中原本的 内容 (类似于 innerHTML)
* <div id='app' v-html="span">
123
</div>
span: '<span>我是span</span>'
* v-text
不解析为dom结构 放到指定的使用指令的节点中
覆盖节点中原本的 内容(类似于 innerText)
* < div id=‘app’ v-Text=“span”>
123
</ div>
span: ‘我是span’
* 二.条件渲染指令
v-if
<span v-if="bool">我是一个加载中的图标</span>
bool:false false dom就不出现 true dom就渲染
v-else 如果v-if 内的值为false v-else指令的dom就渲染
如果v-if 内的值为true v-else指令的dom就不渲染
注意:如果else和if要一起使用 之间不能有其他的干扰
<span v-if="bool">我是一个加载中的图标</span>
<span v-else>我是加载好的数据</span>
v-else-if
<span v-if="num>80">优秀</span>
<span v-else-if="num>=60&&num<= 80">一般</span>
<span v-else>不及格</span>
多个节点 同一个判断条件
<span v-if="bool">1</span>
<span v-if="bool">2</span>
<span v-if="bool">3</span>
<span v-if="bool">4</span>
<span v-if="bool">5</span>
进一步改进
<div v-if="bool">
<span>1</span>
<span >2</span>
<span >3</span>
<span >4</span>
<span >5</span>
</div>
再进一步改进 template 不会被渲染
<template v-if="bool">
<span>1</span>
<span >2</span>
<span >3</span>
<span >4</span>
<span >5</span>
</template>
*/
内容渲染指令
条件渲染指令
v-if
条件性的渲染一块内容 判断为 true才会被渲染
v-else
两个分支 同一个判断语句
注意: 结构不能被打断
v-else-if
多个分支 不同的判断语句
应用: 加载中的图标 回到顶部 侧边栏
v-show
修改dom的display
v-if和v-show的区别
v-if为false 元素直接不存在 什么都不做
v-show为false 只是不显示 元素是在的 存在于dom里面
如果你的dom 需要频繁切换状态 使用v-show
只切换少次状态 使用v-if
<p v-if="list.length">{{list}}</p>
list: []
setTimeout(() => {
vm.list = ['你', '我']
}, 1000)
v-once (了解)
解除动态的关联 只会渲染一次 (一次性的指令)
<span v-once="bool">我是小图标</span>
修改 bool值 视图不会发生改变
属性绑定指令
v-bind
<img v-bind:src="imgSrc" alt="">
v-bind:属性='动态属性值' 属性值 识别为 Vue实例内的数据 {{}}
简写方式
<img :src="imgSrc" alt="">
v-bind 动态绑定class
第一种方式(字符串的写法)
//class类名 不确定 比如说是请求获取的类名
<span class="box" v-bind:class="iconClass">我是span</span>
iconClass:'icon-font'
第二种方式(对象的写法)
<span class="box" :class="{iconClass:bool}">我是span</span>
<!-- :class="{类名:判断条件}" -->
bool为 true 具备iconClass这个类名
false 没有这个类名
<span class="box" :class="{iconClass:bool}">1</span>
<br>
<span class="box" :class="{iconClass:!bool}">2</span>
<br>
<button v-on:click="fn">修改bool</button>
data() {
return {
bool: true
}
},
methods: {
//自定义的方法(函数)
fn: function () {
this.bool = !this.bool
}
},
第三种方式(数组的写法)
// 数组内 可以写字符串形式 也可以写对象形式
<span class="box" :class="['icon-font','iconClass']">1</span>
<span class="box" :class="['icon-font',iconClass]">1</span>
iconClass:'iconClass',
配合写法
<span class="box" :class="[{'icon-font':!bool},{iconClass:bool}]">1</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>
<style>
.box{
font-size: 25px;
width: 10px;
background-color:pink;
}
.icon-font{
color: red;
}
.iconClass{
background-color: aqua;
}
</style>
</head>
<body>
<div id="app">
<!-- <span v-once="bool">我是一个加载中的图标</span> -->
<!-- <img v-bind:src="imgSrc" alt=""> -->
<!-- <img :src="imgSrc" alt="" width="60px"> -->
<!-- <span v-show="bool">我是一个加载中的图标</span> -->
<!-- <span v-if="bool">我是一个加载中的图标</span> -->
<!-- <span v-show="list.length">{{list}}</span> -->
<!-- <span class="box" :class="iconClass">我是一个加载中的图标</span> -->
<!-- <span class='box' :class="{iconClass:bool}">我是span</span><br> -->
<!-- :class="{类名:判断条件}"
bool为 true 具备iconClass这个类名
false 没有这个类名
-->
<!-- <span class="box" :class="{iconClass:bool}">1</span><br> -->
<!-- <span class="box" :class="{iconClass:!bool}">2</span> -->
<!-- 设置一个点击事件 来回切换 1 2 -->
<!-- <button v-on:click="fn">修改bool的值</button> -->
<!-- 数组的写法
数组内 可以写字符串形式 也可以写对象形式
-->
<!-- <span class="box" :class="['icon-font','iconClass']">1</span> -->
<!-- <span class="box" :class="['icon-font',iconClass]">1</span>
iconClass:"iconClass"
-->
<!-- 配合写法 -->
<!-- <span class="box" :class="[{'icon-font':!bool},{iconClass:bool}]">1</span> -->
<!-- 方法一 -->
<!-- <Span class="box" v-bind:style="{fontSize:size}">1</Span> -->
<!-- 方法二 -->
<!-- <Span class="box" v-bind:style="{fontSize:size+'px',opacity:num}">1</Span> -->
<!--
v-bind:style="{属性名:动态属性值}"
属性名 两种写法 fontSize 'fontsize'
-->
<!-- <button v-on:click="fn1">字体增大,透明度减少</button> -->
<!-- 方法二: 数组的方式-->
<span class="box" v-bind:style="[handleWidth(),handleColor()]">123</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
// Vue.config.productionTip = false;
const vm = new Vue({
el:'#app',
data(){
return{
bool :false,
// list:[],
// imgSrc:"1.jpg",
// 异步请求来的数据
// iconClass:'icon-font'
iconClass:"iconClass",
// size:'60px',
size:20,
num:1,
color:'red'
}
},
methods: {
// 自定义的方法(函数)
fn: function(){
this.bool = !this.bool
},
fn1:function(){
this.size++;
this.num -=0.1
},
handleWidth(){
return {width: this.size +'px'}
},
handleColor:function(){
return {background: this.color}
}
},
})
// 模拟请求数据过程
setTimeout(() =>{
vm.list = ['nhao1','wshui']
},1000)
</script>
</body>
</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>
<style>
.box{
background-color: aqua;
}
</style>
</head>
<body>
<div id="app">
<img v-bind="attr"/>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
// Vue.cofig.productionTip = false;
new Vue({
el:"#app",
data(){
return{
attr:{
src:'1.jpg',
class:{box:true},
width:200
},
}
}
})
</script>
</body>
</html>
总结
写法 v-bind:class='xxx' 简写 :class='xxx' xxx可以是字符串 可以是对象(用的较多) 可以是数组
v-bind 动态绑定 style
某一个样式 有动态的变化 比如高度 透明度
第一种方式 对象写法 (常用)
<span class="box" v-bind:style="{属性名:动态属性值}">1</span>
<!-- 属性名 两种写法 fontSize 'font-size' -->
<span class="box" v-bind:style="{fontSize:size+'px'}">1</span>
<button v-on:click="fn">字体变大</button>
size: 60
methods: {
//自定义的方法(函数)
fn: function () {
this.size++
}
},
<span class="box" v-bind:style="{fontSize:size+'px',opacity:num}">1</span>
第二种方式 数组写法 (了解)
//将多个样式 应用到同一个元素上
<span class="box" v-bind:style="[handleWidth(),handleColor()]">1</span>
<span class="box" v-bind:style="[{ width: size + 'px' },{ backgroundColor: color }]">1</span>
data() {
return {
size: 60,
color: 'red'
}
},
handleWidth() {
// 一通计算 width.....
return { width: this.size + 'px' }
},
handleColor() {
// 一通计算 color.....
return { backgroundColor: this.color }
}
多个属性同时绑定 (了解)
<img v-bind="attr">
attr: {
src: '01.jpg',
class: { iconClass: true },
width: 100
},
事件绑定指令
v-on 绑定事件的指令
监听 dom 点击 拖拽 滑入滑出 键盘事件
基础使用
<span>苹果</span>
<button v-on:click="num--"> - </button>
<span>{{num}}箱</span>
<button v-on:click="num++"> + </button>
<!-- <button v-on:事件名="事件处理逻辑"> + </button> -->
<span>苹果</span>
<button v-on:click="decrease"> - </button>
<span>{{num}}箱</span>
<button v-on:click="increase"> + </button>
<!-- v-on:事件名="函数名" 函数不需要加括号 -->
methods: {
decrease() {
this.num = Math.max(0, --this.num)
},
increase() {
this.num++
}
},
// 简写方式
// @click ===> v-on:click 简写的时候 : 开头是属性绑定 @开头是事件绑定
// <button @click="decrease"> - </button>
注意
1.函数作为事件函数是 使用不需要加括号
2.methods内的函数 内部的this指向 vm 要用data中的数据 this.数据名
3.this指向问题
changeNum() {
console.log(this);//指向vm
setTimeout(function () {
console.log(this);//指向window
this.num = 10086
}, 1000)
}
改成这样
changeNum() {
console.log(this);//vm
setTimeout(() => {
console.log(this);//vm
this.num = 10086
}, 1000)
}
methods内的函数内部 回调函数==> 温和无刺激的 箭头函数 要不然的话 this指向 window
changeNum: () => {
console.log(this); //window
this.num = 10086
},
changeNum: function () {
console.log(this);//vm
this.num = 10086
},
被Vue管理的函数 methods里面的函数 使用普通函数
不被Vue管理的函数 使用箭头函数