Vue小字典

1.插值表达式

声明式渲染/文本插值
语法:{{ 表达式 }} 下面是vue变量

<template><div><h1>{{ msg }}</h1><h2>{{ obj.name }}</h2><h3>{{ obj.age>=18 ? '成年了':'未成年'}}</h3></div>
</template><script>
export default {data() {return{msg:"hello,world",obj : {name:"zs",age:18}}}
}</script><style></style>

2.vue指令-v-bind   :属性名=“vue变量”

目标:
给标签属性设置vue变量的值
vue指令, 实质上就是特殊的 html 标签属性, 特点: v- 开头
每个指令,都有独立的作用

语法:
v-bind:属性名=“vue变量”
简写:
:属性名=“vue变量”

总结:
把vue变量的值,赋予给dom属性上,影响标签显示效果,

只要前面加了冒号: 后面引号里就是js代码 js代码里的英文单词就是变量

没有冒号就是字符串

<!-- vue指令 v-bind属性动态赋值 -->
    <a v-bind:href="url">我是a标签</a>
    <img src="imgsrc" alt="">

3.vue指令-v-on         简写  @事件名=“methods中的函数”

目标:
给标签绑定事件
语法:
v-on:事件名=“要执行的少量代码”
v-on:事件名=“methods中的函数”
v-on:事件名=“methods中的函数(实参)”
简写:
vue指令@事件名=“methods中的函数”
总结:
常用@事件名,给dom标签绑定事件,以及=右侧事件处理函数

简写
变量v-bind   :
v-on     @事件名=“methods中的函数”

<template><div><p>你要买商品的数量:{{count}}</p><button v-on:click="count=count+1">增加1</button><button v-on:click="addFn">增加1个</button><button v-on:click="addcountFn(5)">增加5个</button><button @click="subFn">减少</button></div>
</template><script>
export default {data(){return{count:1,}},methods:{addFn(){this.count++},addcountFn(num){this.count += num},subFn(){this.count--}}
}
</script><style></style>

3.1. vue指令-@事件对象

目标:

vue事件处理函数中,拿到事件对象

语法:

无参数,通过形参直接接收

有参数,通过 $event 指代事件对象传给事件处理函数

<template><div><a @click="one" href="http://www.baidu.com">阻止百度</a><a @click="two(10,$event)" href="http://www.baidu.com">阻止去百度</a></div>
</template><script>
export default {methods:{one(e){e.preventDefault();},two(num,e){e.preventDefault();}}}
</script><style></style>

3.2.vue指令-@修饰符

目标:

在事件后面.修饰符名 - 给事件带来更强大的功能

语法:

@事件名.修饰符=“methods里的函数”

.stop - 阻止事件冒泡

.prevent - 阻止默认行为

.once - 程序运行期间,只触发一次事件处理函数

<template><div @click="fatherFn"><button @click.stop="btn">.syop阻止事件冒泡</button><a href="https://www.baidu.com" @click.prevent="btn">.prevent阻止默认行为</a><button @click.once="btn">.once程序运行期间,只触发一次事件处理函数</button></div>
</template><script>
export default {methods:{fatherFn(){console.log("father被触发了");},btn(){console.log(1);}}}
</script><style></style>

总结:

修饰符给事件扩展额外功能

3.3.vue指令-@按键修饰符

目标:
给键盘事件,添加修饰符,增强能力
语法:
@keyup.enter - 监测回车按键
@keyup.esc - 监测返回按键
总结:
多使用事件修饰符,可以提高开发效率,少去自己判断过程

<template><div><input type="text" @keydown.enter="enterFn"><hr><input type="text" @keydown.esc="escFn"></div>
</template><script>
export default {methods:{enterFn(){console.log("enter回车按键了");},escFn(){console.log("esc按键了");}}}
</script><style></style>

3.4.vue指令-@翻转世界

this.msg=this.msg.split("").reserve().join("")

字符串分隔为数组, 翻转顺序, 数组再拼接为字符串 再返回给msg变量

!!!以后想在函数里访问别的变量,得用this调用

<template><div><h1>{{ str }}</h1><button @click="reverseFn">翻转</button></div>
</template><script>
export default {data: function () {return {str: "hello World",};},methods: {reverseFn() {// this.str = this.str.split("").reverse().join("");let arr = this.str.split("");let arr2 = arr.reverse();this.str = arr2.join("");},},
};
</script><style>
</style>

4.vue指令 v-model

目标:
把value属性和vue数据变量,双向绑定到一起;
语法:
v-model=“vue数据变量”
双向数据绑定:
数据变化 —> 视图自动同步
视图变化 —> 数据自动同步

 <template><div><!-- v-model:是实现vuejs变量和表单标签value属性,双向绑定的指令 --><div><span>用户</span><input type="text" v-model="username"></div><div><span>密码</span><input type="text" v-model="pass"></div><div><span>来自于:</span><!-- 下拉菜单要绑定在select上 --><select v-model="from"><option value="北京市">北京</option><option value="南京市">南京</option><option value="天津市">天津</option></select></div><div><!-- (重要)遇到复选框, v-model的变量值非数组 - 关联的是复选框的checked属性数组   - 关联的是复选框的value属性--><span>爱好: </span><input type="checkbox" v-model="hobby" value="画画">画画<input type="checkbox" v-model="hobby" value="听歌">听歌<input type="checkbox" v-model="hobby" value="看动漫">看动漫</div><div><span>性别:</span><input type="radio" value="男" name="sex" v-model="gender">男<input type="radio" value="女" name="sex" v-model="gender">女</div><div><span>自我介绍</span><textarea v-model="intro"></textarea></div></div></template><script>export default {data(){return{username:"",pass:"",from: "",hobby: [], sex: "",intro: "",};// 总结:// 特别注意: v-model, 在input[checkbox]的多选框状态// 变量为非数组, 则绑定的是checked的属性(true/false) - 常用于: 单个绑定使用// 变量为数组, 则绑定的是他们的value属性里的值 - 常用于: 收集勾选了哪些值}}</script><style></style>

总结:
本阶段 v-model 只能用在表单元素上,以后学组件后讲 v-model 高级用法

vue指令 v-model修饰符

目标:
让 v-model 拥有更强大的功能;
语法:

v-model.修饰符=“vue数据变量”
.number 以parseFloat转成数字类型

.trim 去除首尾空白字符
.lazy 在change时触发而非input时

<template><div><div><span>年龄:</span><!-- .number修饰符 -把值parseFloat转载数值再赋予给v-model对应的变量 --><input type="text" v-model.number="age"></div><div><span>人生格言:</span><!-- .trim修饰 -去除首尾两边空格 --><input type="text" v-model.trim="motto"></div><div><span>自我介绍:</span><!-- .lazy修饰符 -失去焦点内容改变时(onchange事件),把内容同步给v-model的变量 --><textarea v-model.lazy="intro"></textarea></div></div>
</template><script>
export default {data() {return {age: "",motto: "",intro: ""}}
}
</script><style></style>

总结:
v-model修饰符,可以对值进行预处理,非常高效好用

5.vue指令 v-text和v-html

目标:
更新DOM对象的innerText / innerHTML
语法:
v-text=“vue数据变量”
v-html=“vue数据变量”
注意:
会覆盖插值表达式

<template><div><!-- v-text把值当成普通字符串显示 --><p v-text="str"></p><!--  v-html把值当做html解析 --><p v-html="str"></p></div>
</template><script>
export default {data(){return{str:"<span>我是一个span标签</span>"}}}
</script><style></style>

总结:
v-text把值当成普通字符串显示,v-html把值当做html解析

6.vue指令 v-show和v-if

目标:
控制标签的隐藏或出现
语法:

v-show=“vue变量”
v-if=“vue变量”

原理:

v-show用的display:none隐藏 (频繁切换使用)
v-if 直接从DOM树上移除

高级:
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使用

<template><div><!-- v-show或者v-ifv-show="vue变量"v-if="vue变量"--><h1 v-show="isOk">v-show的盒子</h1><h1 v-if="isOk">v-if的盒子</h1><!-- v-show隐藏: 采用display:none //频繁切换v-if隐藏: 采用从DOM树直接移除 //移除--><div><p v-if="age">我成年了</p><p v-else>还得多吃饭</p></div></div>
</template><script>
export default {data(){return{isOk:true,age:20}}
}
</script><style></style>

总结:
使用v-show和v-if以及v-else指令,方便通过变量控制一套标签出现/隐藏

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="app">
<!--  多重分支,不建议直接用标签,建议用计算属性去做--><h2 v-if="score>=90">优秀</h2><h2 v-else-if="score>=80">良好</h2><h2 v-else-if="score>=60">及格</h2><h2 v-else>不及格</h2><hr><hr><h2>{{result}}</h2>
</div><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>const app = new Vue({el:"#app",data:{message:"Hello Ting,I am Key!",score:95,},computed:{result(){let showMessage = '';if(this.score>=90){showMessage = '优秀';}else if(this.score>=80){showMessage = '良好';}else if(this.score>=60){showMessage = '及格';}else{showMessage = '不及格';}return showMessage;}}})
</script></body>
</html>

7.vue指令-v-for

目标:
列表渲染,所在标签结构,按照数据数量,循环生成

 <li v-for="item in arr" >{{item}}</li> <li v-for="(item,index) in arr">{{item}} ---{{index}}</li> 

语法:

数组对象的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 v-for="(item, index) in list" :key="index">

最后补一个li, 然后从第二个往后, 都要更新内容
根元素没变, 子元素没变, 元素内容改变

用key提高更新性能

1v-for先循环产生新的DOM结构, key是连续的, 和数据对应
2然后比较新旧DOM结构, 找到区别, 打补丁到页面上

目标结构:
可以遍历数组/对象/数字/字符串(可遍历结构)
口诀: 想让谁循环生成, v-for就写谁身上 in两边一定要有空格
注意:
v-for的变量名只能用到v-for里
临时变量名不能用到v-for范围外

<template><div id="app"><div id="app"><!-- v-for 把一组数据, 渲染成一组DOM --><p>学生姓名</p><ul><li v-for="(item,index) in arr" :key="index">{{index}}---{{item}}</li></ul><p>学生详细信息</p><ul><li v-for="obj in stuArr" :key="obj.id"><span>{{ obj.name }}</span><span>{{ obj.sex }}</span><span>{{ obj.hobby }}</span></li></ul><!-- v-for遍历对象(了解) --><p>老师信息</p><div v-for="(value, key) in tObj" :key="value">{{ key }} -- {{ value }}</div><!-- v-for遍历整数(了解) - 从1开始 --><p>序号</p><div v-for="i in count" :key="i">{{ i }}</div>
</div></div>
</template><script>
export default {data() {return {arr: ["小明", "小欢欢", "大黄"],stuArr: [{id: 1001,name: "孙悟空",sex: "男",hobby: "吃桃子",},{id: 1002,name: "猪八戒",sex: "男",hobby: "背媳妇",},],tObj: {name: "小黑",age: 18,class: "1期",},count: 10,};},
}
</script><style></style>

总结:
vue最常用指令,铺设页面利器,快速把数据赋予到相同的dom结构上循环生成

8.vue基础 v-for更新监测

目标:
当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: 更新值 要替换的内容

<template><div><ul><li v-for="(val,index) in arr" :key="index">{{val}}</li></ul><button @click="revBtn">数组翻转</button><button @click="sliceBtn">截取前3个</button><button @click="updateBtn">更新第一个元素值</button></div>
</template><script>
export default {data(){return{arr:[5,3,9,2,1]}},methods:{revBtn(){// 1. 数组翻转可以让v-for更新this.arr.reverse()},sliceBtn(){// 2. 数组slice方法不会造成v-for更新// slice不会改变原始数组// this.arr.slice(0, 3)// 解决v-for更新 - 覆盖原始数组let newArr = this.arr.slice(0,3)this.arr = newArr},updateBtn(){// 3. 更新某个值的时候, v-for是监测不到的// this.arr[0] = 1000;// 解决-this.$set()// 参数1: 更新目标结构// 参数2: 更新位置// 参数3: 更新值this.$set(this.arr,0,1000)}
}}
</script><style></style>

9.vue基础 动态class

目标:
用v-bind给标签class设置动态的值
语法:
:class="{类名:布尔值}"
总结:
就是把类名保存在vue变量中赋予给标签

<template><div><!-- 语法::class="{类名: 布尔值}"使用场景: vue变量控制标签是否应该有类名--><p :class="{red_str:isActive}">动态class</p></div>
</template><script>
export default {data(){return{isActive:true}}}
</script><style>
.red_str{color: red;
}
</style>

10.vue基础-动态style

目标: 给标签动态设置style的值

语法:

:style="{css属性: 值}"

<template><div><!-- 动态style语法:style="{css属性名: 值}"--><p :style="{backgroundColor : colorStr}">动态style</p></div>
</template><script>
export default {data(){return{colorStr:'red'}}}
</script><style></style>

总结:

动态style的key都是css属性名

11.vue过滤器-定义使用

目标:
转换格式,过滤器就是一个函数,传入值返回处理后的值
过滤器只能用在, 插值表达式和v-bind表达式
Vue中的过滤器场景:
字母转大写,输入"hello",输出"HELLO"
字符串翻转,“输入hello,world”,输出"dlrow,olleh"

语法:

1,全局过滤器,任意vue文件内直接使用

在main里设置,这里是引号,逗号,只能有一个
语法
Vue.filter(“过滤器名” , (值) =>处理结果)

// 1.全局注册过滤器
Vue.filter("test", function (val, s) {return val + s
})// 1.全局注册过滤器 过滤器接参数
Vue.filter("reverse", val => {return val.split("").reverse().join(s)
})

2,局部过滤器

和data方法并列设置,这里是冒号

filters: {过滤器名字: (值) => {return “返回处理后的值”}

例子:

全局定义字母都大写的过滤器局部定义字符串翻转的过滤器

<template><div><p >原来的样子:{{ msg }}</p><!-- 2. 过滤器使用语法: {{ 值 | 过滤器名字 }}--><p>使用翻转过滤器:{{ msg | reverse}}</p><p :title="msg | toUp">鼠标长停</p></div>
</template><script>
export default {data(){return{msg:'Hello,vue'}},// 方式2: 局部 - 过滤器// 只能在当前vue文件内使用/*语法: filters: {过滤器名字 (val) {return 处理后的值}}*/filters:{toUp(val){//toUpperCase将字符串转换成大写;return val.toUpperCase()```}
}
```}
</script><style></style>

总结:
把值转成另一种形式,使用过滤器,Vue3用函数替代了过滤器;
全局注册最好在main.js中注册,一处注册到处使用;
vue过滤器-传参和多过滤器目标:
可同时使用多个过滤器,或者给过滤器传参

过滤器传参: vue变量 | 过滤器(实参)
多个过滤器: vue变量 | 过滤器1 | 过滤器2

<template><div><p >原来的样子:{{ msg }}</p><!-- 1.给过滤器传值语法: vue变量 | 过滤器名(值)--><p>使用翻转过滤器:{{ msg | reverse('|')}}</p><!-- 2.多个过滤利使用语法: vue变量 | 过滤器1 | 过滤器2--><p :title="msg | toUp | reverse('|')">鼠标长停</p></div>
</template><script>
export default {data(){return{msg:'Hello,vue'}},// 方式2: 局部 - 过滤器// 只能在当前vue文件内使用/*语法: filters: {过滤器名字 (val) {return 处理后的值}}*/filters:{toUp(val){return val.toUpperCase()```}
}
```}
</script><style></style>

总结:
过滤器可以传参,还可以对某个过滤器结果,后面在使用一个过滤器

12.vue计算属性-computed

计算属性使用场景
一个数据,依赖另外一些数据计算而来的结果
语法:

computed:{"计算属性名"(){return "值"}}

需求:
求2个数的和显示到页面上

<template><div><p>{{ num }}</p></div>
</template><script>
export default {data(){return{a:30,b:40}},// 计算属性:// 场景: 一个变量的值, 需要用另外变量计算而得来/*语法:computed: {计算属性名 () {return 值}}*/// 注意: 计算属性和data属性都是变量-不能重名// 注意2: 函数内变量变化, 会自动重新计算结果返回computed:{num(){return this.a + this.b}}}
</script><style></style>

注意:
计算属性也是vue数据变量,所以不要和data里重名,用法和data相同
总结:
一个数据,依赖另外一些数据计算而来的结果

13.vue计算属性-缓存

计算属性的好处计算属性是基于它们的依赖项的值结果进行缓存的,
只要依赖的变量不变,都直接从缓存取结果
依赖的变量 变化, 函数会"自动"重新执行并重新缓存
computed计算属性只打印一次,计算属性有缓存功能
methods函数方法打印了3次

<template>
<div><p>{{ reverseMessage }}</p><p>{{ reverseMessage }}</p><p>{{ reverseMessage }}</p><p>{{ getMessage() }}</p><p>{{ getMessage() }}</p><p>{{ getMessage() }}</p>
</div>
</template><script>
export default {data(){return {msg: "Hello, Vue"}},// 计算属性优势:// 带缓存// 计算属性对应函数执行后, 会把return值缓存起来// 依赖项不变, 多次调用都是从缓存取值// 依赖项值-变化, 函数会"自动"重新执行-并缓存新的值computed: {reverseMessage(){console.log("计算属性执行了");return this.msg.split("").reverse().join("")}},methods: {getMessage(){console.log("函数执行了");return this.msg.split("").reverse().join("")}}
}
</script><style></style>

总结:
计算属性根据依赖变量结果缓存,依赖变化重新计算结果存入缓存,比普通方法性能更高

14.vue计算属性-完整写法

目标:
计算属性也是变量,如果想要直接赋值,需要使用完整写法
语法:

computed:{"属性名":{set(值){    },get(){return"值"}}}

需求:
计算属性给v-model使用
页面准备输入框

<template><div><div><span>姓名:</span><input type="text" v-model="full"></div></div>
</template><script>
// 问题: 给计算属性赋值 - 需要setter
// 解决:
/*完整语法:computed: {"计算属性名" (){},"计算属性名": {set(值){},get(){return 值}}
}*/
export default {computed:{full:{// 给full赋值触发set方法set(val){console.log(val)},// 使用full的值触发get方法get(){return"无名氏"}}}}
</script><style></style>

总结:
想要给计算属性赋值,需要使用set方法

15.vue侦听器-watch

目标:
可以侦听data/computed属性值改变
语法:

watch:{"被侦听的属性名"(newVal,oldVal){   }}

完整例子代码:

<template><div><input type="text" v-model="name"></div>
</template><script>
export default {data(){return{name:""}},// 目标: 侦听到name值的改变/*语法:watch: {变量名 (newVal, oldVal){// 变量名对应值改变这里自动触发}}*/watch:{// newVal: 当前最新值// oldVal: 上一刻值name(newVal,oldVal){console.log(newVal,oldVal);}}}
</script><style></style>

总结:
想要侦听一个属性变化,可使用侦听属性watch
vue侦听器-深度侦听和立即执行目标:
侦听复杂类型,或者立即执行侦听函数
语法:

watch:{"要侦听的属性名":{immediate:true, //立即执行deep:true, //深度侦听复杂类型内变化handler(newVal,oldVal){},
}}

完整例子代码:

<template><div><input type="text" v-model="user.name"><input type="text" v-model="user.age"></div>
</template><script>
export default {data(){return{user:{name:"",age:0}}},// 目标: 侦听对象/*语法:watch: {变量名 (newVal, oldVal){// 变量名对应值改变这里自动触发},变量名: {handler(newVal, oldVal){},deep: true, // 深度侦听(对象里面层的值改变)immediate: true // 立即侦听(网页打开handler执行一次)}
}*/watch:{user:{handler(newVal,oldVal){// user里的对象console.log(newVal,oldVal);},deep:true,immediate:true}}
}
</script><style></style>

总结:
immediate立即侦听,deep深度侦听,handler固定方法触发

16.vue组件_基础使用

目标:
每个组件都是一个独立的个体,代码里体现为一个独立的 .vue文件
口诀:
哪部分标签复用,就把哪部分封装到组件内
(重要):
组件内 template只能有一个根标签
组件内data必须是一个函数,独立作用域
步骤:
1.创建组件:
封装标签+样式+js - 组件都是独立的, 为了复用;
2.注册组件:
创建后需要注册后再使用;


17.全局 - 注册使用

全局入口在 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 里用;
单双标签都可以或者小写加 - 形式,运行后,会把这个自定义标签当做组件解析,使用组件里封装的标签替换到这个位置;

<PannelG></PannelG> <PannelG/> <pannel-g></pannel-g>
<pannel-g/>

vscode会自动补全,爱用哪个用哪个

18.局部 - 注册使用

语法:

import 组件对象 from 'vue文件路径'export default {    component: {       "组件名": 组件对象    } }

任意 vue文件中引入,注册,使用
案例:

<template><div id="app"><h3>案例:折叠面板</h3><!-- 4. 组件名当做标签使用 --><!-- <组件名></组件名> --><PannelG></PannelG><PannelL></PannelL></div>
</template><script>
// 目标: 局部注册 (用的多)
// 1. 创建组件 - 文件名.vue
// 2. 引入组件
import Pannel from './components/Pannel_1'
export default {// 3. 局部 - 注册组件/*语法: components: {"组件名": 组件对象}*/components: {PannelL: Pannel}
}
</script>

组件使用总结:
1.(创建)封装 html+css+vue到独立的 .vue文件中
2.(引入注册)组件文件 => 得到组件配置对象
3.(使用)当前页面当做标签使用

19. vue组件-scoped作用

目标:
解决多个组件样式名相同,冲突问题
需求:
div标签名选择器,设置背景色
问题:
发现组件里的div和外面的div都生效了
解决:
给Pannel.vue组件里 style标签上加上 scoped属性

<style scoped>

在style上加入 scoped属性,就会在此组件的标签上加上一个随机生成的data-v开头的属性
而且必须是当前组件的元素,才会有这个自定义属性,才会被这个样式作用到
总结:style 上加 scoped,组件内的样式只在当前vue组件生效

20.vue组件通信

(1.1)_父向子-props

父传子口诀(步骤)是什么?
子组件内, props定义变量, 在子组件使用变量
父组件内, 使用子组件, 属性方式给props变量传值

需求:
封装一个商品组件 MyProduct.vue ,外部传入具体要显示的数据
步骤:

1.创建子组件 components/MyProduct.vue

2.App.vue中在父组件引入组件,components注册组件,

3.父组件通过属性传递参数title,price 和通过变量:intro传值

4.子组件内在props定义变量,用于接收外部传入的值,

5.在标签内用{{}}显示

案例:

子 :   components/MyProduct.vue
 - 准备标签

父组件 -> 子组件 传值
1. 子组件内, 定义变量, 准备接收, 然后使用变量

<template>
<div class="my-product">
<--使用变量-->
<h3>标题: {{ title }}</h3>
<p>价格: {{ price }}元</p>    <p>{{ intro }}</p>
</div> </template> <script> export default {
// 定义变量 准备接收
props: ['title', 'price', 'intro']}</script> <style> .my-product {  width: 400px;  padding: 20px;   border: 2px solid #000;   border-radius: 5px;   margin: 10px;
}
</style>
2.父组件(App.vue)内, 要展示封装的子组件(MyProduct.vue)
引入组件, 注册组件, 使用组件, 传值进去

App.vue中使用组件

<template><div>     <!--
目标: 父(App.vue) -> 子(MyProduct.vue) 分别传值进入
需求: 每次组件显示不同的数据信息
步骤(口诀):
1. 子组件 - props - 变量 (准备接收)
2. 父组件 - 传值进去
使用组件 传值进去
-->     <Product title="好吃的口水鸡" price="50" intro="开业大酬宾, 全场8折"></Product>
<Product title="好可爱的可爱多" price="20" intro="老板不在家, 全场1折"></Product>
<Product title="好贵的北京烤鸭" price="290" :intro="str"></Product>   </div>
</template> script>
// 1. 创建组件 (.vue文件)
// 2. 引入组件 import Product from './components/MyProduct' export default {
data(){
return {
str: "好贵啊, 快来啊, 好吃"     }
},   // 3. 注册组件
components: {
// Product: Product
// key和value变量名同名 - 简写     Product   }
} </script> <style> </style>

总结:
组件封装复用的标签和样式,而具体数据要靠外面传入

(1.2)vue组件通信_父向子-配合循环

目标:
把数据循环分别传入给组件内显示
案例:

<template>
<div>
<MyProduct
v-for="obj in list"
:key="obj.id"
:title="obj.proname"
:price="obj.proprice"
:intro="obj.info"    ></MyProduct>  </div>
</template> <script>
// 目标: 循环使用组件-分别传入数据
// 1. 创建组件
// 2. 引入组件
import MyProduct from './components/MyProduct' export default {  data() {
return {
list: [ {
id: 1,
proname: "超级好吃的棒棒糖",
proprice: 18.8,
info: "开业大酬宾, 全场8折",
},   {
id: 2,
proname: "超级好吃的大鸡腿",
proprice: 34.2,
info: "好吃不腻, 快来买啊",
},    {
id: 3,
proname: "超级无敌的冰激凌",
proprice: 14.2,
info: "炎热的夏天, 来个冰激凌了",         },],     };
},   // 3. 注册组件
components: {
// MyProduct: MyProduct    MyProduct  } };</script> <style> </style>

在vue中需要遵循单向数据流原则
1.父组件的数据发生了改变,子组件会自动跟着变
2.子组件不能直接修改父组件传递过来的 props , props是只读的
父组件传给子组件的是一个对象,子组件修改对象的属性,是不会报错的,对象是引用类型,互相更新
总结:
props的值不能重新赋值,对象引用关系属性值改变,互相影响

vue组件通信_单向数据流

props变量本身是只读 , 不能重新赋值

从父到子的数据流向,叫单向数据流
原因:子组件修改,不通知父级,造成数据不一致性
如果第一个MyProduct.vue内自己修改商品价格为5.5 , 但是App.vue里原来还记着18.8 ,数据 不一致 了
所以 Vue规定 props里的变量,本身是只读的
总结:
props变量本身是不能重新赋值的
问题:
子组件内能改变, 父传入的数据吗?
解决:
要通过自定义事件$emit() 方法传值 影响父组件接收,然后事件监听  数据响应式 来影响子组件

(2)vue组件通信_子向父

什么时候用子传父? 当子要改变父的数据

1.接收值的人 监听的是  子组件传过来的同个自定义事件

2.传值的人 添加的是点击事件     点击事件方法里 会触发自定义事件

3.接收方 都会是 函数方法接收的值

function (val) {

console.log(val);

}

子传父如何实现?
父:     @自定义事件名=“父methods函数”   
子:      this.$emit(“自定义事件名”,传值) -执行父methods里的函数代码

在父组件中给子组件绑定一个自定义的事件,子组件通过$emit()触发该事件并传值。

目标:
从子组件把值传出来给外面使用
语法:

子组件通过$emit广播事件

父组件 监听这个事件,并接受数据

父组件内, 绑定自定义事件和事件处理函数
语法: @自定义事件名="父methods里函数名"

1.父:监听这个事件 @自定义事件名=“父methods函数”

子组件通过$emit广播事件

父组件 监听这个事件,并接受数据

  <child @whd="testFn"></child>methods: {// val就会接收到父组件这个188的参数// 接收子组件data里的数据testFn(val) {console.log("我是父组件的打印" + val); //我是父组件的打印q,w},},
子组件内, 恰当的时机, 触发父给绑的自定义事件, 导致父methods里事件处理函数执行

2.子: 添加点击事件 传值给父组件 执行子methods里的函数代码

 <button @click="fn">传值给父组件</button>

3.子:自定义事件名 广播给父组件传值 this.$emit(“自定义事件名”,传值) -

fn(){
​
this.$emit("whd", 188);
​
}
 // 如果希望传data里的list
data() {return {list: ["q", "w"],};},methods: {fn(){
​
this.$emit("whd", this.list);}
}

案例:

1.子: 添加点击事件 传值给父组件 执行子methods里的函数代码

<button @click="subFn">宝刀-砍1元</button>

2.子:自定义事件名 广播给父组件传值 this.$emit(“自定义事件名”,传值) -

this.$emit('subprice', this.index, 1)

案例:
MyProduct_sub.vue

<template>
<div class="my-product">
<h3>标题: {{ title }}</h3>
<p>价格: {{ price }}元</p>
<p>{{ intro }}</p>    <button @click="subFn">宝刀-砍1元</button>
</div> </template> <script>
import eventBus from '../EventBus'
export default {
props: ['index', 'title', 'price', 'intro'],
methods: {
subFn(){
this.$emit('subprice', this.index, 1)
// 子向父
eventBus.$emit("send", this.index, 1)// 跨组件     }   }
} </script> <style>
.my-product {
width: 400px;
padding: 20px;
border: 2px solid #000;
border-radius: 5px;
margin: 10px; } </style>

3.父:监听这个事件 @自定义事件名=“父methods函数”

@subprice="fn"

App.vue

<template>
<div>
<!-- 目标: 子传父 -->    <!-- 1. 父组件, @自定义事件名="父methods函数" -->
<MyProduct v-for="(obj, ind) in list"
:key="obj.id"
:title="obj.proname"
:price="obj.proprice"
:intro="obj.info"
:index="ind"
@subprice="fn"    >
</MyProduct>
</div>
</template> <script> import MyProduct from './components/MyProduct_sub' export default {
data() {
return {
list: [{
id: 1,
proname: "超级好吃的棒棒糖",
proprice: 18.8,
info: "开业大酬宾, 全场8折",
},
{
id: 2,          proname: "超级好吃的大鸡腿",
proprice: 34.2,
info: "好吃不腻, 快来买啊",
},
{
id: 3,          proname: "超级无敌的冰激凌",
proprice: 14.2,
info: "炎热的夏天, 来个冰激凌了",        }, ],
};
},   components: {
MyProduct
},
methods: {
fn(inde, price){
// 逻辑代码
this.list[inde].proprice > 1 && (this.list[inde].proprice = (this.list[inde].proprice - price).toFixed(2))     }   }
};</script> <style>
</style>

总结:
父自定义事件和方法,等待子组件触发事件给方法传值

(3)vue组件通信-EventBus

目标:
常用于跨组件通信时使用
两个组件的关系非常的复杂,通过父子组件通讯是非常麻烦的.这时候可以使用通用的组件通讯方案:事件总线( 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就是接收的数据})
    } 进行数据接收


核心语法:
空的Vue对象,只负责on注册时间,emit触发事件,一定要确保$on先执行

什么时候使用eventBus技术?
当2个没有引用关系的组件之间要通信传值
eventBus技术本质是什么?
空白Vue对象, 只负责$on和$emit

一、创建空白Vue对象并导出

EventBus/index.js -定义事件总线bus对象

import Vue from 'vue'
export default new Vue()// 1. new Vue()
// 2. 用到了 Vue就需要导入 import
// 3. 导出空白vue对象

二、右边要 要接收值的组件 List.vue

List.vue注册时间,等待接收要砍价的值,准备兄弟页面

1.引入空白vue对象(EventBus)

 import eventBus from "../EventBus";

引入的是文件夹

当import遇到文件夹 会自动找里面的index.js文件,

并把里面的东西导过来 赋值到变量上 用eventBus这个变量名接收

如果文件名不叫index.js需要把名字写全

2.eventBus.$on监听事件(''事件名',函数体)

接收方 $on监听自定义事件

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});},

3.组件创建完毕,监听send事件

created(){}是在list.vue这个组件被创建时自动执行这个方法

在创建的时候立刻用$on绑定一个自定义事件名,

当事件被触发的时候,要接一个索引和要砍掉的价格

原来是在app.vue里砍一刀的   现在要在List.vue

<template>
<ul class="my-product">
<li v-for="(item, index) in arr"
:key="index">
<span>{{ item.proname }}</span>
<span>{{ item.proprice }}</span>
</li>
</ul>
</template> <script>
// 目标: 跨组件传值
// 1. 引入空白vue对象(EventBus)
// 2. 接收方 - $on监听事件 import eventBus from "../EventBus"; export default { props: ["arr"],// 3. 组件创建完毕, 监听send事件
created() {eventBus.$on("send", (index, price) => {
this.arr[index].proprice > 1 && (this.arr[index].proprice = (this.arr[index].proprice - price).toFixed(2)); }); },
}; </script> <style>
.my-product {width: 400px;
padding: 20px;
border: 2px solid #000;
border-radius: 5px;
margin: 10px;
} </style>

三、左边 要传递值的组件 MyProduct_sub.vue

1.也引入空白vue对象(EventBus)

import eventBus from '../EventBus'

2.eventBus.$emit("事件名", 值)

传值发送方 $emit广播自定义事件

点击 砍一刀 按钮时 触发这个函数 向空白对象身上触发刚才监听的 同名自定义事件,把值丢过去

methods: {subFn(){eventBus.$emit("send", this.index, 1) // 跨组件}}

MyProduct_sub.vue

<template>
<div class="my-product">
<h3>标题: {{ title }}</h3>
<p>价格: {{ price }}元</p>
<p>{{ intro }}</p>
<button @click="subFn">宝刀-砍1元</button>
</div>
</template> <script>
import eventBus from '../EventBus' export default {
props: ['index', 'title', 'price', 'intro'],
methods: { subFn(){ this.$emit('subprice', this.index, 1) // 子向父 eventBus.$emit("send", this.index, 1)
// 跨组件 } } } </script> <style>
.my-product {
width: 400px;
padding: 20px;
border: 2px solid #000;
border-radius: 5px;
margin: 10px;
}
</style>

Vue小字典-vue基础相关推荐

  1. vue小程序开发(四)首页 推荐

    vue小程序开发(四)首页 推荐 编写 首页-推荐 模块 推荐-最顶部模块 推荐-月份模块 月份模块标题样式 推荐-热门模块 基本布局 使用scroll-view改造容器 分页功能分析 实现头部固定 ...

  2. Vue框架的入门基础学习

    当创建新的vue项目时,遇到无法加载文件 E:\node\node_global\vue.ps1,因为在此系统上禁止运行脚本的错误,以下为解决办法. vue中文文档 菜鸟教程:Vue.js 该笔记只是 ...

  3. Vue(三):vue基础入门

    目录 一.侦听器 1.1 什么是watch侦听器 1.2 方法格式的侦听器的应用--判断用户名是否被占用 ​1.3 immediate属性-对象格式的侦听器 1.4 deep属性-对象格式的侦听器 二 ...

  4. Vue2.x 核心基础(Vue概述,Vue基本使用,@vue/cli脚手架,Element-UI 的基本使用,Vue模板语法)

    1. Vue概述 尤雨溪:Vue.js的创建者 2014年2月,Vue.js正式发布 2015年10月27日,正式发布1.0.0 2016年4月27日,发布2.0的预览版本 Vue:渐进式JavaSc ...

  5. 学习VUE第七天课程(VUE之组件(基础、分类、命名))

    VUE之组件(基础.分类.命名) 组件( Component )是 Vue.js 最核心的功能,也是整个框架设计最精彩的地方,当然也是最难掌握的. 接下来会由浅入深地学习组件的全部内容,并通过几个案例 ...

  6. Vue.js最最最基础入门的笔记整理

    2021.1.23 文章目录 Vue.js学习笔记(一) 准备工作 学前须知 开发工具 课程安排 Vue基础 Vue简介 第一个Vue程序 el:挂载点 data:数据对象 本地应用 1.内容绑定,事 ...

  7. 开源商城:小程序+Vue管理员后台+SpringBoot后台服务

    分享过几个开源商城,每个都有一点遗憾.这也是自然,商城这类开源项目,多是一个人下班时间搞得.每个人的技术栈掌握情况不一,即使所谓的全栈开发,也总是比较擅长前端或后端中的一块. 如果是几个人一起开发,那 ...

  8. 云闪付小程序Vue授权组件只兼容Vue2,改造兼容Vue3版本

    此文章发布时,云闪付小程序的官方文档提示暂不支持Vue3 云闪付小程序文档 - Vue授权组件 引用后发现组件内部确实使用了很多Vue3 中已经删除了或者不推荐的方法,导致各种报错. 并且提示还要修改 ...

  9. 适合初学者练手的vue小项目(附github源码)

    vue慢慢的成为了前端最受欢迎的框架之一,在很多项目之中开发都能用得到,如今也已经发展到3.0了,可能是因为这个框架可以提高工作效率,因此受到大家的追捧,在之前的文章里面也说过,2019年,大前端学习 ...

最新文章

  1. Android NDK开发之旅(2):一篇文章搞定Android Studio中使用CMake进行NDK/JNI开发
  2. 使用httpHandlers进行url rewrite时,提示http 404 error 错误
  3. select报错 spark_spark-sql master on yarn 模式运行 select count(*) 报错日志
  4. 【踩坑速记】开源日历控件,顺便全面解析开源库打包发布到Bintray/Jcenter全过程(新),让开源更简单~...
  5. php mysql 排序规则_php 数组排序以及按照某个字段排序
  6. 单词翻转(信息学奥赛一本通-T1144)
  7. MBA 案例:一个叫花子做的策划
  8. js中的内置对象(详细篇)
  9. OpenCV-Python实战(番外篇)——利用 SVM 算法识别手写数字
  10. 微机原理、计算机组成原理与计算机体系结构之间的关系
  11. DiskGeniux无损分区
  12. con 元器件符号_altium designer常用元件电气符号和封装形式
  13. arcgis api for js去掉地图边框与logo(arcgis api for js篇.3)
  14. 我为什么要选软件工程专业
  15. IO---缓冲流、字符集、转换流、序列化和反序列化
  16. 广州图书馆——携程评论爬取
  17. Opencv学习(3)——基础矩阵F、本质矩阵E、单应矩阵H 函数解析
  18. 致所有初学者--助力所有ERP初学者!!!
  19. 简要视音频发展编年史
  20. 金蝶EAS补丁部署操作步骤

热门文章

  1. 如何删除idea里面创建的工程项目
  2. php会计科目,新会计准则会计科目表(中英文对照)
  3. python排序算法——插入排序
  4. python 查询mysql数据导出excl_python查询mysql并生成excel表
  5. ipad怎样分屏_【工具】ZotExpert:实现iPad文献管理的无缝同步
  6. NetStream information objects
  7. IDEA2021.1版本安装教程
  8. 使用cmd运行java出现错误:编码GBK 的不可映射字符
  9. python批量修改图像像素,修改命名,二值化,划分数据集
  10. 如何把WPS转换成PDF格式?新手也能轻松学会的方法