百度文库推广网站,wordpress图片放大代码,seo优化个人博客,湖南发展最新消息公告19、组件之间传递数据
组件与组件之间不是完全独立的#xff0c;而是有交集的#xff0c;那就是组件与组 件之间是可以传递数据的 传递数据的解决方案就是 props
ComponentA.vue
template!-- 使用ComponentB组件#xff0c;并传递title属性 --h3…19、组件之间传递数据
组件与组件之间不是完全独立的而是有交集的那就是组件与组 件之间是可以传递数据的 传递数据的解决方案就是 props
ComponentA.vue
template!-- 使用ComponentB组件并传递title属性 --h3ComponentA/h3ComponentB title传递数据/
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vue;export default {// 定义组件选项对象components: {// 将ComponentB注册为当前组件的局部组件ComponentB}
};
/script
ComponentB.vue
template!-- 使用props接收来自父组件的title属性 --h3ComponentB/h3p{{ title }}/p
/templatescript
export default {// 定义组件选项对象props: [title]
};
/script
动态数据传递
template!-- 使用ComponentA和ComponentB组件 --h3ComponentA/h3!-- 将父组件的数据message传递给ComponentB --ComponentB :titlemessage /
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vue;export default {// 定义组件选项对象data() {return {message: 动态数据 // 定义数据message};},components: {ComponentB // 将ComponentB注册为当前组件的局部组件}
};
/script 注意事项 props 传递数据只能从父级传递到子级不能反其道而行 组件传递多种数据类型
通过 props 传递数据不仅可以传递字符串类型的数据还可以是其 他类型例如数字、对象、数组等 但实际上任何类型的值都可以作为 props 的值被传递.
传递Number类型
ComponentA.vue
template!-- 显示ComponentA标题 --h3ComponentA/h3!-- 使用ComponentB组件并传递age属性 --ComponentB :ageage/
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vue;export default {data() {return {age: 20 // 定义数据age};},components: {ComponentB // 将ComponentB注册为当前组件的局部组件}
};
/script ComponentB.vue
template!-- 显示ComponentB标题 --h3ComponentB/h3!-- 显示从父组件传递过来的age属性 --p{{ age }}/p
/templatescript
export default {props: [age] // 定义props接收来自父组件的age属性
};
/script
传递Array类型
ComponentA.vue
template!-- 显示ComponentA标题 --h3ComponentA/h3!-- 使用ComponentB组件并传递names属性 --ComponentB :namesnames /
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vue;export default {data() {return {names: [iwen, ime, frank] // 定义数据names};},components: {ComponentB // 将ComponentB注册为当前组件的局部组件}
};
/script ComponentB.vue
template!-- 显示ComponentB标题 --h3ComponentB/h3!-- 使用v-for指令遍历names数组并显示每个元素 --p v-for(item, index) of names :keyindex{{ item }}/p
/templatescript
export default {props: [names] // 定义props接收来自父组件的names属性
};
/script
传递Object类型
ComponentA.vue
template!-- 显示ComponentA标题 --h3ComponentA/h3!-- 使用ComponentB组件并传递userInfo属性 --ComponentB :userInfouserInfo /
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vue;export default {data() {return {userInfo: { // 定义数据userInfoname: iwen,age: 20}};},components: {ComponentB // 将ComponentB注册为当前组件的局部组件}
};
/script ComponentB.vue
template!-- 显示ComponentB标题 --h3ComponentB/h3!-- 显示从父组件传递过来的userInfo.name属性的值 --p{{ userInfo.name }}/p!-- 显示从父组件传递过来的userInfo.age属性的值 --p{{ userInfo.age }}/p
/templatescript
export default {props: [userInfo] // 定义props接收来自父组件的userInfo属性
};
/script
组件传递Props效验
Vue 组件可以更细致地声明对传入的 props 的校验要求
ComponentA.vue
template!-- 显示ComponentA标题 --h3ComponentA/h3!-- 使用ComponentB组件并传递title和userInfo属性 --ComponentB titleProps效验 :userInfouserInfo /
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vue;export default {data() {return {userInfo: { // 定义数据userInfoname: iwen,age: 20}},components: {ComponentB // 将ComponentB注册为当前组件的局部组件}
};
/script
ComponentB.vue
template!-- 显示ComponentB标题 --h3ComponentB/h3!-- 显示从父组件传递过来的title属性的值 --p{{ title }}/p!-- 显示从父组件传递过来的userInfo.name属性的值 --p{{ userInfo.name }}/p!-- 显示从父组件传递过来的userInfo.age属性的值 --p{{ userInfo.age }}/p
/templatescript
export default {props: { // 定义props接收来自父组件的title和userInfo属性title: {type: String},userInfo: {type: Object}}
};
/script
默认值default
template!-- 显示ComponentB标题 --h3ComponentB/h3!-- 显示从父组件传递过来的title属性的值 --p{{ title }}/p!-- 显示从父组件传递过来的userInfo.name属性的值 --p{{ userInfo.name }}/p!-- 显示从父组件传递过来的userInfo.age属性的值 --p{{ userInfo.age }}/p!-- 显示从父组件传递过来的age属性的值 --p{{ age }}/p
/templatescript
export default {// 定义props选项接收来自父组件的title、userInfo和age属性props: {title: {type: String // title属性的类型为String},userInfo: {type: Object, // userInfo属性的类型为Objectdefault() {return {} // 默认值为空对象}},age: {type: Number, // age属性的类型为Numberdefault: 20 // 默认值为20}}
};
/script
必选项required
template!-- 显示ComponentB标题 --h3ComponentB/h3!-- 显示从父组件传递过来的title属性的值 --p{{ title }}/p!-- 显示从父组件传递过来的userInfo.name属性的值 --p{{ userInfo.name }}/p!-- 显示从父组件传递过来的userInfo.age属性的值 --p{{ userInfo.age }}/p!-- 显示从父组件传递过来的age属性的值 --p{{ age }}/p
/templatescript
export default {// 定义props选项接收来自父组件的title、userInfo和age属性props: {title: {type: String, // title属性的类型为Stringrequired: true // title属性是必需的},userInfo: {type: Object, // userInfo属性的类型为Object// 对象或者数组应当用工厂函数返回default() {return {} // 默认值为空对象}},age: {type: Number, // age属性的类型为Numberdefault: 20 // 默认值为20}
};
/script 在Vue.js中prop 是一种特殊的数据属性用于父组件向子组件传递数据。prop 是只读的这意味着子组件不能修改从父组件接收到的 prop 数据。如果尝试修改 prop 的值Vue 会发出警告信息提示 prop 是只读的。 20、组件事件
在Vue.js框架中组件之间的通信是一个常见的需求。$emit方法就是用来在组件的模板表达式中触发自定义事件的这使得父子组件之间可以进行通信。通过这种方式子组件可以向父组件发送消息比如通知某个操作已经完成或者请求父组件执行某个操作。
自定义事件的触发可以用于多种目的其中之一就是组件之间传递数据。例如当用户在子组件中进行某种操作时子组件可以通过$emit方法向父组件发送一个事件携带必要的数据。父组件可以监听这个事件并在事件触发时接收数据从而实现数据的传递。
父组件ComponentA.vue
template!-- 显示标题 --h3ComponentA/h3!-- 引入子组件ComponentB并监听名为some-event的自定义事件 --ComponentB some-eventgetHandle/!-- 显示从子组件接收到的数据 --pComponentA接受的数据: {{ message }}/p
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vueexport default {data() {return {// 初始化一个空字符串用于存储从子组件接收到的数据message: }},components: {// 注册子组件ComponentBComponentB},methods: {// 定义一个方法getHandle用于处理从子组件接收到的数据getHandle(data) {this.message data; // 将接收到的数据赋值给message属性}}
}
/script
子组件ComponentB.vue
template!-- 显示标题 --h3ComponentB/h3!-- 定义一个按钮点击时触发sendHandle方法 --button clicksendHandle发送数据/button
/templatescript
export default {methods: {// 定义一个方法sendHandle用于触发自定义事件并发送数据sendHandle() {this.$emit(someEvent, ComponentB的数据); // 触发名为someEvent的事件并传递数据}}
}
/script 组件之间传递数据 父传子使用 props 在Vue.js中props是父组件向子组件传递数据的一种方式。父组件可以通过在子组件标签中定义属性来传递数据这些属性在子组件内部可以通过props对象访问。 这种方式是单向数据流确保了数据的流向是从父组件到子组件有助于避免组件之间的耦合。 子传父使用自定义事件 (this.$emit) 当需要从子组件向父组件传递数据时可以使用自定义事件。子组件通过this.$emit方法触发一个事件并将数据作为参数传递。父组件需要监听这个事件并在事件触发时接收数据。 这种方式允许子组件在需要时通知父组件例如用户交互或数据变化。 组件事件配合 v-model 使用
如果是用户输入我们希望在获取数据的同时发送数据配合 v-model 来使用
父组件ComponentA.vue
templatedivh3ComponentA/h3!-- 使用some-event监听来自ComponentB的自定义事件 --componentB some-eventgetHandle/!-- 显示从ComponentB接收到的数据 --pComponentA接受的数据: {{ message }}/p/div
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vueexport default {data() {return {// 初始化message为空字符串用于存储从子组件接收的数据message: }},components: {// 注册子组件ComponentBComponentB},methods: {// 定义getHandle方法来接收从子组件传递的数据getHandle(data) {this.message data;}}
}
/script
子组件ComponentB.vue
templatedivh3ComponentB/h3!-- 使用v-model绑定输入框的值到searchText --input v-modelsearchText //div
/templatescript
export default {data() {return {// 初始化searchText为空字符串searchText: }},watch: {// 监听searchText的变化searchText(newVal, oldVal) {// 当searchText变化时触发someEvent事件并将新值作为参数传递this.$emit(someEvent, newVal);}}
}
/script
组件数据传递
通常我们使用 props 来实现父组件向子组件的数据传递单向下行绑定但Vue.js也提供了一种方式使得子组件可以通过 props 实现数据的“回传”给父组件这通常通过使用 .sync 修饰符或在Vue 3中使用 v-model 来实现。
父组件ParentComponent.vue
templatedivh3ComponentA/h3!-- 使用:onFnEvent监听来自ChildComponent的自定义事件 --Child :onFnEventfn /!-- 显示从ChildComponent接收到的数据 --p{{ message }}/p/div
/templatescript
// 导入子组件Child
import Child from ./components/Child.vue;export default {data() {return {// 初始化message为空字符串用于存储从子组件接收的数据message: }},methods: {// 定义fn方法来接收从子组件传递的数据fn(data) {this.message data;}},components: {// 注册子组件ChildChild}
}
/script
子组件Child.vue
templatedivh3组件传递数据/h3!-- 调用onFnEvent方法并传递数据 --p{{ onFnEvent(测试数据) }}/p/div
/templatescript
export default {props: {// 定义一个名为onFnEvent的prop类型为FunctiononFnEvent: {type: Function}}
}
/script 代码解释 父组件ParentComponent.vue: 在模板中使用Child :onFnEventfn /标签引入子组件并使用:onFnEventfn来监听子组件触发的事件。 当子组件触发事件时父组件的fn方法会被调用并接收子组件传递的数据。 message数据属性用于存储从子组件接收到的数据并在模板中显示。 子组件Child.vue: 在模板中调用onFnEvent方法并传递数据测试数据。 定义一个名为onFnEvent的prop类型为Function用于接收父组件传递的事件处理函数。 21、插槽 Slots 我们已经了解到组件能够接收任意类型的 JavaScript 值作为 props但组件要如何接收模板内容呢在某些场景中我们可能 想要为子组件传递一些模板片段让子组件在它们的组件中渲染这 些片段。
solt元素是一个插槽出口 (slot outlet)标示了父元素提供的插槽 内容 (slot content) 将在哪里被渲染.
父组件ComponentA.vue
templatedivh3ComponentA/h3!-- 使用ComponentB并在插槽中传递内容 --ComponentBh3插槽传递视图内容/h3/ComponentB/div
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vue;export default {components: {// 注册子组件ComponentBComponentB}
}
/script
子组件ComponentB.vue
templatedivh3ComponentB/h3!-- 使用slot标签来接收从父组件传递的内容 --slot/slot/div
/templatescript
export default {// ComponentB不需要额外的逻辑只需定义插槽
}
/script
渲染作用域
插槽内容可以访问到父组件的数据作用域因为插槽内容本身是在 父组件模板中定义的.
父组件ComponentA.vue
templatedivh3ComponentA/h3!-- 使用ComponentB并在插槽中传递内容 --ComponentBh3{{ message }}/h3/ComponentB/div
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vue;export default {data() {return {// 定义message数据属性用于存储要传递给子组件的内容message: message在父级}},components: {// 注册子组件ComponentBComponentB}
}
/script
子组件ComponentB.vue
templatedivh3ComponentB/h3!-- 使用slot标签来接收从父组件传递的内容 --slot/slot/div
/templatescript
export default {// ComponentB不需要额外的逻辑只需定义插槽
}
/script
默认内容
在外部没有提供任何内容的情况下可以为插槽指定默认内容.
templatedivh3ComponentB/h3!-- 使用slot标签定义插槽并设置默认内容 --slot插槽默认值/slot/div
/templatescript
export default {// ComponentB不需要额外的逻辑只需定义插槽和默认值
}
/script
具名插槽
父组件ComponentA.vue
templatedivh3ComponentA/h3!-- 使用ComponentB并为header和main插槽传递内容 --ComponentBtemplate v-slot:headerh3标题/h3/templatetemplate v-slot:mainp内容/p/template/ComponentB/div
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vue;export default {data() {return {// 定义message数据属性虽然在这个例子中没有用到message: message在父级}},components: {// 注册子组件ComponentBComponentB}
}
/script
子组件ComponentB.vue
templatedivh3ComponentB/h3!-- 使用slot标签定义具名插槽header --slot nameheader/slothr!-- 使用slot标签定义具名插槽main --slot namemain/slot/div
/templatescript
export default {// ComponentB不需要额外的逻辑只需定义具名插槽
}
/script 代码解释 父组件ComponentA.vue: 在模板中使用ComponentB标签引入子组件并为header和main插槽传递内容。 使用template v-slot:header和template v-slot:main来指定内容应该填充到哪个插槽中。 ComponentB组件被注册在父组件的components对象中使其可以在父组件的模板中使用。 子组件ComponentB.vue: 在模板中使用slot nameheader/slot和slot namemain/slot来定义具名插槽。这些插槽用于接收从父组件传递的内容。 当父组件使用ComponentB标签并包含具名插槽的内容时这些内容将替换子组件中的相应插槽标签。 在Vue.js中v-slot 指令用于定义插槽而 # 符号是 v-slot 的简写形式用于指定插槽的名称。 父组件ComponentA.vue
templatedivh3ComponentA/h3!-- 使用ComponentB并为header和main插槽传递内容 --ComponentBtemplate #headerh3标题/h3/templatetemplate #mainp内容/p/template/ComponentB/div
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vue;export default {data() {return {// 定义message数据属性用于存储要传递给子组件的内容message: message在父级}},components: {// 注册子组件ComponentBComponentB}
}
/script
子组件ComponentB.vue
templatedivh3ComponentB/h3!-- 使用slot标签定义具名插槽header --slot nameheader/slothr!-- 使用slot标签定义具名插槽main --slot namemain/slot/div
/templatescript
export default {// ComponentB不需要额外的逻辑只需定义具名插槽
}
/script
在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点我们需要一种方法来让子组件在渲染时 将一部分数据提供给插槽 我们也确实有办法这么做可以像对组件传递 props 那样向一个 插槽的出口上传递 attributes
父组件ComponentA.vue
templatedivh3ComponentA/h3!-- 使用ComponentB并通过具名插槽slotProps传递数据 --componentB v-slotslotPropsh3{{ message }}-{{ slotProps.text }}/h3/componentB/div
/templatescript
// 导入子组件ComponentB
import ComponentB from ./ComponentB.vue;export default {data() {return {// 定义message数据属性用于存储要传递给子组件的内容message: message在父级}},components: {// 注册子组件ComponentBComponentB}
}
/script 子组件ComponentB.vue
templatedivh3ComponentB/h3!-- 使用slot标签定义具名插槽并传递message数据 --slot :textmessage/slot/div
/templatescript
export default {data() {return {// 定义message数据属性用于存储子组件的数据message: ComponentB中的数据}}
}
/script 代码解释 父组件ComponentA.vue: 在模板中使用componentB标签引入子组件并为slotProps插槽传递内容。 使用template v-slotslotProps来指定内容应该填充到哪个插槽中并从子组件接收数据。 message数据属性用于存储要传递给子组件的内容。 ComponentB组件被注册在父组件的components对象中使其可以在父组件的模板中使用。 子组件ComponentB.vue: 在模板中使用slot :textmessage/slot来定义具名插槽。这个插槽用于接收从父组件传递的内容。 message数据属性用于存储子组件的数据并通过插槽传递给父组件。 具名插槽传递数据
template!-- 显示ComponentA的标题 --h3ComponentA/h3!-- 使用ComponentB组件并通过名为header的slot传递slotProps --ComponentB #headerslotProps!-- 显示从父组件传递的消息和slotProps.text --h3{{ message }}-{{ slotProps.text }}/h3/ComponentB
/templatescript
// 导入ComponentB组件
import ComponentB from ./ComponentB.vueexport default {data() {return {// 定义一个消息变量用于在模板中显示message: message在父级}},// 定义组件对象用于注册子组件components: {ComponentB}
}
/script
template!-- 显示ComponentB的标题 --h3ComponentB/h3!-- 使用slot允许父组件通过名为header的slot传递内容 --slot nameheader :textmessage/slot
/templatescript
export default {data() {return {// 定义一个消息变量用于在模板中显示message: ComponentB中的数据}}
}
/script
22、组件生命周期
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤比如 设置好数据侦听编译模板挂载实例到 DOM以及在数据改变 时更新 DOM。在此过程中它也会运行被称为生命周期钩子的函 数让开发者有机会在特定阶段运行自己的代码。 template!-- 显示组件生命周期的标题 --h3组件生命周期/h3!-- 显示message数据 --p{{ message }}/p!-- 一个按钮点击时调用updateHandle方法更新数据 --button clickupdateHandle更新数据/button
/templatescript
export default {// data函数返回一个对象其中包含一个message属性初始值为老数据data() {return {message: 老数据}},// methods对象包含组件的方法methods: {// updateHandle方法更新message属性的值为新数据updateHandle() {this.message 新数据}},// 生命周期钩子函数beforeCreate() {// 在组件实例初始化之后调用此时不能访问data中的属性console.log(组件创建之前);},created() {// 在实例创建完成后被立即调用此时可以访问data中的属性console.log(组件创建之后);},beforeMount() {// 在挂载开始之前被调用相关的render函数首次被调用console.log(组件渲染之前);},mounted() {// el被新创建的vm.$el替换并挂载到实例上去之后调用该钩子console.log(组件挂载之后);},beforeUpdate() {// 数据更新之前调用可以访问data中的属性但是视图尚未更新console.log(数据更新之前);},updated() {// 数据更新之后调用可以访问data中的属性视图已经更新console.log(数据更新之后);},beforeUnmount() {// 实例销毁之前调用此时可以访问data中的属性但是视图已经销毁console.log(组件卸载之前);},unmounted() {// 实例销毁后调用此时不能访问data中的属性console.log(组件卸载之后);}
}
/script beforeCreate在组件实例初始化之后调用此时不能访问data中的属性。 created在实例创建完成后被立即调用此时可以访问data中的属性。 beforeMount在挂载开始之前被调用相关的render函数首次被调用。 mountedel被新创建的vm.$el替换并挂载到实例上去之后调用该钩子。 beforeUpdate数据更新之前调用可以访问data中的属性但是视图尚未更新。 updated数据更新之后调用可以访问data中的属性视图已经更新。 beforeUnmount实例销毁之前调用此时可以访问data中的属性但是视图已经销毁。 unmounted实例销毁后调用此时不能访问data中的属性。 生命周期应用
通过ref获取元素DOM结构
template!-- 模板部分 --h3组件生命周期应用/h3!-- 一个段落元素通过ref属性设置引用名为name --p refname哈哈哈/p
/templatescript
export default {// beforeMount生命周期钩子beforeMount() {// 在这个阶段DOM尚未渲染因此$refs.name是undefinedconsole.log(this.$refs.name); // 输出undefined},// mounted生命周期钩子mounted() {// 在这个阶段DOM已经渲染完成可以通过$refs访问模板中的DOM元素console.log(this.$refs.name); // 输出p refname哈哈哈/p的DOM元素}
}
/script beforeMount 生命周期钩子在这个阶段Vue 已经完成了模板的编译但是还没有挂载 DOM 元素因此 this.$refs.name 是 undefined。 mounted 生命周期钩子在这个阶段Vue 已经完成了模板的挂载DOM 元素已经创建并添加到页面中因此可以通过 this.$refs.name 访问到 p 元素的 DOM 对象。 模拟网络请求渲染数据页面加载后初始化数据
template!-- 模板部分 --h3组件生命周期应用/h3!-- 使用v-for指令循环渲染banner数组中的每一项 --ulli v-for(item, index) in banner :keyindex!-- 显示每一项的标题 --h3{{ item.title }}/h3!-- 显示每一项的内容 --p{{ item.content }}/p/li/ul
/templatescript
export default {// data函数返回一个对象其中包含一个banner数组初始为空data() {return {banner: []}},// mounted生命周期钩子mounted() {// 在组件挂载到DOM后初始化banner数组this.banner [{title: 我在爱尔兰,content: 爱尔兰爱尔兰语Poblacht na hÉireann英语Republic of Ireland, 是一个西欧的议会共和制国家西临大西洋东靠爱尔兰海与英国隔海相望是北美通向欧洲的通道爱尔兰自然,},{title: 一个人的东京,content: 东京(Tokyo)是日本国的首都是亚洲第一大城市世界第二大城市。全球最大的经济中心之一。东京的著名观光景点有东京铁塔、皇居、国会议事堂、浅草寺、浜离宫、上野公园与动物园,},{title: 普罗旺斯的梦,content: 普罗旺斯(Provence)位于法国东南部毗邻地中海和意大利从地中海沿岸延伸到内陆的丘陵地区中间有大河“Rhone”流过。自古就以靓丽的阳光和蔚蓝的天空迷人的地中海和心醉,},{title: 相约夏威夷之夏,content: 夏威夷州位于北太平洋中距离美国本土3,700公里总面积16,633平方公里属于太平洋沿岸地区。首府为檀香山。在1778至1898年间夏威夷也被称为“三明治群岛”(Sandwich Islands),}]}
}
/script 23、动态组件
有些场景会需要在两个组件间来回切换比如 Tab 界面
templateh3ComponentA/h3
/template
templateh3ComponentB/h3
/template
template!-- 模板部分 --h3组件切换/h3!-- 使用 :is 绑定来动态切换组件 --component :iscurrentTab/component!-- 一个按钮点击时调用 changeComponentHandle 方法切换组件 --button clickchangeComponentHandle切换/button
/templatescript
// 导入ComponentA和ComponentB组件
import ComponentA from ./components/ComponentA.vue
import ComponentB from ./components/ComponentB.vueexport default {// 注册ComponentA和ComponentB为本地组件components: {ComponentA,ComponentB},// data函数返回一个对象其中包含一个currentTab属性用于控制显示哪个组件data() {return {currentTab: ComponentA, // 默认显示ComponentA}},// methods对象包含组件的方法methods: {// changeComponentHandle方法用于切换currentTab的值从而切换组件changeComponentHandle() {this.currentTab this.currentTab ComponentA ? ComponentB : ComponentA;}}
}
/script :is 是一个属性绑定它用于动态地绑定组件的名称或路径。 就相当于是componentA/ 24、组件保持存活
当使用 component :is... 来在多个组件间作切换时被切换掉的组件会被卸载。我们可以通过keep-alive组件强制被切换掉的组件仍然保持“存活”的状态下一次使用该组件的时候需要重新渲染浪费资源。
就是加个标签的事儿
template!-- 模板部分 --h3组件切换/h3!-- 使用 keep-alive 包裹动态组件保持切换组件的状态 --keep-alive!-- 使用 :is 绑定来动态切换组件 --!-- 当 currentTab 变化时Vue 将根据 currentTab 的值渲染对应的组件 --component :iscurrentTab/component/keep-alive!-- 一个按钮点击时调用 changeComponentHandle 方法切换组件 --!-- 这将改变 currentTab 的值从而触发组件的切换 --button clickchangeComponentHandle切换/button
/templatescript
// 导入ComponentA和ComponentB组件
import ComponentA from ./components/ComponentA.vue
import ComponentB from ./components/ComponentB.vueexport default {// 注册ComponentA和ComponentB为本地组件使其在模板中可用components: {ComponentA,ComponentB},// data函数返回一个对象其中包含一个currentTab属性用于控制显示哪个组件data() {return {currentTab: ComponentA, // 默认显示ComponentA组件}},// methods对象包含组件的方法methods: {// changeComponentHandle方法用于切换currentTab的值从而切换组件// 当按钮被点击时这个方法会被调用changeComponentHandle() {// 使用三元运算符来切换currentTab的值// 如果当前是ComponentA则切换到ComponentB反之亦然this.currentTab this.currentTab ComponentA ? ComponentB : ComponentA;}}
}
/script keep-alive 标签用于包裹动态组件 component :iscurrentTab/component。它的作用是保持组件的状态即使组件被切换之前的状态也不会丢失这样可以提高性能因为避免了不必要的组件销毁和重建。 25、异步组件
在大型项目中我们可能需要拆分应用为更小的块并仅在需要时再从服务器加载相关组件。Vue 提供了 defineAsyncComponent方法来实现此功能
template!-- 模板部分 --h3组件切换/h3!-- 使用 keep-alive 包裹动态组件保持切换组件的状态 --keep-alive!-- 使用 :is 绑定来动态切换组件 --!-- 当 currentTab 变化时Vue 将根据 currentTab 的值渲染对应的组件 --component :iscurrentTab/component/keep-alive!-- 一个按钮点击时调用 changeComponentHandle 方法切换组件 --!-- 这将改变 currentTab 的值从而触发组件的切换 --button clickchangeComponentHandle切换/button
/templatescript
// 从 vue 导入 defineAsyncComponent 方法用于定义异步组件
import { defineAsyncComponent } from vue
// 导入 ComponentA 组件
import ComponentA from ./components/ComponentA.vue
// 使用 defineAsyncComponent 定义异步加载的 ComponentB 组件
const AsyncComponentB defineAsyncComponent(() import(./components/ComponentB.vue)
)export default {// 注册 ComponentA 和 AsyncComponentB 为本地组件使其在模板中可用components: {ComponentA,AsyncComponentB},// data 函数返回一个对象其中包含一个 currentTab 属性用于控制显示哪个组件data() {return {currentTab: ComponentA, // 默认显示 ComponentA 组件}},// methods 对象包含组件的方法methods: {// changeComponentHandle 方法用于切换 currentTab 的值从而切换组件// 当按钮被点击时这个方法会被调用changeComponentHandle() {// 使用条件运算符来切换 currentTab 的值// 如果当前是 ComponentA则切换到 AsyncComponentB反之亦然this.currentTab this.currentTab ComponentA ? AsyncComponentB : ComponentA;}}
}
/script 异步组件 使用 defineAsyncComponent 方法定义了一个异步组件 AsyncComponentB。这允许 Vue 延迟加载 ComponentB.vue 文件直到实际需要渲染该组件时才加载。 异步组件在大型应用中非常有用可以减少初始加载时间提高性能。 26、依赖注入
通常情况下当我们需要从父组件向子组件传递数据时会使用 props。想象一下这样的结构有一些多层级嵌套的组件形成了一颗巨大的组件树而某个深层的子组件需要一个较远的祖先组件中的部分数据。在这种情况下如果仅使用 props 则必须将其沿着组件链逐级传递下去这会非常麻烦 。 这一问题被称为“prop 逐级透传”
provide 和 inject 可以帮助我们解决这一问题。 一个父组件相对于其所有的后代组件会作为依赖提供者。任何后代的组件树无论层级有多深都可以注入由父组件提供给整条链路的依赖 template!-- 模板部分 --h3祖宗/h3 !-- 显示“祖宗”标题 --Parent / !-- 使用子组件 Parent --
/templatescript
// 导入子组件 Parent
import Parent from ./components/Parent.vueexport default {// 使用 provide 提供一个 message可以在子孙组件中通过 inject 访问provide: {message: 爷爷的财产},// 注册子组件 Parent使其在模板中可用components: {Parent}
}
/script
template!-- 模板部分 --h3Parent/h3 !-- 显示“Parent”标题 --Child / !-- 使用子组件 Child --
/templatescript
// 导入子组件 Child
import Child from ./Child.vueexport default {// 注册子组件 Child使其在模板中可用components: {Child // 注册的组件名称与模板中使用的标签名称一致}
}
/script template!-- 模板部分 --h3Child/h3 !-- 显示“Child”标题 --p{{ message }}/p !-- 显示从祖先组件注入的消息 --
/templatescript
export default {// 使用 inject 选项来接收名为 message 的数据inject: [message]
}
/script provide/inject这是 Vue 提供的一种跨组件通信方式允许一个祖先组件向其所有子孙组件提供数据而不必通过每个中间组件逐级传递 props。 provide 和 inject 只能由上到下的传递不能反向传递 // 导入 Vue 的 createApp 函数
import { createApp } from vue
// 导入根组件 App
import App from ./App.vue// 创建一个 Vue 应用实例
const app createApp(App)// 使用 app.provide 提供全局数据
// 这里提供一个名为 golabData 的数据值是 我是全局数据
app.provide(golabData, 我是全局数据)// 将 Vue 应用挂载到 id 为 app 的 DOM 元素上
app.mount(#app) 使用 app.provide(golabData, 我是全局数据) 提供一个全局数据。这里 golabData 是一个键我是全局数据 是这个键对应的值。任何组件都可以通过 inject 选项访问这个全局数据。 27、Vue应用
vue从哪开始执行的
每个 Vue 应用都是通过 createApp函数创建一个新的 应用实例
// 从 vue 导入 createApp 函数用于创建 Vue 应用实例
import { createApp } from vue
// 导入根组件 App
import App from ./App.vue// 创建 Vue 应用实例
// 在一个 Vue 项目中通常只有一个 Vue 应用实例
const app createApp(App)// 将 Vue 应用挂载到页面中 id 为 app 的元素上
app.mount(#app)
我们传入 createApp 的对象实际上是一个组件每个应用都需要一个“根组件”其他组件将作为其子组件。
import { createApp } from vue
// 从一个单文件组件中导入根组件
import App from ./App.vueconst app createApp(App)应用实例必须在调用了 .mount() 方法后才会渲染出来。该方法接收一个“容器”参数可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串.页面挂载到index.html文件上的idapp元素上。
app.mount(#app)div idapp/div在src目录下的assets文件夹的作用就是存放公共资源例如图片、公共CSS或者字体图标等.