Vue.js的组件化思想--上
一、Vue中的组件
Vue视图层的灵魂 — 组件化
组件(Component)是 Vue.js 最强大的功能之一;
组件可以扩展 HTML 元素,封装可重用的代码;
在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
二、全局组件的创建和注册
全局组件-步骤:1.创建组件Vue.extend(),指定组件的名称--2.注册组件Vue.component()--3.挂载作用域下实例化
案例代码:
<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>全局组件</title></head><body><div id="app"> ???<my-date></my-date> ???????<my-date></my-date> ???</div><hr><div id="app1"> ???<my-date></my-date> ???????<my-date></my-date> ???</div><script_top src="js/vue.js"></script_top><script_top>// 全局组件-步骤:1.创建组件Vue.extend(),指定组件的名称--2.注册组件Vue.component()--3.挂载作用域下实例化 ???// 1.创建组件 ???let Profile = Vue.extend({ ???????template:` ???????????<div> ???????????????<input ???type=‘date‘> ???????????????<p>今天已经是夏天了</p> ???????????</div>` ???}); ???// 2.注册组件,指定组件的名称 ???Vue.component(‘my-date‘,Profile); ???// 3.挂载作用域下实例化 ???new Vue({ ???????el:‘#app‘, ???????data:{ ???????} ???}); ???new Vue({ ???????el:‘#app1‘, ???????data:{ ???????} ???})</script_top></body></html>
运行结果:
调用Vue.extend()创建的是一个组件构造器,构造器有一个选项对象,选项对象的template属性用于定义组件要渲染的HTML;
调用Vue.component()注册组件时,需要提供2个参数:组件的标签名 和 组件构造器;注册的组件要挂载到某个Vue实例下,否则它不会生效;
Vue.extend() 和 Vue.component():由于 Vue 本身是一个构造函数,Vue.extend() 是一个类继承方法,它用来创建一个 Vue 的子类并返回其构造函数;
而Vue.component() 的作用在于:建立指定的构造函数与 ID 字符串间的关系,从而让 Vue.js 能在模板中使用它;直接向 Vue.component() 传递 options 时,它会在内部调用 Vue.extend()。
三、局部组件的创建和注册
案例代码:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div id="app"> ???<my_date></my_date> ???<my_color></my_color></div><script_top src="js/vue.js"></script_top><script_top>// 1.创建组件let Profile = Vue.extend({template:`<div><inputtype=‘date‘><p>今天已经是夏天了</p></div>`});// 可以拥有多个局部组件let Profile2 = Vue.extend({template:`<div><inputtype=‘color‘><p我是一个色板</p></div>`});new Vue({el:‘#app‘,// 2.注册组件,指定组件的名称.// 注意:局部组件一定要加scomponents:{‘my_date‘:Profile,‘my_color‘:Profile2}})</script_top></body></html>
运行结果:
局部组件只能在局部作用域调用:否则会报错!
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>局部组件只能在局部作用域调用</title></head><body><div id="app"> ???<my_date></my_date> ???<my_color></my_color></div><hr><div id="app1"> ???<my_date></my_date> ???<my_color></my_color></div><script_top src="js/vue.js"></script_top><script_top>// 1.创建组件let Profile = Vue.extend({template:`<div><inputtype=‘date‘><p>今天已经是夏天了</p></div>`});// 可以拥有多个局部组件let Profile2 = Vue.extend({template:`<div><inputtype=‘color‘><p我是一个色板</p></div>`});new Vue({el:‘#app‘,// 2.注册组件,指定组件的名称.// 注意:局部组件一定要加scomponents:{‘my_date‘:Profile,‘my_color‘:Profile2}})// 局部组件只能在局部作用域调用new Vue({el:‘#app1‘})</script_top></body></html>
运行结果:
四、另一种组件创建和注册方式
直接通过Vue.component注册或获取全局组件,主要体现在以下几种方式:
// 注册组件,传入一个扩展过的构造器
Vue.component(‘my-component‘, Vue.extend({ /* ... */ }))
// 注册组件,传入一个选项对象(自动调用 Vue.extend)
Vue.component(‘my-component‘, { /* ... */ })
// 获取注册的组件(始终返回构造器)
var MyComponent = Vue.component(‘my-component‘)
4.1 自定义全局组件
第二种写法。(第一步、第二步写在一起。)
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>全局组件</title></head><body><div id="app"> ???<my-date></my-date> ???<my-date></my-date></div><hr><div id="app1"> ???<my-date></my-date> ???<my-date></my-date></div><script_top src="js/vue.js"></script_top><script_top>// 全局组件-步骤:1.创建组件Vue.extend(),指定组件的名称--2.注册组件Vue.component()--3.挂载作用域下实例化// 1.创建组件// 2.注册组件,指定组件的名称Vue.component(‘my-date‘,{// 模板选项template:`<div><inputtype=‘date‘><p>今天已经是夏天了</p></div>`});new Vue({el:‘#app‘,data:{}});new Vue({el:‘#app1‘,data:{}})</script_top></body></html>
4.2 自定义局部组件
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>局部组件写法2</title></head><body><div id="app"> ???<my_date></my_date> ???<my_color></my_color></div><hr><div id="app1"> ???<my_date></my_date> ???<my_color></my_color></div><script_top src="js/vue.js"></script_top><script_top>new Vue({el:‘#app‘,// 2.注册组件,指定组件的名称.// 注意:局部组件一定要加scomponents:{‘my_date‘:{template:`<div><inputtype=‘date‘><p>今天已经是夏天了</p></div>`},‘my_color‘:{template:`<div><inputtype=‘color‘><p我是一个色板</p></div>`}}})</script_top></body></html>
五、父子组件
组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B 。
最简单的父子组件:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div id="app"> ???<parent></parent> ???<child></child></div><script_top src="js/vue.js"></script_top><script_top>// 1.子组件构造器let Child1 = Vue.extend({template:`<img src="./img/1.jpg" width="200" />`,});let Child2 = Vue.extend({template:`<p>我是美女哦!</p>`,});// 全局组件componentVue.component(‘child‘,Child1);// 2.父组件构造器 ?Vue.component(‘parent‘,{//局部组件componentscomponents:{‘my_child1‘:Child1,‘my_child2‘:Child2},template:`<div><my_child1></my_child1><my_child2></my_child2></div>`});new Vue({el:‘#app‘,})</script_top></body></html>
运行结果:
在父子组件组合使用中要注意以下一些问题:
1.没有实例化的子组件不能拿出来单独使用!
2.在父标签内部嵌套子标签!
???????因为在父标签一旦生成真实的DOM,其内部的子标签就会被解析成为普通的HTML标签来执行,而且<child-component>不是标准的HTML标签,会被浏览器过滤掉。
六、在组件上绑定Class和Style
数据绑定一个常见需求是操作元素的 class 列表和它的内联样式。因为它们都是属性 ,我们可以用v-bind 处理它们:只需要计算出表达式最终的字符串。
而且,把 v-bind 用于 class 和 style 时,表达式的结果类型除了字符串之外,还可以是对象或数组。
案例代码:
七、template和script_top标签
尽管在上面组件的组件注册的方式已经很简单,但是在template选项中拼接HTML的标签还是不符合常规的编程习惯,而且HTML元素和js代码混杂在一起造成了很大的耦合性。
那么,template和script_top标签可以帮助我们将定义在JS中的HTML模板分离出来。
注意: 两种注册方式效果一样,官方建议用第一种。
(1)使用template标签注册组件:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div id="app"> ???<my-div></my-div></div><hr> <template id="my_div"><div>我是贝贝</div></template><script_top src="js/vue.js"></script_top><script_top>// 1.实例化组件 ?全局组件componentVue.component(‘my-div‘,{template:‘#my_div‘})new Vue({el:‘#app‘,})</script_top></body></html>
运行结果:
注意:必须只有一个出口文件,否则会报错!
(2)使用script_top标签注册组件:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div id="app"> ???<my-div></my-div></div><script_top type="text/template" id="my_div"><!-- 注意必须只有一个出口文件,否则会报错 --><div><img src="./img/1.jpg" width="200"><div>我是美女哦!</div></div></script_top><script_top src="js/vue.js"></script_top><script_top>// 1.实例化组件 ?全局组件componentVue.component(‘my-div‘,{template:‘#my_div‘});new Vue({el:‘#app‘,})</script_top></body></html>
注意:使用<script_top>标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略<script_top>标签内定义的内容。
八、挂载选项data必须是函数
使用组件时,大多数可以传入到 Vue 构造器中的选项可以在 Vue.extend() 或Vue.component()中注册组件时使用,但有一个重要前提: data 必须是函数。
下面代码会出现的问题:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div id="app"> ???<my-div></my-div></div><script_top type="text/template" id="my_div"><!-- 注意必须只有一个出口文件,否则会报错 --><div><img src="./img/1.jpg" width="200"><p>我是美女哦!</p><p>{{message}}</p></div></script_top><script_top src="js/vue.js"></script_top><script_top>// 1.实例化组件 ?全局组件componentVue.component(‘my-div‘,{template:‘#my_div‘,data:{message:‘我的贝贝‘}});new Vue({el:‘#app‘,})</script_top></body></html>
正确的写法:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><div id="app"> ???<my-div></my-div></div><script_top type="text/template" id="my_div"><!-- 注意必须只有一个出口文件,否则会报错 --><div><img src="./img/1.jpg" width="200"><p>我是美女哦!</p><p>{{message}}</p></div></script_top><script_top src="js/vue.js"></script_top><script_top>// 1.实例化组件 ?全局组件componentVue.component(‘my-div‘,{template:‘#my_div‘,/*data:{message:‘我的贝贝‘}*/// 挂载组件data必须是个函数。data(){return {message:‘我的贝贝‘}}});new Vue({el:‘#app‘,})</script_top></body></html>
运行结果:
注意:如果data选项指向某个对象,这意味着所有的组件实例共用一个data。
我们应当使用一个函数作为 data 选项,让这个函数返回一个新对象。
运行结果:这三个组件共享了同一个 data , 因此增加一个 counter 会影响所有组件!
解决办法:为每个组件返回新的 data 对象来解决这个问题!
data: function () {
return {
counter: 0
}
}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>验证data必须是函数</title></head><body><div id="app"><!-- data必须是函数:内容不会共享,每次都是独立的。 --> ???<my-btn></my-btn> ???<my-btn></my-btn> ???<my-btn></my-btn> ???<my-btn></my-btn></div><template id="my_btn"><!-- v-on @ --><button @click="counter+=1">点击次数:{{counter}}</button></template><script_top src="js/vue.js"></script_top><script_top>// 1.实例化组件Vue.component(‘my-btn‘,{template:‘#my_btn‘,data(){return {counter:0}}});new Vue({el:‘#app‘})</script_top></body></html>
运行结果:
Vue.js的组件化思想--上
原文地址:https://www.cnblogs.com/yimiflh/p/9280618.html
知识推荐
- POJ - 1258 Agri-Net (最小生成树)
- php自动加载类文件探讨,spl_autoload_register自动加载原理
- PHP之Trait特性
- CI框架中,判断post,ajax,get请求的方法
- PHP中new self()和new static()的区别探究
- hibernate
- Error-MVC: 未能找到路径“D:DsWebDS.Webdistbinroslyncsc.exe”的一部分。
- 正则表达式-将字符串替换成json格式
- Gson与FastJson比较
- JS浏览器的三种弹框:
- 单点登录在asp.net中的简单实现
- Net Core中使用Newtonsoft.Json进行序列化保持原有大小写
- Flume原理解析【转】
- php 时间函数
- 使用 HAProxy + Nginx 搭建 Web 群集
- AJAX
- PHP面试(三):面试技巧
- ASP.NET Core 配置跨域(CORS)