声明式渲染/文本插值
语法:{{ 表达式 }} 下面是vue变量
{{ msg }}
{{ obj.name }}
{{ obj.age>=18 ? '成年了':'未成年'}}
目标:
给标签属性设置vue变量的值
vue指令, 实质上就是特殊的 html 标签属性, 特点: v- 开头
每个指令,都有独立的作用
总结:
把vue变量的值,赋予给dom属性上,影响标签显示效果,
只要前面加了冒号: 后面引号里就是js代码 js代码里的英文单词就是变量
没有冒号就是字符串
目标:
给标签绑定事件
语法:
v-on:事件名=“要执行的少量代码”
v-on:事件名=“methods中的函数”
v-on:事件名=“methods中的函数(实参)”
简写:
vue指令@事件名=“methods中的函数”
总结:
常用@事件名,给dom标签绑定事件,以及=右侧事件处理函数
简写
变量v-bind :
v-on @事件名=“methods中的函数”
你要买商品的数量:{{count}}
目标:
vue事件处理函数中,拿到事件对象
语法:
无参数,通过形参直接接收
有参数,通过 $event 指代事件对象传给事件处理函数
目标:
在事件后面.修饰符名 - 给事件带来更强大的功能
语法:
@事件名.修饰符=“methods里的函数”
.stop - 阻止事件冒泡
.prevent - 阻止默认行为
.once - 程序运行期间,只触发一次事件处理函数
总结:
修饰符给事件扩展额外功能
目标:
给键盘事件,添加修饰符,增强能力
语法:
@keyup.enter - 监测回车按键
@keyup.esc - 监测返回按键
总结:
多使用事件修饰符,可以提高开发效率,少去自己判断过程
this.msg=this.msg.split("").reserve().join("")
字符串分隔为数组, 翻转顺序, 数组再拼接为字符串 再返回给msg变量
!!!以后想在函数里访问别的变量,得用this调用
{{ str }}
目标:
把value属性和vue数据变量,双向绑定到一起;
语法:
v-model=“vue数据变量”
双向数据绑定:
数据变化 —> 视图自动同步
视图变化 —> 数据自动同步
用户
密码
来自于:
爱好:
画画
听歌
看动漫
性别:
男
女
自我介绍
总结:
本阶段 v-model 只能用在表单元素上,以后学组件后讲 v-model 高级用法
目标:
让 v-model 拥有更强大的功能;
语法:
.trim 去除首尾空白字符
.lazy 在change时触发而非input时
年龄:
人生格言:
自我介绍:
总结:
v-model修饰符,可以对值进行预处理,非常高效好用
目标:
更新DOM对象的innerText / innerHTML
语法:
v-text=“vue数据变量”
v-html=“vue数据变量”
注意:
会覆盖插值表达式
总结:
v-text把值当成普通字符串显示,v-html把值当做html解析
目标:
控制标签的隐藏或出现
语法:
原理:
高级:
v-else使用
v-if的原理:
当 `v-if` 元素被触发,元素及其所包含的指令/组件都会销毁和重构。v-if后面的条件为false时,对应的元素以及其子元素不会渲染
v-if判断语句用,v-else则是和v-if一起出现,
v-else必须要和v-if匹配使用,v-else不能单独使用。 只有v-if的值为false时,v-else模块才会显示出来。
当v-if判断为true时,v-else不执行;
当v-if判断为false时,v-else才执行。
v-else-if会在多个判断语句时使用到,但不常用。
v-else使用
v-show的盒子
v-if的盒子
我成年了
还得多吃饭
总结:
使用v-show和v-if以及v-else指令,方便通过变量控制一套标签出现/隐藏
Title
优秀
良好
及格
不及格
{{result}}
目标:
列表渲染,所在标签结构,按照数据数量,循环生成
{{item}}
{{item}} ---{{index}}
语法:
数组对象的key值有id用id, 没id用索引
无key - 就地更新 有key - 值为索引 有key - 值为id
1.数组
v-for="(值变量名,索引变量名) in 目标结构" :key="index"
v-for="(item,index) in arr" :key="index"
2.数组对象
v-for=“(值变量名) in 目标结构” :key="obj.id"
v-for=“obj in arr” :key="obj.id"
3.
最后补一个li, 然后从第二个往后, 都要更新内容
根元素没变, 子元素没变, 元素内容改变
1v-for先循环产生新的DOM结构, key是连续的, 和数据对应
2然后比较新旧DOM结构, 找到区别, 打补丁到页面上
目标结构:
可以遍历数组/对象/数字/字符串(可遍历结构)
口诀: 想让谁循环生成, v-for就写谁身上 in两边一定要有空格
注意:
v-for的变量名只能用到v-for里
临时变量名不能用到v-for范围外
学生姓名
-
{{index}}---{{item}}
学生详细信息
-
{{ obj.name }}
{{ obj.sex }}
{{ obj.hobby }}
老师信息
{{ key }} -- {{ value }}
序号
{{ i }}
总结:
vue最常用指令,铺设页面利器,快速把数据赋予到相同的dom结构上循环生成
目标:
当v-for遍历的目标结构改变,Vue触发v-for的更新
vue不能监测到数组里赋值的动作而更新,如果需要请使用Vue.set() 或者this.$set(), 或者覆盖整个数组
口诀:
数组变更方法,就会导致v-for更新,页面更新
数组非变更方法,返回新数组,就不会导致v-for更新,
1.数组改变了页面也会更新,方法本身会修改js 数组本身的时候
这些方法会触发原始数组改变, v-for会监测到并更新页面
push() pop() shift() unshift() splice() sort() reverse()
这些方法不会触发v-for更新:
slice() filter() concat()
concat()
2.可采用覆盖数组或this.$set()
1.截取 不触发原数组更改 解决v-for更新 - 覆盖原始数组
// slice不会改变原始数组
// this.arr.slice(0, 3)
let newArr = this.arr.slice(0,3)
this.arr = newArr
等同 this.arr = this.arr.slice(0,3)
2.解决-使用Vue.set() 或者this.$set()
this.$set(this.arr,0,1000)
}
参数
1: 更新目标结构 参数
2: 更新位置 第几个参数
3: 更新值 要替换的内容
-
{{val}}
目标:
用v-bind给标签class设置动态的值
语法:
:class="{类名:布尔值}"
总结:
就是把类名保存在vue变量中赋予给标签
动态class
目标: 给标签动态设置style的值
语法:
:style="{css属性: 值}"
动态style
总结:
动态style的key都是css属性名
目标:
转换格式,过滤器就是一个函数,传入值返回处理后的值
过滤器只能用在, 插值表达式和v-bind表达式
Vue中的过滤器场景:
字母转大写,输入"hello",输出"HELLO"
字符串翻转,“输入hello,world”,输出"dlrow,olleh"
语法:
在main里设置,这里是引号,逗号,只能有一个
语法
Vue.filter(“过滤器名” , (值) =>处理结果)
// 1.全局注册过滤器
Vue.filter("test", function (val, s) {
return val + s
})
// 1.全局注册过滤器 过滤器接参数
Vue.filter("reverse", val => {
return val.split("").reverse().join(s)
})
和data方法并列设置,这里是冒号
filters: {过滤器名字: (值) => {return “返回处理后的值”}
例子:
全局定义字母都大写的过滤器局部定义字符串翻转的过滤器
原来的样子:{{ msg }}
使用翻转过滤器:{{ msg | reverse}}
鼠标长停
总结:
把值转成另一种形式,使用过滤器,Vue3用函数替代了过滤器;
全局注册最好在main.js中注册,一处注册到处使用;
vue过滤器-传参和多过滤器目标:
可同时使用多个过滤器,或者给过滤器传参
过滤器传参: vue变量 | 过滤器(实参)
多个过滤器: vue变量 | 过滤器1 | 过滤器2
原来的样子:{{ msg }}
使用翻转过滤器:{{ msg | reverse('|')}}
鼠标长停
总结:
过滤器可以传参,还可以对某个过滤器结果,后面在使用一个过滤器
计算属性使用场景
一个数据,依赖另外一些数据计算而来的结果
语法:
computed:{
"计算属性名"(){
return "值"
}
}
需求:
求2个数的和显示到页面上
{{ num }}
注意:
计算属性也是vue数据变量,所以不要和data里重名,用法和data相同
总结:
一个数据,依赖另外一些数据计算而来的结果
计算属性的好处计算属性是基于它们的依赖项的值结果进行缓存的,
只要依赖的变量不变,都直接从缓存取结果
依赖的变量 变化, 函数会"自动"重新执行并重新缓存
computed计算属性只打印一次,计算属性有缓存功能
methods函数方法打印了3次
{{ reverseMessage }}
{{ reverseMessage }}
{{ reverseMessage }}
{{ getMessage() }}
{{ getMessage() }}
{{ getMessage() }}
总结:
计算属性根据依赖变量结果缓存,依赖变化重新计算结果存入缓存,比普通方法性能更高
目标:
计算属性也是变量,如果想要直接赋值,需要使用完整写法
语法:
computed:{
"属性名":{
set(值){
},
get(){
return"值"
}
}
}
需求:
计算属性给v-model使用
页面准备输入框
姓名:
总结:
想要给计算属性赋值,需要使用set方法
目标:
可以侦听data/computed属性值改变
语法:
watch:{
"被侦听的属性名"(newVal,oldVal){
}
}
完整例子代码:
总结:
想要侦听一个属性变化,可使用侦听属性watch
vue侦听器-深度侦听和立即执行目标:
侦听复杂类型,或者立即执行侦听函数
语法:
watch:{
"要侦听的属性名":{
immediate:true, //立即执行
deep:true, //深度侦听复杂类型内变化
handler(newVal,oldVal){
},
}
}
完整例子代码:
总结:
immediate立即侦听,deep深度侦听,handler固定方法触发
目标:
每个组件都是一个独立的个体,代码里体现为一个独立的 .vue文件
口诀:
哪部分标签复用,就把哪部分封装到组件内
(重要):
组件内 template只能有一个根标签
组件内data必须是一个函数,独立作用域
步骤:
1.创建组件:
封装标签+样式+js - 组件都是独立的, 为了复用;
2.注册组件:
创建后需要注册后再使用;
全局入口在 main.js , 在new Vue之上注册
语法:
import Vue from 'vue'
import 组件对象 from 'vue文件路径'
Vue.component("组件名",组件对象)
main.js -演示 案例:
目标: 全局注册 (一处定义到处使用)
1. 创建组件 - 文件名.vue
2. 引入组件 import Pannel from './components/Pannel'
3. 全局 - 注册组件 /*
语法:
Vue.component("组件名", 组件对象) */ Vue.component("PannelG", Pannel)
全局注册 PannelG 组件名后,就可以当做标签在任意Vue文件中 template 里用;
单双标签都可以或者小写加 - 形式,运行后,会把这个自定义标签当做组件解析,使用组件里封装的标签替换到这个位置;
vscode会自动补全,爱用哪个用哪个
语法:
import 组件对象 from 'vue文件路径'
export default { component: { "组件名": 组件对象 } }
任意 vue文件中引入,注册,使用
案例:
案例:折叠面板
组件使用总结:
1.(创建)封装 html+css+vue到独立的 .vue文件中
2.(引入注册)组件文件 => 得到组件配置对象
3.(使用)当前页面当做标签使用
目标:
解决多个组件样式名相同,冲突问题
需求:
div标签名选择器,设置背景色
问题:
发现组件里的div和外面的div都生效了
解决:
给Pannel.vue组件里 style标签上加上 scoped属性
在style上加入 scoped属性,就会在此组件的标签上加上一个随机生成的data-v开头的属性
而且必须是当前组件的元素,才会有这个自定义属性,才会被这个样式作用到
总结:style 上加 scoped,组件内的样式只在当前vue组件生效
父传子口诀(步骤)是什么?子组件内, props定义变量, 在子组件使用变量父组件内, 使用子组件, 属性方式给props变量传值
需求:
封装一个商品组件 MyProduct.vue ,外部传入具体要显示的数据
步骤:
案例:
子 : components/MyProduct.vue
- 准备标签
<--使用变量-->
标题: {{ title }}
价格: {{ price }}元
{{ intro }}
App.vue中使用组件
script>
// 1. 创建组件 (.vue文件)
// 2. 引入组件 import Product from './components/MyProduct'
export default {
data(){
return {
str: "好贵啊, 快来啊, 好吃"
}
},
// 3. 注册组件
components: {
// Product: Product
// key和value变量名同名 - 简写 Product
}
}
总结:
组件封装复用的标签和样式,而具体数据要靠外面传入
目标:
把数据循环分别传入给组件内显示
案例:
在vue中需要遵循单向数据流原则
1.父组件的数据发生了改变,子组件会自动跟着变
2.子组件不能直接修改父组件传递过来的 props , props是只读的
父组件传给子组件的是一个对象,子组件修改对象的属性,是不会报错的,对象是引用类型,互相更新
总结:
props的值不能重新赋值,对象引用关系属性值改变,互相影响
从父到子的数据流向,叫单向数据流
原因:子组件修改,不通知父级,造成数据不一致性
如果第一个MyProduct.vue内自己修改商品价格为5.5 , 但是App.vue里原来还记着18.8 ,数据 不一致 了
所以 Vue规定 props里的变量,本身是只读的
总结:
props变量本身是不能重新赋值的
问题:
子组件内能改变, 父传入的数据吗?
解决:
要通过自定义事件$emit() 方法传值 影响父组件接收,然后事件监听 数据响应式 来影响子组件
function (val) {
console.log(val);
}
在父组件中给子组件绑定一个自定义的事件,子组件通过$emit()触发该事件并传值。
目标:
从子组件把值传出来给外面使用
语法:
子组件通过$emit广播事件
父组件 监听这个事件,并接受数据
methods: { // val就会接收到父组件这个188的参数 // 接收子组件data里的数据 testFn(val) { console.log("我是父组件的打印" + val); //我是父组件的打印q,w }, },
fn(){ this.$emit("whd", 188); }// 如果希望传data里的list data() { return { list: ["q", "w"], }; }, methods: { fn(){ this.$emit("whd", this.list); } }
案例:
this.$emit('subprice', this.index, 1)
标题: {{ title }}
价格: {{ price }}元
{{ intro }}
@subprice="fn"
App.vue
总结:
父自定义事件和方法,等待子组件触发事件给方法传值
目标:
常用于跨组件通信时使用
两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的.这时候可以使用通用的组件通讯方案:事件总线( event-bus )
兄弟组件传值
1.创建空白Vue对象并导出 eventBus.js
2. 给A组件 绑定一个自定义事件,通过eventBus.$emit()触发该事件并传值,
3. B组件在组件 监听这个自定义事件 创建时的created阶段通过 eventBus.$on() 接收数据
通过中央通信 let bus = new Vue()
A组件:methods :{
sendData(){
bus.$emit('getData',value)
} 发送
B组件:created(){
bus.$on(‘getData’,(value)=>{value就是接收的数据})
} 进行数据接收
什么时候使用eventBus技术?当2个没有引用关系的组件之间要通信传值eventBus技术本质是什么?空白Vue对象, 只负责$on和$emit
import Vue from 'vue'
export default new Vue()
// 1. new Vue()
// 2. 用到了 Vue就需要导入 import
// 3. 导出空白vue对象
List.vue注册时间,等待接收要砍价的值,准备兄弟页面
import eventBus from "../EventBus";
引入的是文件夹
当import遇到文件夹 会自动找里面的index.js文件,
并把里面的东西导过来 赋值到变量上 用eventBus这个变量名接收
如果文件名不叫index.js需要把名字写全
eventBus.$on监听事件(''事件名',函数体) 组件一创建完 空白对象就触发 自定义事件 接收传值
组件创建完毕,监听send事件
页面一加载 立马开启监听 中介是不是收到兄弟的传值了 eventBus.$on("send")
created(){}是在list.vue这个组件被创建时自动执行这个方法
所以用created(){} 生命周期这个天然方法 页面一加载 会立马开启监听事件 生命周期函数
是在list.vue这个组件被创建时 自动执行这个方法
// 3. 组件创建完毕, 监听send事件 created() { eventBus.$on("send", (index, price) => { // 价格砍掉再赋值给左边的变量 conslole.log(index,price) this.arr[index].proprice=price }); },
created(){}是在list.vue这个组件被创建时自动执行这个方法
在创建的时候立刻用$on绑定一个自定义事件名,
当事件被触发的时候,要接一个索引和要砍掉的价格
原来是在app.vue里砍一刀的 现在要在List.vue
-
{{ item.proname }}
{{ item.proprice }}
import eventBus from '../EventBus'
点击 砍一刀 按钮时 触发这个函数 向空白对象身上触发刚才监听的 同名自定义事件,把值丢过去
methods: { subFn(){ eventBus.$emit("send", this.index, 1) // 跨组件 } }
MyProduct_sub.vue
标题: {{ title }}
价格: {{ price }}元
{{ intro }}