第一章、快速入门
-
Vue
是什么 -
Vue
的特点 -
Vue.js
安装 -
Vue.js
入门案例-
响应式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>响应式</title> </head> <body> <div id="app"> <h1>{{aa}}</h1> </div> <!--引用本地Vue.js--> <script src="vue.global.js"></script> <script> //实例化对象 const HelloVue = { //通过data定义值 data() { //返回一个值 return { aa: "你好.Vue.js" } } }; //创建Vue对象,接管ID为App<DIV>标签 const app = Vue.createApp(HelloVue).mount('#app') </script> </body> </html>
-
命令式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>命令式</title> </head> <body> <div id="app"></div> <script> //获取DIV的ID const app = document.getElementById('app') // 添加一个H1标签 let h1E = document.createElement('h1') //给H1标签添加内容 app.appendChild(h1E) //给H1标签innerText属性赋值 h1E.innerText = "你好,Vue.js" </script> </body> </html>
-
创建列表
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>相应式</title> </head> <body> <div id="app"> <ul> <li>{{colleges [0]}}</li> <li>{{colleges [1]}}</li> <li>{{colleges [2]}}</li> <li>{{colleges [3]}}</li> </ul> <ul> <li v-for="college in colleges">{{college}}</li> </ul> </div> <!--引用本地Vue.js--> <script src="vue.global.js"></script> <script> //实例化对象 const ListApp = { //通过data定义值 data() { //返回一个对象 return { colleges: ['1', '2', '3', '4'] } } }; //创建Vue对象,接管ID为App<DIV>标签 const app = Vue.createApp(ListApp).mount('#app') </script> </body> </html>
-
通过输入框修改*
A
标签URL
*<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>相应式</title> </head> <body> <div id="app"> <a v-bind:href="msg2">{{msg2}}</a> <br> <input v-model="msg1" v-on:keyup.enter="fun" v-on:blur.native.capture="fun" placeholder="请在这里网址回车结结束"> </div> <!--引用本地Vue.js--> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { msg1: "", msg2: "网址" } }, methods: { fun() { this.msg2 = "https://" + this.msg1 } } }).mount('#app') </script> </body> </html>
-
-
MVC
、MVP
、MVVM
-
Vue
中对MVVM
的运用
第二章、基础语法
-
双括号语法
-
常用指令
-
插值语法
-
V-Text
-
V-Html
-
预期:
String
-
详细:
更新元素的
innerHTML
。注意:内容按普通HTML
插入 - 不会作为Vue
模板进行编译。如果试图使用v-html
组合模板,可以重新考虑是否通过使用组件来替代。 在网站上动态渲染任意
HTML
是非常危险的,因为容易导致XSS 攻击
。只在可信内容上使用v-html
,永不用在用户提交的内容上。 在单文件组件里,
scoped
的样式不会应用在*v-html
内部,因为那部分HTML
没有被Vue
的模板编译器处理。如果你希望针对v-html
*的内容设置带作用域的CSS
,你可以替换为CSS modules
或用一个额外的全局<style>
元素手动设置类似 BEM 的作用域策略。 -
实例:
<div v-html="html"></div>
-
-
V-Pre
-
V-Cloak
-
V-Once
-
不需要表达式
-
详细:
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
-
实例:
<!-- 单个元素 --> <span v-once>This will never change: {{msg}}</span> <!-- 有子元素 --> <div v-once> <h1>comment</h1> <p>{{msg}}</p> </div> <!-- 组件 --> <my-component v-once :comment="msg"></my-component> <!-- `v-for` 指令 --> <ul> <li v-for="i in list" v-once>{{i}}</li> </ul>
-
-
-
条件和循环
-
V-show
-
V-if
-
V-show和V-if区别
V-if
是"真正"的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地销毁和重建。V-show
不管初始条件是什么,元素总是会被渲染,并且只是简单基于CSS
进行切换。V-show
会在HTML
展示,你在输入框输入内容也会存在就算是不停切换依旧会存在,V-if
不会在HTML
显示,在输入框内输入的内容在切换后就不存在了,如果需要频繁的切换使用V-show
效果最好。-
实例:
V-show
和V-if
综合案例<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>V-if和V-show</title> </head> <body> <div id="app"> <div v-if="flag">要下雨</div> <div v-else>不下雨</div> <div v-show="flag">要去</div> <div v-show="!flag">不去</div> <button v-on:click="getFlag()">切换</button> </div> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { flag: true, } }, computed: {}, methods: { getFlag() { return this.flag = !this.flag } } }).mount('#app') </script> </body> </html>
<!--登录案例--> <!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>V-if和V-show综合案例</title> </head> <body> <div id="app"> <label v-show="flag"> 手机: <input type="text" placeholder="请输入手机号" v-model="name"> </label> <label v-show="!flag"> 邮箱: <input type="text" placeholder="请输入邮箱" v-model="name"> </label> <label> <br> 密码: <input type="password" placeholder="请输入密码" v-model="password"> </label> <br> <button v-on:click="getFlag()">切换登录模式</button> <button v-on:click="login()">登录</button> </div> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { flag: true, name: '', password: '' } }, computed: {}, methods: { getFlag() { return this.flag = !this.flag }, login() { if (this.flag === true) { if (this.name === '123' || this.password === '123') { return alert("登录成功") } return alert("登录失败") } if (this.flag === false) { if (this.name === '456' || this.password === '123') { return alert("登录成功") } return alert("登录失败") } } } }).mount('#app') </script> </body> </html>
-
-
V-else
-
V-else-if
-
V-for
-
预期:
Array
Object
number
string
Iterable
-
为什么要绑定*
Key
*Key
是给每个vnode
的唯一id
,可以依靠Key
,更准确、更快的拿到oldVnode
中对应的vnode
节点,方便插入数据后数据错位 -
用法:
基于源数据多次渲染元素或模板块。此指令之值,必须使用特定语法
alias in expression
,为当前遍历的元素提供别名:<div v-for="item in items"> {{ item.text }} </div>
另外也可以为数组索引指定别名 (或者用于对象的键):
<div v-for="(item, index) in items"></div> <div v-for="(value, key) in object"></div> <div v-for="(value, name, index) in object"></div>
v-for
的默认行为会尝试原地修改元素而不是移动它们。要强制其重新排序元素,你需要用特殊*attribut
* *key
*来提供一个排序提示:<div v-for="item in items" :key="item.id"> {{ item.text }} </div>
v-for
也可以在实现了可迭代协议的值上使用,包括原生的Map
和Set
。v-for
的详细用法可以通过以下链接查看教程详细说明。 -
实例:
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>V-for遍历数组</title> </head> <body> <div id="app"> <h1>简单遍历</h1> <ul> <li v-for="arrs in arr ">数组里的内容:{{arrs}}</li> </ul> <h1>带索引遍历</h1> <ul> <li v-for="(arrs,index) in arr ">数组里的内容:{{arrs}}。下标:{{index}}</li> </ul> <h1>遍历数组里的对象</h1> <ul> <li v-for="(arrClasss,index) in arrClass "> 数组里的内容:{{arrClasss}}。姓名:{{arrClasss.name}}。年龄:{{arrClasss.age}}岁。地址:{{arrClasss.address}}。下标:{{index}} </li> </ul> <h1>遍历对象</h1> <ul> <li v-for="itme in person "> 数组里的内容:{{itme}}。 </li> </ul> <h1>遍历对象带键值对的</h1> <ul> <li v-for="(itme ,key) in person "> 键:{{key}}。值:{{itme}}。 </li> </ul> <h1>遍历对象带键值对和索引的</h1> <ul> <li v-for="(itme ,key, index) in person"> 键:{{key}}。值:{{itme}}。索引:{{index}} </li> </ul> </div> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { arr: ['一', '二', '三', '四', '五'], arrClass: [ {name: "张三", age: "12", address: "上海"}, {name: "李四", age: "13", address: "北京"}, {name: "王五", age: "14", address: "深圳"}, {name: "赵六", age: "15", address: "广州"}, {name: "周七", age: "16", address: "香港"}, ], person: { name: "祈求者", age: "五万岁", address: ["夜魇", "天辉"] } } }, computed: {}, methods: {} }).mount('#app') </script> </body> </html>
-
-
V-if与V-for的优先级对比
-
-
绑定属性
-
V-bind
-
缩写:
:
-
预期:
any (with argument)
Object (without argument)
-
参数:
attrOrProp (optional)
-
修饰符:
.prop
- 作为一个 DOM property 绑定而不是作为 attribute 绑定。.camel
- (2.1.0+) 将 kebab-case attribute 名转换为 camelCase。(从 2.1.0 开始支持).sync
(2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的v-on
侦听器。
-
用法:
动态地绑定一个或多个 attribute,或一个组件 prop 到表达式。
在绑定
class
或style
attribute 时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。
没有参数时,可以绑定到一个包含键值对的对象。注意此时
class
和style
绑定不支持数组和对象。 -
实例:
<!-- 绑定一个 attribute --> <img v-bind:src="imageSrc"> <!-- 动态 attribute 名 (2.6.0+) --> <button v-bind:[key]="value"></button> <!-- 缩写 --> <img :src="imageSrc"> <!-- 动态 attribute 名缩写 (2.6.0+) --> <button :[key]="value"></button> <!-- 内联字符串拼接 --> <img :src="'/path/to/images/' + fileName"> <!-- class 绑定 --> <div :class="{ red: isRed }"></div> <div :class="[classA, classB]"></div> <div :class="[classA, { classB: isB, classC: isC }]"> <!-- style 绑定 --> <div :style="{ fontSize: size + 'px' }"></div> <div :style="[styleObjectA, styleObjectB]"></div> <!-- 绑定一个全是 attribute 的对象 --> <div v-bind="{ id: someProp, 'other-attr': otherProp }"></div> <!-- 通过 prop 修饰符绑定 DOM attribute --> <div v-bind:text-content.prop="text"></div> <!-- prop 绑定。“prop”必须在 my-component 中声明。--> <my-component :prop="someThing"></my-component> <!-- 通过 $props 将父组件的 props 一起传给子组件 --> <child-component v-bind="$props"></child-component> <!-- XLink --> <svg><a :xlink:special="foo"></a></svg> <!-- .camel 修饰符允许在使用 DOM 模板时将 v-bind property 名称驼峰化,例如 SVG 的 viewBox property: --> <svg :view-box.camel="viewBox"></svg> <!-- 在使用字符串模板或通过 vue-loader/vueify 编译时,无需使用 .camel。-->
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>切换Class</title> <style> .mydiv { color: black; } .red { font-size: 60px; } .yellow { border: red solid 1px; } .blue { text-decoration: underline; } </style> </head> <body> <div id="app"> <!-- 用对象是之间前面的变量是CSS的变量名--> <P v-bind:class="{mydiv:temp,red:temp,yellow:temp,blue:temp}">sadasdsd</P> <!-- 数组的里面的是CSS样式重新定义的变量名--> <P v-bind:class="ks">sadasdsd</P> <!-- 调用函数--> <P v-bind:class="ks">sadasdsd</P> <button v-on:click="chengge">点我</button> </div> <!--引用本地Vue.js--> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { temp: true, ks: ['mydiv', 'red', 'yellow', 'blue'] } }, methods: { chengge() { this.temp = !this.temp }, CSS() { return cs = ['mydiv', 'red', 'yellow', 'blue'] } } }).mount('#app') </script> </body> </html>
-
-
V-On
-
缩写:
@
-
预期:
Function
Inline Statement
Object
-
参数:
event
-
修饰符:
-
用法:
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个
$event
property:v-on:click="handle('ok', $event)"
。v-on
同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。 -
实例:
<!-- 方法处理器 --> <button v-on:click="doThis"></button> <!-- 动态事件 --> <button v-on:[event]="doThis"></button> <!-- 内联语句 --> <button v-on:click="doThat('hello', $event)"></button> <!-- 缩写 --> <button @click="doThis"></button> <!-- 动态事件缩写 --> <button @[event]="doThis"></button> <!-- 停止冒泡 --> <button @click.stop="doThis"></button> <!-- 阻止默认行为 --> <button @click.prevent="doThis"></button> <!-- 阻止默认行为,没有表达式 --> <form @submit.prevent></form> <!-- 串联修饰符 --> <button @click.stop.prevent="doThis"></button> <!-- 键修饰符,键别名 --> <input @keyup.enter="onEnter" /> <!-- 点击回调只会触发一次 --> <button v-on:click.once="doThis"></button> <!-- 对象语法 --> <button v-on="{ mousedown: doThis, mouseup: doThat }"></button> <!-- 在子组件上监听自定义事件 (当子组件触发“my-event”时将调用事件处理器): --> <my-component @my-event="handleThis"></my-component> <!-- 内联语句 --> <my-component @my-event="handleThis(123, $event)"></my-component>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>V-on</title> </head> <body> <div id="app"> <h1>运输结果:{{sum}}</h1> <button @click="add">+</button> <button @click="sub">-</button> <h1>传递参数</h1> <button @click="getClick1()">不带参数</button> <button @click="getClick2">不带参数</button> <button @click="getClick3(123,'asd','阿斯顿',sum)">带参数</button> <!-- 传递事件的时候需要使用$ 参数放在钱事件在最后--> <button @click="getClick4(123,'asd','阿斯顿',sum,$event)">带参数需要事件对象</button> </div> <!--引用本地Vue.js--> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { sum: 0 } }, methods: { add() { this.sum++; }, sub() { this.sum--; if (this.sum < 0) { return this.sum = 0 } }, getClick1(aaa) { //空对象 console.log(aaa); }, getClick2(aaa) { //默认的事件对象 console.log(aaa); }, getClick3(aaa, bbb, ccc, ddd) { //默认的事件对象 console.log(aaa, bbb, ccc, ddd); }, getClick4(aaa, bbb, ccc, ddd, event) { //默认的事件对象 console.log(aaa, bbb, ccc, ddd, event); } } }).mount('#app') </script> </body> </html>
-
-
-
表单绑定
-
V-model
-
预期:随表单控件类型不同而不同。
-
限制于:
-
修饰符:
.lazy
- 监听change
而不是input
事件.number
- 输入字符串转为有效的数字.trim
- 输入首尾空格过滤
-
用法:
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>V-model的实例</title> </head> <body> <div id="app"> <h1>单选</h1> <label> <input type="checkbox" v-model="flag">是否同意协议 </label> <P>是否同意协议:{{flag ? "同意" : "不同意"}}</P> <button v-bind:disabled="!flag">下一步</button> <h1>多选</h1> <label> <input type="checkbox" value="篮球" v-model="arr">篮球 <input type="checkbox" value="足球" v-model="arr">足球 <input type="checkbox" value="排球" v-model="arr">排球 <input type="checkbox" value="网球" v-model="arr">网球 <input type="checkbox" value="台球" v-model="arr">台球 </label> <p>你选择的兴趣是:{{arr}}</p> <h1>动态的绑定</h1> <label v-for="index in textArr " v-bind:for="index"> <input type="checkbox" v-bind:value="index" v-bind:id="index" v-model="likes">{{index}} <br> </label> <p>你选择的兴趣是:{{likes}}</p> <h1>下拉单选</h1> <p>选择所在的城市:{{getCity}}</p> <label> <select name="getCity" v-model="getCity"> <option v-bind:value="index" v-bind:id="index" v-for="index in city">{{index}}</option> </select> </label> <h1>下拉多选</h1> <p>选择所在的城市:{{getCitys}}</p> <label> <select v-bind:name="getCitys" v-model="getCitys" multiple> <option v-bind:value="index" v-bind:id="index" v-for="index in citys">{{index}}</option> </select> </label> <h1>V-model修饰符</h1> <label> <input v-model.lazy="smg"> <input v-model.number="num"> <input v-model.trim="name"> </label> <p>{{smg}}</p> <br> <p>{{num}}是{{typeof num}}类型</p> <br> <P>过滤首位空格xxxx{{name}}xxxx</P> </div> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { flag: false, arr: [], textArr: ["祈求者", "丽娜", "露娜", "帕吉", "帕克"], likes: [], city: ["昆明", "大理", "玉溪"], getCity: "昆明", citys: ["昆明", "大理", "玉溪"], getCitys: [], smg: '', num: 0, name: "" } }, computed: {}, methods: {} }).mount('#app') </script> </body> </html>
-
V-model的基本实现:
通过单项绑定一个
Value
,然后通过事件监听,监听输入事件,让事件获取单项绑定的value
,实现V-model
的效果<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>V-model的底层实现</title> </head> <body> <div id="app"> <label> <input type="text" v-bind:value="msg" v-on:input="getMSG"> </label> <h1>{{msg}}</h1> </div> <script src="vue.global.js"></script> <script> const app = Vue.createApp({ data() { return { msg: '' } }, computed: {}, methods: { getMSG(event) { //Vue event.target.value( ) 获取当前文本框的值(由事件触发时) return this.msg = event.target.value } } }).mount('#app') </script> </body> </html>
-
-
-
自定义指令
-
Vue
2.0写法-
用函数的方式自定义指令
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义组件</title> </head> <body> <div id="app"> <span v-big="n"></span> </div> </body> <script src="js/vue3.js"></script> <script> const app = Vue.createApp({ data() { return { n: 1 } }, directives: { //element:真实的DOM元素 //binding:获取到值 //big函数何时被调用 。 1.指令和元素成功绑定时。2.指令所在的模板从新解析时 big(element, binding) { element.innerText = binding.value } } }).mount('#app') </script> </html>
-
用对象的方式自定义指令
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义组件</title> </head> <body> <div id="app"> <input v-abc:value="n"> <button v-on:click="n++">{{n}}</button> </div> </body> <script src="js/vue2.js"></script> <script> new Vue({ data: { n: 1 }, directives: { abc: { //指令与元素成功绑定时 bind(element, binding) { //element:真实的DOM元素 //binding:获取到值 element.value = binding.value }, //指令所在元素被插入页面时 inserted(element, binding) { element.value = binding.value element.focus() }, //指令所在的模板从新解析时 update(element, binding) { element.value = binding.value element.focus() }, } } }).$mount('#app') </script> </html>
-
-
Vue
3.0写法除了默认设置的核心指令(
v-model
和v-show
),Vue
也允许注册自定义指令。下面我们注册一个全局指令*
v-focus
*, 该指令的功能是在页面加载时,元素获得焦点指令定义函数提供了几个钩子函数(可选):
created
: 在绑定元素的属性或事件监听器被应用之前调用beforeMount
: 指令第一次绑定到元素并且在挂载父组件之前调用mounted
: 在绑定元素的父组件被挂载后调用beforeUpdate
: 在更新包含组件的 VNode 之前调用updated
: 在包含组件的 VNode 及其子组件的 VNode 更新后调用beforeUnmount
: 当指令与在绑定元素父组件卸载之前时,只调用一次unmounted
: 当指令与元素解除绑定且父组件已卸载时,只调用一次
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义组件</title> </head> <body> <div id="app"> <p>页面载入时,input 元素自动获取焦点:</p> <input v-focus:value="num"> <br> <span v-runoob="{ name: '曹李奶奶', url: 'www.baidu.com' }"></span> <br> <span v-abc="num"></span> </div> </body> <script src="js/vue3.js"></script> <script> const app = Vue.createApp({ data() { return { num: 1 } }, directives: { //正常写法 focus: { // 在绑定元素的 attribute 或事件监听器被应用之前调用 created(element, binding) { //element:真实的DOM元素 //binding:获取到值 console.log("created" + 1) }, // 在绑定元素的父组件挂载之前调用 beforeMount(element, binding) { //element:真实的DOM元素 //binding:获取到值 console.log("beforeMount" + 2) }, // 绑定元素的父组件被挂载时调用 mounted(element, binding) { //element:真实的DOM元素 //binding:获取到值 element.value = binding.value console.log("mounted" + 3) element.focus() }, // 在包含组件的 VNode 更新之前调用 beforeUpdate(element, binding) { //element:真实的DOM元素 //binding:获取到值 console.log("beforeUpdate" + 4) }, // 在包含组件的 VNode 及其子组件的 VNode 更新之后调用 updated(element, binding) { //element:真实的DOM元素 //binding:获取到值 console.log("beforeUpdate" + 5) }, // 在绑定元素的父组件卸载之前调用 beforeUnmount(element, binding) { //element:真实的DOM元素 //binding:获取到值 console.log("beforeUpdate" + 6) }, // 卸载绑定元素的父组件时调用 unmounted(element, binding) { //element:真实的DOM元素 //binding:获取到值 console.log("beforeUpdate" + 7) } }, //接收对象 runoob: { mounted(element, binding) { console.log(binding.name); console.log(binding.url); var s = JSON.stringify element.innerHTML = s(binding.value) }, }, //函数写法 abc(element, binding) { element.innerHTML = binding.value }, } }).mount('#app') </script> </html>
-
-
计算属性和函数的区别
在多次调用情况下函数每次都重新执行,计算属性只执行一次并且把执行结果缓存在页面上,如果中途计算属性则全部计算属性都会被修改,所以计算属性只满足于展示并且多次出现一类的属性就使用计算属性,如果只是一次那就用函数
-
第三章、理解 Vue
的 MVVM
模型
-
M
模型(
Model
):对应这data中的数据 -
V
视图(
View
):模板 -
VM
视图模型(
ViewModel
):Vue
实例对象 -
*
MVVM
*模型总结data
中所有的属性,最后都出现在vm
身上。vm
身上所有的属性及Vue
原型上所有属性,在Vue
模板中都可以直接使用
第四章、数据代理
-
回顾
Object.defineProperty
方法<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>defineProperty方法</title> </head> <body> <script> let person = { name: "张三", sex: "男" } let numbers = 12; //Object.defineProperty 对添加数据进行限制 Object.defineProperty(person, "age", { // value: 18, // enumerable: true,//控制属性是否可以枚举, 默认值是false // writable: true,//控制属性是否可以修改, 默认值是false // configurable: true,//控制属性是否可以删除, 默认值是false //当有数据被读取的时候就执行这个方法 get() { console.log("数据被执行了") return numbers }, //当被修改的时候就执行这个方法 set(v) { console.log("数据被修改了") numbers = v } }) </script> </body> </html>
-
数据代理
通过一个对象代理另一个对象的中的属性读写
-
Vue
中的数据代理Object.defineProperty
进行数据代理,实现data
里面的数据进行动态的数据代理
第五章、监视属性
通过handler这个方法去监听数据的更新和变化
immediate
初始化监视属性deep
监视子项的变换
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>监视属性</title>
</head>
<body>
<div id="app">
<input type="text" name="" id="" v-model="aaa">
<input type="text" name="" id="" v-model="bbb">
<h1>{{fullName}}</h1>
<br>
<input type="text" v-model="arr.name">
<button @click="arr.age++">{{arr.age}}</button>
</div>
<script src="vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
aaa: "1",
bbb: "2",
arr: {
name: "张三",
age: 15
}
}
},
computed: {
fullName: function () {
return this.aaa + this.bbb
}
},
// 页面开始渲染的时候监视属性(这里是官网里官网案例)
created() {
this.$watch('aaa', {
//初始化监听handler的变换
immediate: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
})
this.$watch('fullName', {
//初始化监听handler的变换
immediate: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
})
this.$watch('arr', {
//初始化监听handler的变换
immediate: true,
// 监视子项的变化
deep: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
})
},
// 在监视器里监视属性
watch: {
aaa: {
//初始化监听handler的变换
immediate: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
},
fullName: {
immediate: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
},
arr: {
immediate: true,
// 监视子项的变化
deep: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
},
'arr.name': {
immediate: true,
// 监视某个子项的变化
deep: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
},
// 简写形式是不能配置immediate和deep的
aaa(newdata, olddata) {
console.log(newdata, olddata);
}
}
}).mount('#app')
//这也是一种监听器,但只能监听一个,属性不能监听多,而且要写在实例化后面
.$watch('arr', {
//初始化监听handler的变换
immediate: true,
// 监视子项的变化
deep: true,
handler(newdata, olddata) {
console.log(newdata, olddata);
}
})
</script>
</body>
</html>
第六章、全家API
-
Vue.set
-
参数:
-
返回值:设置的值。
-
用法:
向响应式对象中添加一个
property
,并确保这个新property
同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新property
,因为Vue
无法探测普通的新增property
(比如this.myObject.newProperty = 'hi'
) -
案例:
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>vue.set方法</title> </head> <body> <div id="app"> <h1>支持vue2.0使用</h1> <input type="text" name="" id="" v-model="aaa" placeholder="添加地址"> <ul> <li>{{arr.name}}--{{arr.age}}--{{arr.dz}}</li> </ul> <br> <button @click="txsx()">添加</button> </div> <script src="vue.js"></script> <script> const vm = new Vue({ data() { return { aaa: "", arr: { name: "张三", age: 15 } } }, methods: { txsx() { this.$set(this.arr, 'dz', this.aaa); } } }).$mount('#app') </script> </body> </html>
-
注意:
vue.set
只支持vue2.0
,*vue3.0
*应该有类似的实现,会在添加
-
-
待修改
第七章、过滤器
Vue2
存在Vue3
被移除了,不是很重要的,但是可以了解一下
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>过滤器</title>
</head>
<body>
<div id="app">
<h1>{{time}}</h1>
<h1>{{time | getLocalTime}}</h1>
</div>
<script src="js/vue2.js"></script>
<script>
const vm = new Vue({
data() {
return {
time: new Date().getTime()
}
},
filters: {
getLocalTime(nS) {
console.log(nS)
return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' ');
}
}
}).$mount('#app')
</script>
</body>
</html>
第八章、组件
-
传统方式编写应用
-
通过组件编写应用
-
什么是组件
实现应用中局部功能代码和资源的集合
-
怎么实现
Vue
组件-
非单文件组件
-
一个文件包含多个组件
-
Vue2
写法<!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>组件</title> <script src="js/vue2.js"></script> </head> <body> <div id="app" style="border: solid 1px red"> <hello></hello> <hr> <!--第三步:渲染组件--> <school></school> <hr> <!--第三步:渲染组件--> <student></student> </div> <hr> <div id="test" style="border: solid 1px black"> <hello></hello> </div> </body> <script> // 第一步:定义组件school和student const school = Vue.extend({ template: ` <div> <h2>这是school组件</h2> <h2>{{name}}</h2> <h2>{{address}}</h2> <button @click="schoolFunction">点我</button> </div> ` , methods: { schoolFunction() { alert(this.name) } }, data() { return { name: "家里蹲", address: "世界尽头" } } }) const student = Vue.extend({ template: ` <div> <h2>这是student组件</h2> <h2>{{name}}</h2> <h2>{{age}}</h2> <button @click="studentFunction">点我</button> </div> ` , methods: { studentFunction() { this.age++ } }, data() { return { name: "曹李赖赖", age: 18 } } }) const hello = Vue.extend({ template: ` <div> <h2>这是全局组件</h2> <h2>{{age}}</h2> <button @click="helloFunction">点我</button> </div> ` , methods: { helloFunction() { this.age++ } }, data() { return { age: 18 } } }) // 第二步:注册逐渐(全局的) Vue.component('hello', hello) // 创建vue实例 new Vue({ el: '#app', // 第二步:注册逐渐(局部) components: { school: school, student: student } }) new Vue({ el: '#test', }) </script> </html>
-
Vue3
写法
-
-
单文件组件
一个文件包含一个组件,文件后缀为
.vue
的文件,明规则首字母大,只支持脚手架使用 -
组件之间嵌套
-
Vue2
写法<!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>组件</title> <script src="js/vue2.js"></script> <style> * { margin: 0; padding: 0; } </style> </head> <body> <div id="app" style="border: solid 5px red;"> <app></app> </div> </body> <script> const student = Vue.extend({ template: ` <div> <h2>这是student组件</h2> <h2>{{name}}</h2> <h2>{{age}}</h2> <button @click="studentFunction">点我</button> </div> ` , methods: { studentFunction() { this.age++ } }, data() { return { name: "曹李赖赖", age: 18 } } }) const school = Vue.extend({ template: ` <div style="background-color:yellow"> <h2>这是school组件</h2> <h2>{{name}}</h2> <h2>{{address}}</h2> <button @click="schoolFunction">点我</button> <student style="border: solid 1px red;background-color:#732097"></student> </div> ` , components: { student: student }, methods: { schoolFunction() { alert(this.name) } }, data() { return { name: "家里蹲", address: "世界尽头" } } }) const hello = Vue.extend({ template: ` <div style="background-color: aqua"> <h2>这是hello组件</h2> <h2>{{age}}</h2> <button @click="helloFunction">点我</button> </div> ` , methods: { helloFunction() { this.age++ } }, data() { return { age: 18 } } }) const app = Vue.extend({ template: ` <div style="border:solid 1px black;margin: 5px"> <school></school> <hello></hello> <button @click="schoolFunction">点我</button> </div> ` , components: { school: school, hello: hello }, methods: { schoolFunction() { alert("我是app组件") } } }) // 创建vue实例 new Vue({ el: '#app', // 可以通过template实现渲染 // template: // ` // <app></app> // `, // 注册逐渐(局部) components: { app } }) </script> </html>
-
Vue3
写法
-
-
组件的民命规则
-
Vue.component
-
-
第九章、脚手架 —— Vue_CLI
-
怎么搭建脚手架
-
官方脚手架网址:https://cli.vuejs.org/zh/
-
通过
CMD
指令查看电脑是否安装脚手架:vue -V
(安装了会出现脚手架版本) -
安装脚手架:
在
CMD
执行npm install -g @vue/cli
这个指令 -
创建项目:
-
切换创建项目的目录,这一步很重要,这就是你项目的所在位置
-
执行指令:
vue create
加你要创建的项目名称 -
选择对应的指令创建项目(这里我选择vue2,回车即可)
-
项目创建完成,这里出现
Successfully
,就说明了创建完成了 -
启动项目
- 执行
cd 你的项目名称
- 执行
npm run scrve
- 复制
Local
后面的地址用浏览器的开 - 打开后页面就下面的样子
- 用浏览篇的控制台里的
vue
插件1看看组件是否是这样的
注意:
cmd
窗口不要关闭,不然项目就关闭了 - 执行
-
-
第十章、ref属性
-
被用来给元素组件注册应用信息(ID的替代者)
-
应用在
HTML
标签上获取的是真实的DOM
元素,应用在组件标签上是组件实例对象2<template> <div id="app"> <h1 v-text="msg" ref="title"></h1> <button ref="button" @click="showDOM()">提示信息</button> <test ref="Text"/> </div> </template> <script> import test from "./components/test.vue"; export default { name: 'App', components: {test}, data() { return { msg: "你好啊!" } }, methods: { showDOM() { console.log(this.$refs.title)//真实的DOM元素 console.log(this.$refs.button)//真实的DOM元素 console.log(this.$refs.Text)//组件的实例对象(VC) } } } </script> <style> * { margin: 0; padding: 0; } </style>
第十一章、props配置
让组件接受外部穿过来的数据
-
传递数据
<test name="张三" :age="15" :sex="1"/>
-
接受数据
-
只接收
<template> <div> <span>{{msg}}</span> <br> <span>学生名字:{{name}}</span> <br> <span>学生性别:{{sex === 1 ? "男" : "女"}}</span> <br> <span>学生年龄:{{myAge}}</span> <br> <button @click="UpDataAge">常识修改信息(控制台会报错)</button> </div> </template> <script> export default { data() { return { msg: "学生信息", myAge: this.age } }, methods: { // props传输的值是不能修改的,直接修改会报错,说以可以在data定义,因为props的优先级高于data UpDataAge() { this.myAge++ } }, // 接收到的props是不能修改的 props: ['name', 'sex', 'age', 'number'] ,//简单申明接收, } </script> <style> </style>
-
限制类型
<template> <div> <span>{{msg}}</span> <br> <span>学生名字:{{name}}</span> <br> <span>学生性别:{{sex === 1 ? "男" : "女"}}</span> <br> <span>学生年龄:{{myAge}}</span> <br> <button @click="UpDataAge">常识修改信息(控制台会报错)</button> </div> </template> <script> export default { data() { return { msg: "学生信息", myAge: this.age } }, methods: { // props传输的值是不能修改的,直接修改会报错,说以可以在data定义,因为props的优先级高于data UpDataAge() { this.myAge++ } }, props: { //接受的同时对数据进行类型限制 name: String, sex: Number, age: Number }, } </script> <style> </style>
-
限制类型、限制必要性、指定默认值
<template> <div> <span>{{msg}}</span> <br> <span>学生名字:{{name}}</span> <br> <span>学生性别:{{sex === 1 ? "男" : "女"}}</span> <br> <span>学生年龄:{{myAge}}</span> <br> <button @click="UpDataAge">常识修改信息(控制台会报错)</button> </div> </template> <script> export default { data() { return { msg: "学生信息", myAge: this.age } }, methods: { // props传输的值是不能修改的,直接修改会报错,说以可以在data定义,因为props的优先级高于data UpDataAge() { this.myAge++ } }, props: { //接受的同时对数据进行类型限制,默认值的指定,必要性的限定 name: { type: String, required: true, }, sex: { type: Number, required: true, }, age: { type: Number, default: 0 } } } </script> <style> </style>
-
备注:
props
是只读的,Vue
底层监测你对props
的修改,如果进行了修改,就会发出警告,若业务确实需要修改,那么请复制props
的内容打Data
中一份,然后去修改Data
中的数据
第十二章、mixin配置——混入
可以把多个组件共用的配在提取成一个混入对象
-
局部混入
-
先定义一个
minxin.js
文件,内容如下3export const mixin = { methods: { ShowName() { console.log(this.name) } }, mounted() { console.log("执行了" + this.name) } } export const mixin2 = { data() { return { new_Json: "Json" } } }
-
然后在组件里引用
<template> <div class="Student"> <h3 @click="ShowName">学生名字:{{name}}</h3> <h3>学生性别:{{sex}}</h3> <h3>{{new_Json}}</h3> </div> </template> <script> import {mixin} from "../mixin" import {mixin2} from "../mixin" export default { data() { return { name: "张三", sex: "男" } }, mixins:[mixin,mixin2] } </script> <style> .Student { color: blue; } </style>
<template> <div class="school"> <h3 @click="ShowName">学校名字:{{name}}</h3> <h3>学校地址:{{address}}</h3> <h3>{{new_Json}}</h3> </div> </template> <script> import {mixin} from "../mixin" import {mixin2} from "../mixin" export default { data() { return { name: "家里蹲", address: "世界尽头" } }, mixins: [mixin, mixin2] } </script> <style> .school { color: red; } </style>
-
-
全局混入
-
先定义一个
minxin.js
文件,内容如下3export const mixin = { methods: { ShowName() { console.log(this.name) } }, mounted() { console.log("执行了" + this.name) } } export const mixin2 = { data() { return { new_Json: "Json" } } }
-
在
main.js
里面添加几行代码// 引入通用的混合类 import {mixin, mixin2} from './mixin' // 调用mixinf添加混合 Vue.mixin(mixin) Vue.mixin(mixin2)
-
查看控制台是否成功,都出现红框内容说明成功了
-
第十三章、插件4
加强Vue,包含
install
方法的一个对象,install
的第一个参数是Vue
,第二个以后的参数是插件使用者传递的数据。
-
自定义插件使用方式
-
先定义一个
plugins.js
5export default { install(Vue) { // 全局过滤器 Vue.filter('mySlice', function (value) { return value.slice(0, 5) }) // 全局自定义指令 Vue.directive('FBind', { // 指令与元素成功绑定时 bind(element, binding) { element.value = binding.value }, // 指令所在元素被插入页面时 inserted(element) { element.focus() }, // 指令所在的模板被从新解析时 update(element, binding) { element.value = binding.value } }) // 全局的混入 Vue.mixin({ data() { return { new_Json: "Json" } } }) // 给Vue原型上添加一个方法 Vue.prototype.hello = () => { console.log(123) } } }
-
在
main.js
添加下面代码import plugins from './plugins'// 引入插件 Vue.use(plugins)// 应用插件
-
在组件使用插件里添加的类(这里是在APP组件里使用)
<template> <div id="app"> <School/> <!--使用了插件的过滤器--> <h3> {{name | mySlice}}</h3> <!--使用了插件里的混入里面的数据--> <h3>mixin:{{new_Json}}</h3> <!-- 使用了插件的自定义指令--> <label> <input type="text" v-FBind:value="name"> </label> <button @click="test">{{name}}button</button> </div> </template> <script> import School from "./components/School"; export default { name: 'App', components: {School}, data() { return { name: "APP" } }, methods: { test() { // 使用了插件里自定义方法 this.hello() } } } </script> <style> * { margin: 0; padding: 0; } </style>
-
第十四章、scoped
属性、less
-
scoped
的使用-
简单定义两个组件并设置样式
<template> <div class="bc"> <h3>学生姓名:{{name}}</h3> </div> </template> <script> export default { data() { return { name: "张三" } } } </script> <style scoped> .bc { background-color: blue; } </style>
<template> <div class="bc"> <h3>学校名称:{{name}}</h3> <div class="test"> <h3>test</h3> </div> </div> </template> <script> export default { data() { return { name: "家里蹲" } } } </script> <style scoped lang="less"> .bc { background-color: red; .test { border: solid 1px #000000; } } </style>
-
查看效果
发现虽然两个组件都设置不同的背景颜色,但是都变成相同的了,应为用了相同的
class
样式名,所以会用你最后引入的组件的样式,进行往前覆盖,我最后引入的是蓝色,说以全都是蓝色 -
使用
scoped
用法:让样式局部生效,防止冲突
写法:
style
标签上面添加scoped
即可<style scoped>
注意:
app
里面添加scoped
属无效的,因为scoped
只会在局部生效在app
设置是无意义的
-
-
less
的使用-
在终端执行命令
npm i less-loader@7
-
使用
less
6写法:
style
标签上面添加lang="less"
即可<style lang="less">
-
第十五章、 WebStorage
-
存储内容大小一般支持在
5MB
左右7 -
浏览器端通过
Window.sessionStorage
和Window.localStorage
属性类实现本地储存机制 -
API
-
xxxxxxStorage.setItem('key','value')
该方法接收一个键和值作为参数,会把键值添加到存储中,如果键名存在,则是更新对应的值
-
xxxxxxStorage.getItem('person')
该方法接收一个键名作为参数,返回键名对应的值
-
xxxxxxStorage.removeItem('key')
该方法接收一个键名作为参数,并把该键名从存储中删除
-
xxxxxxStorage.clear()
该方法清空储存中的数据
-
-
备注:
sessionStorage
存储的内容会随着浏览器关闭而消失localStorage
存储的内容,需要手动清除才会消失xxxxxxStorage.getItem('person')
value
获取不到,那么返回值就是null
-
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>浏览器本地存储</title> </head> <body> <h3>localStorage浏览器关闭还存储着数据</h3> <button onclick="SaveData()">保存浏览器本地数据</button> <button onclick="ReadData()">读取浏览器本地数据</button> <button onclick="DeleteData()">删除一条浏览器本地数据</button> <button onclick="DeleteAllData()">删除全部浏览器本地数据</button> <div id="box"> </div> <script> function SaveData() { localStorage.setItem('str', '你好') localStorage.setItem('num', '123') // JSON.stringify显示obj类型数据 localStorage.setItem('objs', JSON.stringify({name: '张三', age: '18'})) box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = '保存成功,请查看控制台' box.appendChild(span) box.appendChild(br) } function ReadData() { // 读取不到数据都是null box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = localStorage.getItem('str') + ',' + localStorage.getItem('num') + ',' + localStorage.getItem('objs') box.appendChild(span) box.appendChild(br) } function DeleteData() { localStorage.removeItem('str') box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = '删除成功,请查看控制台' box.appendChild(span) box.appendChild(br) } function DeleteAllData() { localStorage.clear() box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = '清除成功,请查看控制台' box.appendChild(span) box.appendChild(br) } </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>浏览器本地会话</title> </head> <body> <h3>sessionStorage浏览器关闭时清空会话</h3> <button onclick="SaveData()">保存浏览器本地会话</button> <button onclick="ReadData()">读取浏览器本地会话</button> <button onclick="DeleteData()">删除一条浏览器本地会话</button> <button onclick="DeleteAllData()">删除全部浏览器本地会话</button> <div id="box"> </div> <script> function SaveData() { sessionStorage.setItem('str', '你好') sessionStorage.setItem('num', '123') // JSON.stringify显示obj类型会话 sessionStorage.setItem('objs', JSON.stringify({name: '张三', age: '18'})) box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = '保存成功,请查看控制台' box.appendChild(span) box.appendChild(br) } function ReadData() { // 读取不到会话都是null box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = sessionStorage.getItem('str') + ',' + sessionStorage.getItem('num') + ',' + sessionStorage.getItem('objs') box.appendChild(span) box.appendChild(br) } function DeleteData() { sessionStorage.removeItem('str') box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = '删除成功,请查看控制台' box.appendChild(span) box.appendChild(br) } function DeleteAllData() { sessionStorage.clear() box = document.getElementById("box") span = document.createElement("span") br = document.createElement("br") span.innerText = '清除成功,请查看控制台' box.appendChild(span) box.appendChild(br) } </script> </body> </html>
第十六章、组件的自定义事件
-
绑定
-
通过调用父组件方法实现向父组件传值
-
父组件
<template> <div id="app"> <H3>{{msg}}</H3> <!--通过调用父组件方法实现向父组件传值--> <h3>这是学校传过来的数据:{{GetSchoolNameData}}</h3> <School :GetSchoolName="GetSchoolName" class="School"/> </div> </template> <script> import School from "./components/School"; export default { name: 'App', components: {Student, School}, data() { return { msg: "你好啊", GetStudentNameData: "", GetSchoolNameData: "", } }, methods: { GetSchoolName(name) { this.GetSchoolNameData = name console.log(name) } } } </script> <style> * { margin: 0; padding: 0; color: white; } #app { background-color: grey; padding: 5px; } .School { background-color: aqua; margin-bottom: 5px; } </style>
-
子组件
<template> <div> <h3>学校名称:{{name}}</h3> <div> <h3>test</h3> <h3>{{GetSchoolName(name)}}</h3> </div> </div> </template> <script> export default { data() { return { name: "家里蹲" } }, // 使用 props 接收父组件过来的值 props: ['GetSchoolName'] } </script>
-
-
通过自定义事件向父组件传值
-
使用
v-on
绑定-
父组件
<template> <div id="app"> <H3>{{msg}}</H3> <!--通过自定义事件向父组件传值--> <!--使用 v-on--> <h3>这是学生传过来的数据:{{GetStudentNameData}}</h3> <!--<Student @StudentName="GetStudentName" class="Student"/>--> <!--这种写法要想触发一次可以这样写--> <Student @StudentName.once="GetStudentName" class="Student"/> </div> </template> <script> import Student from "./components/Student"; export default { name: 'App', components: {Student, School}, data() { return { msg: "你好啊", GetStudentNameData: "", GetSchoolNameData: "", } }, methods: { GetStudentName(name) { this.GetStudentNameData = name console.log(name) } } } </script> <style> * { margin: 0; padding: 0; color: white; } #app { background-color: grey; padding: 5px; } .Student { background-color: pink; } </style>
-
子组件
<template> <div> <h3>学生姓名:{{name}}</h3> <button @click="Send">按钮</button> </div> </template> <script> export default { data() { return { name: "张三" } }, methods: { Send() { this.$emit('StudentName', this.name) } } } </script>
-
-
使用
ref
绑定-
父组件
<template> <div id="app"> <H3>{{msg}}</H3> <!--使用 ref (可以灵活使用)--> <Student ref="StudentData" class="Student"/> </div> </template> <script> import Student from "./components/Student"; import School from "./components/School"; export default { name: 'App', components: {Student, School}, data() { return { msg: "你好啊", GetStudentNameData: "", GetSchoolNameData: "", } }, methods: { GetStudentName(name) { this.GetStudentNameData = name console.log(name) } }, mounted() { // 可以重复触发(配合第二种写法) this.$refs.StudentData.$on('StudentName', this.GetStudentName) // 只触发一次(配合第二种写法) // this.$refs.StudentData.$once('StudentName', this.GetStudentName) } } </script> <style> * { margin: 0; padding: 0; color: white; } #app { background-color: grey; padding: 5px; } .School { background-color: aqua; margin-bottom: 5px; } .Student { background-color: pink; } </style>
-
子组件
<template> <div> <h3>学生姓名:{{name}}</h3> <button @click="Send">按钮</button> </div> </template> <script> export default { data() { return { name: "张三" } }, methods: { Send() { this.$emit('StudentName', this.name) } } } </script>
-
-
-
-
解绑
<template> <div> <h3>学生姓名:{{name}}</h3> <button @click="Send">按钮</button> <button @click="UnSend">按钮</button> </div> </template> <script> export default { data() { return { name: "张三" } }, methods: { Send() { this.$emit('StudentName', this.name) this.$emit('StudentName1', this.name) }, UnSend() { // 解绑单个事件 // this.$off('StudentName') // 解绑多个事件 // this.$off(['StudentName', 'StudentName1']) // 解绑全部事件 this.$off() } } } </script>
第十七章、全局事件总线
一种组件通信的方式,使用与任意组件通讯
按装全局事件总线:在
Main.js
里Vue
的实例对象添加如下代码// 创建Vue实例对象 new Vue({ // 定义全局事件总线 beforeCreate() { Vue.prototype.$bus = this } }).$mount('#app')
使用事件总线:
接收数据:组件一想接收数据,则在组件一中给
$bus
绑定自定义事件,事件的回调留在组件一自身mounted() { // 接收数据 this.$bus.$on('事件名', (value) => { //方法体 }) },
提供数据:
this.$bus.$emit('事件名', person)
解绑$bus在这个组件的自定义事件一定要添加
beforeDestroy() { // TODO 解绑$bus在这个组件的自定义事件 一定要添加 this.$bus.$off(['事件1', '事件2']) }
第十八章、消息订阅和发布-- pubsub.js
的使用8
一种组件通信的方式,使用与任意组件间通信
使用步骤:
安装
npm i pubsub-js
引入
import pubsub from 'pubsub-js'
接收数据
mounted() { // msgName事件名称 // data数据 this.pubId = pubsub.subscribe('Student', (msgName, data) => { console.log("收到消息订阅", msgName, data) }) }
提供数据
methods: { sendStudentName() { // pubsub.publish(事件名称,数据) pubsub.publish('Student', 213) } }
解绑
beforeDestroy() { // 解绑 pubsub.unsubscribe(this.pubId) }