1、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>
<!-- 1.导入vue.js文件 -->
<script src="./vue.js"></script>
</head>
<body>
<!-- 2.写HTML结构 -->
<div id="app">{{ message }}</div>
<script>
// 3.创建vue实例
// (1)导入vue.js本质是得到构造函数vue
// (2)app是调用构造函数得到的实例(app叫做vue实例)
const app = new Vue({
// el是挂载点
el:"#app",
// data是要渲染的数据
data:{
message:'Hello Vue!'
}
})
</script>
</body>
</html>
2、vue插值表达式
<!-- 2.HTML结构 -->
<div id="app">
{{ name }}
<br>
{{ age>30?true:false }}
</div>
<!-- 1. 插值语法:{{ data数据 }}
2.支持数组和对象取值语法
3.支持二元运算
4.支持三元运算
-->
3、v-text指令
<!-- 2.html -->
<div id="app">
<p>喜剧之王 {{ name }}</p>
<p v-text="age">今年</p>
</div>
<!-- 1.学习目标: v-text 指令
作用: 设置元素的文本 innerText
v-text: 替换标签所有的文本(全局替换,之前的文本会被覆盖)
插值: 只替换{{}} 部分 (局部替换)
-->
4、v-html指令
<!-- HTML结构 -->
<div id="app">
<p v-text="name">我的名字叫</p>
<p v-html="name">我的名字叫</p>
</div>
<!--
1.学习目标 : v-html 指令
2.学习路线
作用: 设置元素的innerHTMl
v-text与v-html区别:
v-text: 不能解析字符串中的标签
v-html: 能解析字符串中的标签
-->
5、v-on指令
<!-- HTML结构 -->
<div id="app">
<button v-on:click="doClick">点我</button>
<!-- 标准写法 -->
<div class="box" v-on:mouseenter="doEnter"></div>
<hr />
<!-- 简洁写法 -->
<div class="box" @click="doClick" @mouseenter="doEnter"></div>
</div>
<!--
1.学习目标 : v-on 指令
2.学习路线
a.作用: 给元素绑定事件
b.语法:
标准语法: v-on:事件名 = "方法名"
简洁语法: @事件名 = "方法名"
c.注意点
事件名就是原生事件名去掉on
事件方法定义在vue实例的methods对象中
-->
6、vue事件修饰符
(1) @keydown.enter : 监听enter按键
(2) @click.prevent : 阻止默认行为
(3) @click.stop : 阻止冒泡
7、vue事件参数
<button @click="doDelete( news.id, $event )">删除</button>
// (1)默认情况下,vue的事件方法也有事件对象
// (2)如果给事件传参,则会覆盖默认事件对象 @click='方法名(实参)'
// (3)如果希望 默认时间对象 + 自己参数 同时获取,就可以使用 $event @click='方法名(实参,$event)'
doDelete(id, e) {
console.log(id);
console.log(e);
}
8、v-bind指令
<!-- 标准写法 -->
<img v-bind:src="img" alt="">
<!-- 简洁写法 -->
<img :src="img" alt="">
// 1.默认情况下,只有vue的语法才可以使用data数据.原生的html属性不能使用vue的数据
// 2. 如果希望原生的html也可以使用vue的数据,就可以使用v-bind指令
// (1)v-bind指令作用:让原生属性也可以使用vue的数据
// (2)v-bind语法
// 标准语法:v-bind属性名="vue的数据"
// 简洁写法: :属性名="vue数据"
// (3)总结:在vue中,任何属性只要加 : 就代表访问vue的数据
9、vue的样式绑定
<!-- HTML结构 -->
<div id="app">
<button @click=" flag = !flag">切换样式</button>
<div :class="{ greenBorder:flag, 'red-box':flag }"></div>
<hr />
<div :style="{ width:w,height:h,'background-color':bgc}"></div>
</div>
<script>
/* 创建vue实例 */
let app = new Vue({
//el:挂载点
el: "#app",
//data: 要渲染的数据
data: {
flag:true,
w:'100px',
h:'200px',
bgc:"purple"
},
methods: {
}
})
// vue样式绑定: 设置元素的 class 和 style
// 1.设置元素的 class
// 语法 :class="{ 类名:布尔值 }"
// 注意点 如果类名有 - ,需要用引号 '' 包起来
10、v-for指令
<!-- HTML结构 -->
<div id="app">
<ul>
<li v-for="(item,index) in list">
<span>第 {{ index }} 个元素</span>
<span>名字:{{ item.name }}</span>
<span>年龄:{{ item.age }}</span>
</li>
</ul>
</div>
<!--
1.学习目标: v-for 指令
2.学习路线
(1)作用:遍历数组,并重复生成对应长度的相同标签
(2)语法: v-for="item in 数组名"
遍历下标: v-for="(item, index) in items"
(3)细节: 这个指令写在哪一个元素身上,就重复生成哪一个元素
3.了解 v-for也可以遍历对象
v-for="(value,key,index) in 对象名"
-->
10、v-model双向数据绑定
<!-- HTML结构 -->
<div id="app">
<input type="text" v-model="name" >
<p>我的名字是:{{ name }} </span></p>
<button @click="doClick">点我修改model</button>
</div>
<!--
1.学习目标 : v-model 指令
2.学习路线
(1)作用 : 双向数据绑定
a. 表单元素的值进行了修改,这个变量的值也会跟着修改
b. 这个变量的值进行了修改,表单元素的值也会跟着修改
(2)语法: v-model="变量名"
(3)注意点:
a. v-model只能用于表单元素
b. 变量名要定义在data对象中
-->
11、v-model修饰符
<!-- HTML结构 -->
<div id="app">
<input type="text" placeholder="请输入姓名" v-model.lazy="name"><br>
<p>您的姓名是:{{ name}} </p><hr>
<input type="text" placeholder="请输入年龄" v-model.number="age"><br>
<p>您的年龄是:{{ age + 1}} </p><hr>
<input type="text" placeholder="请输入分数" v-model.trim="grade">
<p>您的分数是:{{ grade}} </p><hr>
</div>
<!--
1.学习目标: v-model修饰符用法
2.语法
v-model.lazy : 在change时触发而非inupt时(失去焦点或enter键的时候才会绑定数据)
v-model.number : 输入字符串转为有效的数字 (有效:能转数字就转,不能转就不转)
v-model.trim : 去掉字符串首尾空格
-->
12、v-if指令
<!-- HTML结构 -->
<div id="app">
<input type="text" placeholder="请输入考试分数" v-model.number="score">
<h2>你的考试分数为:</h2>
<hr>
<h3 v-if="score >= 90">爸爸给你买法拉利</h3>
<h3 v-else-if="score >= 80">爸爸给你买保时捷</h3>
<h3 v-else-if="score >= 60">爸爸给你买奥迪</h3>
<h3 v-else="score < 60">爸爸给你爱的掌声</h3>
</div>
<!--
1.学习目标: v-if指令
2.学习路线:
(1)作用: 根据条件渲染数据
(2)语法:
单分支: v-if="条件语句"
双分支: v-else
多分支: v-else-if="条件语句"
(3)注意点
v-else的前面 必须要有 v-if 或者 v-else-if
-->
13、v-show指令
<!-- HTML结构 -->
<div id="app">
<p v-if="flag">我是v-if渲染出来的</p>
<p v-show="flag">我是v-show渲染出来的</p>
</div>
<!--
1.学习目标: v-show 指令
2.学习路线:
(1)作用: 设置元素的display属性值
(2)语法: v-show="属性值"
属性值为true: 元素的display:block
属性值为false: 元素的display:none
(3)v-show与v-if区别
v-if : 条件渲染。 如果不满足条件,则该元素不会添加到DOM树中
*应用场景:不需要频繁切换
v-show: 显示与隐藏。 只是修改元素的display属性值
*应用场景:需要频繁切换
-->
14、vue中key值的作用
/*
1.学习目标 : vue中key值作用
* (1)key值给元素添加唯一的标识符(类似于人的身份证)
* (2)可以让vue更高效的渲染页面
2.应用场景:
2.1 使用v-if 切换元素
* (较少)当使用v-if切换两个相同的dom结构的元素的时候,由于两个元素DOM结构一致,vue认为你没有切换,
导致渲染出问题.这个时候就需要添加key值,让vue更好的渲染
2.2 使用v-for 渲染列表
* (必用)实际vue开发中,每一个v-for都要加key值
3.虚拟DOM和真实DOM
(1)真实DOM: documen.querySelector('选择器')
* 特点: 内存中的属性很多,有上百个
(2)虚拟DOM: 本质是一个js对象
* 特点: 只存储部分有用的属性
4.虚拟DOM好处
(1)提高了更新DOM的性能(不用把页面全删除重新渲染)
(2)存储更少的数据(节省内存)
5.vue渲染虚拟DOM流程
(1)一开始会把真实DOM上百个属性提取核心属性出来,生成虚拟VNode
(2)使用 object.dedineProperty() 监听data变化
(3)新旧 虚拟DOM对比,找不同的地方
* 底层: 使用 diff算法来找新旧 VNode 不同点
(4)更新虚拟DOM
(5)将虚拟DOM渲染到真实DOM
(总结) key值原理: 让diff算法更好 '辨识' VNode
*/
15、nextTick使用
<script>
// 目标: 点按钮(消失) - 输入框出现并聚焦
// 1. 获取到输入框
// 2. 输入框调用事件方法focus()达到聚焦行为
export default {
data(){
return {
flag: false,
}
},
methods: {
async btn(){
this.flag = true;
/* 1.以下代码无法实现输入框聚焦
原因: data变化更新DOM是异步的,输入框还没有挂载到真实DOM上
*/
// this.$refs.myInp.focus()
/* 2.解决方案:使用$nextTick
(1) $nextTick是一个异步微任务,等待当前函数的dom渲染结束后执行
(2) $nextTick类似于一个非常高级的定时器,自动追踪DOM更新,更新好了就触发
*/
// this.$nextTick(() => {
// this.$refs.myInp.focus()
// })
/* 3.拓展: await异步函数
原因: $nextTick() 返回的是一个Promise对象(底层基于promise)
*/
await this.$nextTick()
this.$refs.myInp.focus()
}
}
}
</script>
16、computed计算属性
计算属性语法 :
a. 在vue实例的computed对象中声明一个函数 (计算属性的属性名)
b. 在这个函数中 return 返回值 (计算属性的属性值)、
计算属性特点及原理介绍 :
a. 计算属性本质是一个函数
b. 计算属性的值就是函数的返回值
c. 缓存机制(提高性能)
(1)计算属性在第一次使用时,会执行一次函数体,之后就会将返回值缓存起来
(2)下一次使用计算属性的时候,不会执行这个函数,而是直接从缓存中读取
(3)只有当计算属性中的数据发生变化时,这个函数才会重新执行一次
computed:{
函数名:{
get(){
get是获取值
},
set(val){
set是修改值
}
}
}
16、watch侦听器
1.侦听器作用: 侦听data中某一个数据的变化
2.侦听器语法: data属性名(newVal,oldVal){}
3.面试点: 侦听器与计算属性区别
(1)计算属性有缓存,侦听器没有缓存
(2)侦听器只能检测一个数据变化,计算属性可以检测多个数据变化
(3)侦听器只能侦听data里面的数据,计算属性可以给vue实例新增属性
(4)侦听器支持异步操作,计算属性不支持异步操作.
watch: {
// // 普通侦听语法: 无法侦听引用类型
// username(newVal, oldVal) {
// console.log(newVal, oldVal); // 新数据和旧数据
// if (newVal === 'admin') {
// this.info = '当前用户已注册'
// } else {
// this.info = ''
// }
// }
// 深度侦听: 侦听引用类型
user: {
deep: true,
handler(newVal, oldVal) {
console.log(newVal, oldVal);
if (newVal.username === 'admin') {
this.info = '该用户已注册'
} else {
this.info = ''
}
}
}
}
mixin混入
1.将组件之中相同的代码抽离出来,创建mixin.js文件进行共享.
2.在组件中导入mixin.js文件,使用minxis:[]进行导入.
vue-cli 的使用
使用前要先用npm install -g @vue/cli 进行安装
创建项目:vue create “项目名”
组件注册
局部祖册
<script>
// 引入组件
import Dome from '@/components/Dome'
export default{
// 注册组件
components:{
Dome
}
// ..
}
</script>
全局注册
// 在main.js文件中引入组件
import Dome from '@/components/Dome'
// 注册组件
Vue.component('Dome',Dome)
组件通讯
父传子:
1.在子组件标签上定义自定义属性
2.子组件通过props进行数据接收
子传父:
1.在子组件标签上添加自定义事件
2.在子组件标签内使用$emit向父组件发出数据
3.父组件使用函数的事件源接收数据
非父子关系:
1.创建 eventBus.js模块,并向外共享一个 Vue 的实例对象
2.在数据发送方,调用 bus.$emit('事件名称',要发送的数据)方法触发自定义事件
3.在数据接收方,调用 bus.$on('事件名称',事件处理函数)方法注册一个自定义事件
使用子组件定义的方法:
1.在子组件标签上定义ref,然后用this.$refs.ref名.方法名()调用.
插槽
1.默认插槽
2.具名插槽
3.作用域插槽
路由
路由的两种工作模式
1.hash模式:地址带#号,兼容性好,app分享校验严格,地址会被标记不合法.
2.histiry模式:地址干净,兼容性略差,部署上线时,刷新页面会出现404的问题.
编程式导航和声明式导航
1.编程式导航:this.$router.push('/')
2.声明式导航:router-link标签里写上要跳转的路径.
vuex
state 存储数据
modules
actions 异步修改
getters
mutations 同步修改