vue 基础 (二) 组件传值
组件间传值
1 父向子传值prop
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <parentchild-value :msg="msgprop"></parentchild-value> </div> <script> let parentchildvalue={ props:["msg"], template:`<div>{{msg}}</div>` } let vue = new Vue({ el: "#app", data:{ msgprop:"父向子传值prop" }, methods: {}, components:{ "parentchild-value":parentchildvalue } }); </script> </body> </html>
2 子向父传值 inject
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>子向父传值 inject</h1> <childparent-value></childparent-value> <div></div> </div> <script> let childparentvalue = { inject: ["provide"], template: `<div>{{provide}}</div>`, }; let vue = new Vue({ el: "#app", data: { value: "inject 传值", }, methods: {}, provide() { return { provide: this.value, }; }, components: { "childparent-value": childparentvalue, }, }); </script> </body> </html>
3测试子获取root组件值和方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>3测试子获取root组件值和方法</h1> <child-root></child-root> </div> <script> let childRoot = { template: `<div><span>{{rootmsg}}</span><button @click="handle">调用root方法</button></div>`, data() { return { rootmsg: this.$root.rootmsg, }; }, methods: { handle: function () { this.$root.rootHandle(); }, }, }; let vue = new Vue({ el: "#app", data: { rootmsg:"rootmsg" }, methods: { rootHandle: function () { console.log(this.$root) alert("root方法调用"); }, showName:function(){ alert("showname") }, handle: function () { this.$root.showName(); this.$root.rootHandle(); console.log(this.$root) }, }, components: { "child-root": childRoot, }, }); </script> </body> </html>
4测试子获取parent组件值的方法
<!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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <h1>4测试子获取parent组件值的方法</h1> <child-parent></child-parent> </div> <script> //4测试子获取parent组件值的方法 var childParent = { template: `<div><span>{{parentmsg}}</span><button @click="handle">调用root方法</button></div>`, data() { return { parentmsg: this.$parent.parentmsg, }; }, methods: { handle: function () { this.$parent.rootHandle(); }, }, }; var vm = new Vue({ el: "#app", data: { parentmsg:"parent" }, methods: { rootHandle:function(){ alert("parent 方法") } }, components:{ "child-parent":childParent, }, }); </script> </body> </html>
5测试父调子值和方法
<!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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <h1>5测试父调子值和方法</h1> <span>测试父调子的值</span><span></span> <button @click="refHandle">测试调用子的方法</button> <child-refs ref="ref"></child-refs> </div> </div> <script> //5测试父调子值和方法 var childRefs = { data() { return { refmsg: "我是refmsg", }; }, template: `<div>{{refmsg}}</div>`, methods: { refHandle: function () { alert(this.refmsg + "方法"); }, }, }; var vm = new Vue({ el: "#app", data: { }, methods: { refHandle: function () { console.log(this.$refs.ref); this.$refs.ref.refHandle(); }, }, components:{ "child-refs":childRefs, }, }); </script> </body> </html>
//6测试子向夫emit传值
<!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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <h1>6测试子向夫emit传值</h1> <childe-emit @parent="emitHandle">点击接收子的消息内容</childe-emit> </div> </div> <script> //6测试子向夫emit传值 var childEmit = { data() { return { name: "emit子消息", }; }, template: `<div><button @click="handleChlid">子按钮</button></div>`, methods: { handleChlid: function () { this.$emit("parent", this.name); }, }, }; var vm = new Vue({ el: "#app", data: {}, methods: { emitHandle: function (name) { alert("接收到子的name了=" + name); }, }, components: { "childe-emit": childEmit, }, }); </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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <h1>11测试$attr 继承父组件的props</h1> <parent-attr></parent-attr> </div> </div> <script> Vue.component("parent-attr", { data() { return { msg: "你好世界", }; }, template: `<div style="color:blue" :pchild="msg" >测试$attr<child-attr type="checkbox" data-status="哈哈" ></child-attr></div>`, methods: {}, }); Vue.component("child-attr", { inheritAttrs: false, template: `<input type="text" v-bind="$attrs"/>`, methods: { handle: function () {}, }, }); var vm = new Vue({ el: "#app", data: {}, methods: { }, components: { }, }); </script> </body> </html>
11测试$attr 继承父组件的props
<!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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <h1>11测试$attr 继承父组件的props</h1> <parent-attr></parent-attr> </div> </div> <script> Vue.component("parent-attr", { data() { return { msg: "你好世界", }; }, template: `<div style="color:blue" :pchild="msg" >测试$attr<child-attr type="checkbox" data-status="哈哈" ></child-attr></div>`, methods: {}, }); Vue.component("child-attr", { inheritAttrs: false, template: `<input type="text" v-bind="$attrs"/>`, methods: { handle: function () {}, }, }); var vm = new Vue({ el: "#app", data: {}, methods: { }, components: { }, }); </script> </body> </html>
12测试动态组件
<!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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <div class="box"> <h1>12测试动态组件</h1> <button v-for="tab in tabs" @click="currentTab=tab.title"> {{tab.displayName}} </button> <keep-alive> <component :is="currentTabComponent"></component> </keep-alive> </div> </div> </div> <script> //12测试动态组件 Vue.component("tab-introduce", { data() { return { content: "java无难事", }; }, template: `<div><input type="text" v-model="content"/></div>`, }); Vue.component("tab-comment", { template: `<div>这是一本好书</div>`, }); Vue.component("tab-qa", { template: `<div>有人看过吗</div>`, }); var vm = new Vue({ el: "#app", data: { currentTab: "introduce", tabs: [ { title: "introduce", displayName: "图书介绍" }, { title: "comment", displayName: "图书评价" }, { title: "qa", displayName: "图书问答" }, ], }, computed: { currentTabComponent: function () { return "tab-" + this.currentTab; }, }, methods: { }, components: { }, }); </script> </body> </html>
13测试组件异步更新队列
<!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> <script src="../js/vue.js"></script> <style> .box { width: 500px; border: 1px solid red; float: left; } ul { list-style: none; } </style> </head> <body> <div id="app"> <div class="box"> <h1>13测试组件异步更新队列</h1> <async-component></async-component> </div> </div> <script> //13测试组件异步更新队列 Vue.component("async-component",{ data() { return { message:"java无难事" } }, template:` <div> <p >{{message}}</p> <p >{{message}}</p> <button @click="change">修改内容</button> </div>`, methods:{ change:function(){ this.message='深入理解vc' // this.$nextTick(()=>{}) // console.log(this) // console.log(this.$refs) // console.log(this.$refs.msg.textContent); } } }) var vm = new Vue({ el: "#app", data: { currentTab: "introduce", tabs: [ { title: "introduce", displayName: "图书介绍" }, { title: "comment", displayName: "图书评价" }, { title: "qa", displayName: "图书问答" }, ], }, computed: { currentTabComponent: function () { return "tab-" + this.currentTab; }, }, methods: { }, components: { }, }); </script> </body> </html>
keep-alive
keep-alive 是 Vue.js 中的一个内置抽象组件,用于缓存不活动的组件实例,而不是销毁它们。这对于保留组件状态或避免重新渲染开销较大的组件时非常有用。当组件被包裹在 <keep-alive> 中时,它的状态会被保留,当它再次被访问时,Vue 会重新渲染组件的已保留状态,而不是从头开始重新创建它。 基本用法 html <keep-alive> <component :is="currentView"></component> </keep-alive> 在这个例子中,currentView 是一个动态组件名,它决定了 <keep-alive> 内部应该渲染哪个组件。当 currentView 更改时,如果新的组件已经在 <keep-alive> 中被渲染过,那么它将不会被重新创建,而是会重新激活其已缓存的实例。 生命周期钩子 当组件被 <keep-alive> 包裹时,它会有两个额外的生命周期钩子: activated:当组件被激活时调用。 deactivated:当组件被停用时调用。 这两个钩子允许你在组件被缓存和重新激活时执行特定的逻辑。 排除和包含 <keep-alive> 允许你指定哪些组件应该被缓存,哪些不应该。这可以通过 include 和 exclude 属性来实现,它们接受逗号分隔的字符串、正则表达式或一个数组。 include:只有匹配的组件会被缓存。 exclude:任何匹配的组件都不会被缓存。 html <!-- 逗号分隔的字符串 --> <keep-alive include="ComponentA,ComponentB"> <component :is="currentView"></component> </keep-alive> <!-- 正则表达式 (使用 v-bind) --> <keep-alive :include="/A|B/"> <component :is="currentView"></component> </keep-alive> <!-- 数组 (使用 v-bind) --> <keep-alive :include="['ComponentA', 'ComponentB']"> <component :is="currentView"></component> </keep-alive> 注意事项 使用 <keep-alive> 时,需要注意内存使用,因为缓存的组件实例会占用内存。 如果组件内部有大量的数据或复杂的计算,那么即使使用 <keep-alive>,也可能不会显著提高性能,因为重新激活组件时仍然需要执行这些计算。 在某些情况下,你可能需要手动清除 <keep-alive> 的缓存,Vue 没有直接提供 API 来清除缓存,但你可以通过改变 currentView 的值来间接实现,或者通过其他方式(如使用 Vuex)来管理组件的缓存状态。
浙公网安备 33010602011771号