
小程序怎么推广_Vue.js中的组件体系
2021-01-07
vue.js既然是框架,那就不能只是简单的完成数据模板引擎的任务,它还提供了页面布局的功能。本文详细介绍使用vue.js进行页面布局的强大工具,vue.js组件系统。
Vue.js组件系统
每一个新技术的诞生,都是为了解决特定的问题。组件的出现就是为了解决页面布局等等一系列问题。vue中的组件分为两种,全局组件和局部组件。
组件的注册
全局组件的注册
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="app" !--第二步,使用-- ponent /ponent /div script // 第一步,注册 ponent("ponent", { template: ` div h2 Hello Vue /h2 /div }); new Vue({ el: "#app", }); /script /body /html
组件的参数
因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data 、 computed 、 watch 、 methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="app" !--第二步,使用-- ponent /ponent /div script // 第一步,注册 ponent("ponent", { data: function () { return { count: 0 } template: ` button v-on:click="count++" You clicked me {{ count }} times. /button ` }); new Vue({ el: "#app", }); /script /body /html
组件的复用
每个实例维护自己的一份独立的数据。
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="app" !--第二步,使用-- ponent /ponent ponent /ponent ponent /ponent /div script // 第一步,注册 ponent("ponent", { data: function () { return { count: 0 } template: ` button v-on:click="count++" You clicked me {{ count }} times. /button ` }); new Vue({ el: "#app", }); /script /body /html
注意当点击按钮时,每个组件都会各自独立维护它的 count 。因为你每用一次组件,就会有一个它的新 实例 被创建。
Data必须是一个函数
data必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝, 也可以写成如下形式
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="app" !--第二步,使用-- ponent /ponent ponent /ponent ponent /ponent /div script // 第一步,注册 ponent("ponent", { data(){ return { count: 0 } template: ` button v-on:click="count++" You clicked me {{ count }} times. /button ` }); new Vue({ el: "#app", }); /script /body /html
局部组件的注册
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
全局组件始终是存在的,除非程序结束,如果组件越来越大,那么程序所占用的空间和消耗的性能就会更大。
所以我们需要局部组件。不用的时候,被垃圾回收。
局部组件的第一种使用方式
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="component-demo" !--最后在根元素当中使用它-- !--第一个中使用方式,会把当前div渲染进DOM-- my-header /my-header /div script // 定义一个局部组件,其实就是一个变量,它是一个object类型 // 属性与全局组件是一样的 let Header = { template: ` button @click="count++" {{ count }} /button data() { return { count: 0 } }; new Vue({ el: "#component-demo", // 第二部,需要在根实例当中使用它 components: { 'my-header': Header }); /script /body /html
局部组件的第二种使用方式
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="component-demo" /div script // 定义一个局部组件,其实就是一个变量,它是一个object类型 // 属性与全局组件是一样的 let Header = { template: ` button @click="count++" {{ count }} /button data() { return { count: 0 } }; new Vue({ el: "#component-demo", // 第二种使用方式,不会将div渲染进DOM,以template为根元素 template: ` my-header /my-header `, // 第二步,需要在根实例当中使用它 components: { 'my-header': Header }); /script /body /html
在局部组件中使用子组件
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script style body { margin: 0; } .box { width: 100%; height: 50px; background-color: #2aabd2; /style /head body div id="component-demo" /div script // 定义一个局部组件,其实就是一个变量,它是一个object类型 // 这个对象的属性与全局组件是一样的(除el属性外) let Fcontent = { template: ` div span 这是头条 /span /div let Header = { template: ` div v-bind: button @click="count++" {{ count }} /button first-content /first-content /div data() { return { count: 0, isBox: true } components: { 'first-content': Fcontent }; new Vue({ el: "#component-demo", // 第二种使用方式,不会将div渲染进DOM,以template为根元素 template: ` my-header /my-header `, // 第二步,需要在根实例当中使用它 components: { 'my-header': Header }); /script /body /html
注:
1.注意写组件标签
2.每个组件的template只识别一个作用域块
通信
父子组件的通信
在父组件中给子组件绑定属性,子组件通过pro凡科抠图=["属性名称"]
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script style body { margin: 0; } .box { width: 100%; height: 50px; background-color: #2aabd2; /style /head body div id="component-demo" /div script // 定义一个局部组件,其实就是一个变量,它是一个object类型 // 属性与全局组件是一样的 let Fcontent = { template: ` div span 这是头条 /span {{ fdata }} /div pro凡科抠图: ['fdata'] let Header = { template: ` div v-bind: button @click="count++" {{ count }} /button first-content :fdata="fathData" /first-content /div data() { return { count: 0, isBox: true, fathData: "我是你爸爸~~~" } components: { 'first-content': Fcontent }; new Vue({ el: "#component-demo", // 第二种使用方式,不会将div渲染进DOM,以template为根元素 template: ` my-header /my-header `, // 第二步,需要在根实例当中使用它 components: { 'my-header': Header }); /script /body /html
子父组件的通信
父组件在mounted的时候,监听一个自定义事件。
给子组件绑定一个click事件之后,通过内建的方法$emit在父组件上触发一个事件,这个时间就是父组件监听的自定义事件。
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script style body { margin: 0; } .box { width: 100%; height: 50px; background-color: #2aabd2; /style /head body div id="component-demo" /div script // 定义一个局部组件,其实就是一个变量,它是一个object类型 // 属性与全局组件是一样的 let Fcontent = { template: ` div button v-on:click="myClick" 放大父组件字体 /button /div methods: { myClick: function () { console.log(this); this.$emit('change-font', 0.1); console.log(this); let Header = { template: ` div v-bind: first-content v-on:change-font="changeFont" /first-content span :style="{ fontSize: postFontSize + 'em' }" Hello Vue /span /div data() { return { count: 0, isBox: true, fathData: "我是你爸爸~~~", postFontSize: 1 } components: { 'first-content': Fcontent methods: { changeFont: function (value) { this.postFontSize += value; const VM = new Vue({ el: "#component-demo", // 第二种使用方式,不会将div渲染进DOM,以template为根元素 template: ` my-header /my-header `, // 第二步,需要在根实例当中使用它 components: { 'my-header': Header }); /script /body /html
非父子通信
其中一个组件向中间调度器提交事件,另一个组件监听中间调度器的事件
混入
混入可以提高代码的重用性。
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.js" /script /head body div id="mixin-demo" my-alex /my-alex p /p my-peiqi /my-peiqi /div script let mixs = { methods: { show: function (name) { console.log(`${name} is here!`); hide: function (name) { console.log(`${name} is gone!`); let myAlex = { template: ` div button @click="show('alex')" 点我显示alex /button button @click="hide('alex')" 点我隐藏alex /button /div mixins: [mixs], let myPeiqi = { template: ` div button @mouseenter="show('peiqi')" 鼠标移入显示沛齐 /button button @mouseleave="hide('peiqi')" 鼠标离开隐藏沛齐 /button /div mixins: [mixs], }; new Vue({ el: "#mixin-demo", components: { "my-alex": myAlex, "my-peiqi": myPeiqi, }) /script /body /html
插槽
有时候我们需要向组件传递一些数据,这时候可以使用插槽.
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title style .nav-link { width: 100px; height: 100px; background-color: #2aabd2; float: left; margin-left: 5px; text-align: center; line-height: 100px; /style script src="../statics/vue.js" /script /head body div id="app01" com-content 登录 /com-content com-content 注册 /com-content com-content 最热 /com-content com-content 段子 /com-content com-content 42区 /com-content com-content 图片 /com-content /div ponent('com-content', { template: ` div slot /slot /div }); new Vue({ el: "#app01", }) /script /body /html
具名插槽
操作使用了组件的复用,如果我们在同一个组件内写入不同的页面呢?此时,我们需要多个插槽,并且给不同的内容命名。
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title style .nav-link { width: 100px; height: 100px; background-color: #2aabd2; float: left; margin-left: 5px; text-align: center; line-height: 100px; /style script src="../statics/vue.js" /script /head body div id="app01" base-layout template slot="header" h1 这是标题栏 /h1 /template template h2 这是内容 /h2 /template template slot="footer" h3 这是页脚 /h3 /template /base-layout /div script let baseLayout = { template: ` div header slot name="header" /slot /header main slot /slot /main footer slot name="footer" /slot /footer /div }; new Vue({ el: "#app01", components: { "base-layout": baseLayout }) /script /body /html
我们还是可以保留一个未命名插槽,这个插槽是 默认插槽 ,也就是说它会作为所有未匹配到插槽的内容的统一出口。
在组件上使用v-model
自定义事件也可以用于创建支持 v-model 的自定义输入组件。记住:
input v-model="searchText"
等价于:
input v-bind:value="searchText" v-on:input="searchText = $event.target.value"
当用在组件上时, v-model 则会这样:
custom-input v-bind:value="searchText" v-on:input="searchText = $event" /custom-input
为了让它正常工作,这个组件内的 input 必须:
将其 value 特性绑定到一个名叫 value 的 prop 上
在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
写成代码之后是这样的:
ponent('custom-input', { pro凡科抠图: ['value'], template: ` input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" })
现在 v-model 就应该可以在这个组件上完美地工作起来了:
custom-input v-model="searchText" /custom-input
如下是在组件中使用v-model示例:
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script /head body div id="app" /div script let Model = { template: ` div input v-bind:value="value" v-on:input="$emit('input', $event.target.value)" h1 {{ value }} /h1 pro凡科抠图: ['value'] let App = { template: ` div custom-input v-model="searchText" /custom-input components: { 'custom-input': Model, data(){ return { searchText: "", }; new Vue({ el: "#app", template: ` App /App `, components: { App, }) /script /body /html
使用组件的注意事项
注意事项一:单个根元素
当构建一个内容页面的组件时,我们的组件可能包含多个HTML标签。
h1 Hello World /h1 h2 Hello Vue /h2
然而如果你在模板中尝试这样写,Vue 会显示一个错误,ponent must have a single root element (每个组件必须只有一个根元素) 。你可以将模板的内容包裹在一个父元素内,来修复这个问题,例如:
div h1 Hello World /h1 h2 Hello Vue /h2 /div
注意事项二:解析特殊HTML元素
有些 HTML 元素,诸如 ul 、 ol 、 table 和 select ,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 li 、 tr 和 option ,只能出现在其它某些特定的元素内部。
这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:
table blog-post-row /blog-post-row /table
这个自定义组件 blog-post-row 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:
table tr is="blog-post-row" /tr /table
需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:
字符串 (例如:template: '...')
单文件组件 (.vue) script type="text/x-template"
使用组件实现路飞导航栏
!DOCTYPE html html lang="en" head meta charset="UTF-8" title Title /title script src="../statics/vue.min.js" /script !-- 引入样式 -- link rel="stylesheet" href="element-ui/lib/theme-chalk/index.css" !-- 引入组件库 -- script src="element-ui/lib/index.js" /script style body { margin: 0; padding: 0; } .header { position: fixed; top: 0; left: 0; width: 100%; } .el-menu { display: flex; align-items: center; justify-content: center; } .footer { position: fixed; bottom: 0; left: 0; width: 100%; } .header img { position: absolute; left: 80px; top: -4px; width: 118px; height: 70px; z-index: 999; /style /head body div id="app" /div template id="header" div img src="static/img/head-logo.a7cedf3.svg"/ el-menu :default-active="activeIndex" mode="horizontal" el-menu-item index="1" 首页 /el-menu-item el-menu-item index="2" 免费课程 /el-menu-item el-menu-item index="3" 轻课 /el-menu-item el-menu-item index="4" 学位课程 /el-menu-item el-menu-item index="5" 智能题库 /el-menu-item el-menu-item index="6" 公开课 /el-menu-item el-menu-item index="7" 内部教材 /el-menu-item el-menu-item index="8" 老男孩教育 /el-menu-item /el-menu /div /template template id="footer" div el-menu mode="horizontal" background-color="black" el-menu-item index="1" 关于我们 /el-menu-item el-menu-item index="2" 联系我们 /el-menu-item el-menu-item index="3" 商业合作 /el-menu-item el-menu-item index="4" 帮助中心 /el-menu-item el-menu-item index="5" 意见反馈 /el-menu-item el-menu-item index="6" 新手指南 /el-menu-item /el-menu /div /template script let pageHeader = { template: "#header", data() { return { activeIndex: "1", let pageFooter = { template: "#footer", let App = { template: ` div div page-header /page-header /div div page-footer /page-footer /div /div components: { 'page-header': pageHeader, 'page-footer': pageFooter, }; new Vue({ el: "#app", template: ` app /app `, components: { 'app': App, }) /script /body /html
效果图:
总结
以上所述是小编给大家介绍的Vue.js中的组件系统,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对凡科网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
扫描二维码分享到微信