Vue.js 组件化开发
三、组件化开发
- 1.1 组件化的实现和使用步骤
- 组件注册步骤解析
- 1.2 全局组件和局部组件
- 1.3 父组件和子组件
- 1.4 注册组件语法糖
- 1.5 组件模板抽离的写法
- 1.6 组件数据存放
- 1.7 父子组件通信
- 父组件向子组件传递数据
- 子组件向父组件传递数据
- 1.8 组件访问
- 父组件访问子组件
- children
- refs
- 子组件访问父组件
- 1.9 插槽
- slot
- 具名插槽
- 作用域插槽
人面对复杂问题的处理方式:
- 任何一个人处理信息的逻辑能力都是有限的
- 所以,当面对一个非常复杂的问题时,我们不太可能—次性搞定一大堆的内容。
- 但是,我们人有一种天生的能力,就是将问题进行拆解。如果将一个复杂的问题,拆分成很多个可以处理的小问题,再将其放在整体当中,你会发现大的问题也会迎刃而解。
组件化也是类似的思想:
- 如果我们将一个页面中所有的处理逻辑全部放在一起,处理起来就会变得非常复杂,而且不利于后续的管理以及扩展。
- 但如果,我们讲一个页面拆分成一个个小的功能块,每个功能块完成属于自己这部分独立的功能,那么之后整个页面的管理和维护就变得非常容易了。
组件化是Vue.js
中的重要思想:
- 它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。
- 任何的应用都会被抽象成一颗组件树。
组件化思想的应用:
- 有了组件化的思想,我们在之后的开发中就要充分的利用它。
- 尽可能的将页面拆分成一个个小的、可复用的组件。
- 这样让我们的代码更加方便组织和管理,并且扩展性也更强。
1.1 组件化的实现和使用步骤
组件的使用分成三个步骤:
- 创建组件构造器
- 注册组件
- 使用组件
<!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>
</head>
<body><div id="app"><!-- 3、使用组件 --><my-cpn></my-cpn><my-cpn></my-cpn></div><script src="../js/vue.js"></script><script>// 1、创建组件构造器const cpnC = Vue.extend({template: `<div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p><p>我是内容,呵呵呵呵</p></div>`,});// 2、注册组件Vue.component('my-cpn', cpnC);const app = new Vue({el: '#app', data: { }})</script>
</body>
</html>
组件注册步骤解析
Vue.extend()
:- 调用
Vue.extend()
创建的是一个组件构造器。 - 通常在创建组件构造器时,传入
template
代表我们自定义组件的模板。该模板就是在使用到组件的地方,要显示的HTML
代码。 - 事实上,这种写法在
Vue2.x
的文档中几乎已经看不到了,它会直接使用下面我们会讲到的语法糖,但是在很多资料还是会提到这种方式,而且这种方式是学习后面方式的基础。
- 调用
Vue.component()
:- 调用
Vue.component()
是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。 - 所以需要传递两个参数:
1、
注册组件的标签名,2、
组件构造器
- 调用
组件必须挂在在某个
Vue
实例下,否则它不会生效- 下面的实例中,我们使用了三次
<my-cpn></my-spn>
- 但是第三次并没有生效
- 下面的实例中,我们使用了三次
1.2 全局组件和局部组件
- 全局组件:在注册之后可以用在任何新创建的
Vue
根实例 (new Vue
) 的模板中。 - 局部组件:局部组件只有在所注册的
Vue
实例中才能使用,并不能在其他未进行注册的Vue
实例中使用。
<!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>
</head>
<body><div id="app"><!-- 3、使用组件 --><my-cpn></my-cpn><cpn></cpn></div><hr><div id="app2"><my-cpn></my-cpn><cpn></cpn></div><script src="../js/vue.js"></script><script>// 1、创建组件构造器const cpnC = Vue.extend({template: `<div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p><p>我是内容,呵呵呵呵</p></div>`,});// 2、注册组件(全局组件,意味着可以在多个 Vue 实例下面使用)Vue.component('my-cpn', cpnC);const app = new Vue({el: '#app', data: { },// 局部组件components: {cpn: cpnC}})const app2 = new Vue({el: '#app2', data: { }})</script>
</body>
</html>
在上面的代码中,我们创建了两个Vue
实例对象app
和app2
,同时我们使用注册了全局组件my-cpn
以及在app
内注册了局部组件cpn
。我们在app
和app2
中使用上面的两个组件,可以看到局部组件cpn
并没有在app2
中生效,符合我们的预期。
1.3 父组件和子组件
在前面我们看到了组件树:
- 组件和组件之间存在层级关系
- 而其中一种非常重要的关系就是父子组件的关系
我们来通过代码看这种层级关系:
<!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>
</head>
<body><div id="app"><cpn2></cpn2></div><script src="../js/vue.js"></script><script>// 1、创建第一个组件构造器(子组件)const cpnC1 = Vue.extend({template: `<div><h2>我是标题1</h2><p>我是内容,哈哈哈哈</p></div>`,});// 2、创建第二个组件构造器(父组件)const cpnC2 = Vue.extend({template: `<div><h2>我是标题2</h2><p>我是内容,呵呵呵呵</p><cpn1></cpn1></div>`,components: {cpn1: cpnC1,},});const app = new Vue({el: '#app', data: { },components: {cpn2: cpnC2,}})</script>
</body>
</html>
1.4 注册组件语法糖
通过语法糖的方式,我们可以跳过Vue.extend()
方法,直接通过Vue.component()
方法实现组件的注册。
<!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>
</head>
<body><div id="app"><!-- 3、使用组件 --><cpn1></cpn1><cpn2></cpn2></div><script src="../js/vue.js"></script><script>// 1、全局组件注册语法糖// 1.1 创建组件构造器// const cpn1 = Vue.extend({// template: `// <div>// <h2>我是标题</h2>// <p>我是内容,哈哈哈哈</p>// <p>我是内容,呵呵呵呵</p>// </div>`,// });// 1.2 注册组件// Vue.component('cpn1', cpn1);Vue.component('cpn1', {template: `<div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p><p>我是内容,呵呵呵呵</p></div>`,});const app = new Vue({el: '#app', data: { },components: {cpn2: {template: `<div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p><p>我是内容,呵呵呵呵</p></div>`,}}})</script>
</body>
</html>
1.5 组件模板抽离的写法
在IDE
中,写组件的template
时,由于其是一个字符串,所以没有代码提示,写起来非常不方便。并且template
的代码直接耦合在Vue
的代码中,非常的凌乱。为此,我们可以将组件的模板抽离出来,有两种抽离的方式。
<!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>
</head>
<body><div id="app"><cpn1></cpn1><hr><cpn2></cpn2></div><!-- 1、第一种写法 --><script type="text/x-template" id="cpn"><div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p></div></script><!-- 2、第二种写法 --><template id="cpn2"><div><h2>我是标题</h2><p>我是内容,哈哈哈哈</p></div></template><script src="../js/vue.js"></script><script>Vue.component('cpn1', {template: '#cpn',});Vue.component('cpn2', {template: '#cpn2',});const app = new Vue({el: '#app', data: { },})</script>
</body>
</html>
通常,我们采用的是方式二。可以看到,组件模板抽离后的代码看起来非常简洁。
1.6 组件数据存放
组件是一个单独功能模块的封装:
这个模块有自己的 HTML 模板,也应该有属于自己的数据data
组件中的数据是保存在哪里呢?顶层的Vue
实例中吗?
我们可以通过下面的代码测试,组件中能不能直接访问Vue
实例中的data
<!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>
</head>
<body><div id="app"><cpn></cpn></div><template id="a"><div><h2>{{ message}}</h2></div></template><script src="../js/vue.js"></script><script>Vue.component('cpn', {template: '#a',});const app = new Vue({el: '#app', data: {message: 'Hello'},})</script>
</body>
</html>
我们发现并不能访问,而且即使可以访问,如果将所有的数据都放在Vue
实例中,Vue
实例会变的非常臃肿。
结论:Vue 组件应该有自己保存数据地方。
组件自己的数据存放在哪里呢?
- 组件对象也有一个
data
属性(也可以有methods
属性) - 只是这个
data
属性必须是一个函数 - 而且这个函数返回一个对象,对象内部保存着数据
<!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>
</head>
<body><div id="app"><cpn></cpn></div><template id="a"><div><h2>{{ title }}</h2><p>我是内容,哈哈哈哈</p></div></template><script src="../js/vue.js"></script><script>Vue.component('cpn', {template: '#a',data() {return {title: 'Hello'}}});const app = new Vue({el: '#app', data: { },})</script>
</body>
</html>
1.7 父子组件通信
子组件是不能引用父组件或者Vue
实例的数据的。
但是,在开发中,往往一些数据确实需要从上层产地到下层:
- 比如在一个页面中,我们从服务器请求到了很多的数据
- 其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示
- 这个时候,并不会让子组件再次发送要给网络请求,而是直接让大组件(父组件)将数据传递给小组件(子组件)。
如果进行父子组件间的通信呢?官方提到
- 通过
props
向子组件传递数据 - 通过事件向父组件发送消息
Vue
实例同样是组件,所以Vue
实例与子组件通信和父组件与子组件通信的过程是一样的。
父组件向子组件传递数据
在子组件中,使用选项props
来声明需要从父组件接收到的数据。
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>
</head>
<body><div id="app"><cpn :cmovies="movies" :cmessage="message"></cpn><!-- 如果要传递的是 data 属性,则必须用 v-bind --><cpn cmovies="movies" cmessage="message"></cpn></div><template id="a"><div>{{cmessage}}<ul><li v-for="movie in cmovies">{{movie}}</li></ul></div></template><script src="../js/vue.js"></script><script>const cpn = {template: '#a',props: ['cmovies', 'cmessage'],}const app = new Vue({el: '#app', data: {message: 'Hello',movies: ['a', 'b', 'c', 'd'] },components: {cpn}})</script>
</body>
</html>
在上面,我们的props
选项是使用一个数组。
我们说过,处理数组之外,我们也可以使用对象,当需要对props
进行类型等验证时,就需要对象写法了。
验证都支持如下数据类型:
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
<!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>
</head>
<body><div id="app"><cpn :cmovies="movies" ></cpn><!-- 错误语法:必须用 v-bind --><!-- <cpn cmovies="movies" cmessage="message"></cpn> --></div><template id="a"><div>{{cmessage}}<ul><li v-for="movie in cmovies">{{movie}}</li></ul></div></template><script src="../js/vue.js"></script><script>const cpn = {template: '#a',// props: ['cmovies', 'cmessage'],props: {// 1、类型检查// cmovies: Array,// cmessage: String// 2、提供一些默认值cmessage: {type: String,default: 'aaaa',required: false},cmovies: {type: Array,}}}const app = new Vue({el: '#app', data: {message: 'Hello',movies: ['a', 'b', 'c', 'd'] },components: {cpn}})</script>
</body>
</html>
子组件向父组件传递数据
props
用于父组件向子组件传递数据,还有一种比较常见的是子组件传递数据或事件到父组件中。
我们应该如何处理呢?这个时候,我们需要使用自定义事件来完成。
什么时候需要自定义事件呢?
- 当子组件需要向父组件传递数据时,就要用到自定义事件了。
- 我们之前学习的
v-on
不仅仅可以用于监听DOM
事件,也可以用于组件间的自定义事件。
自定义事件的流程︰
- 在子组件中,通过
$emit('事件名', [参数])
来触发事件。 - 在父组件中,通过
v-on
来监听子组件事件。
<!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>
</head>
<body><!-- 父组件模板 --><div id="app"><cpn v-on:itemclick="cpnClick"></cpn></div><!-- 子组件模板 --><template id="a"><div><button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button></div></template><script src="../js/vue.js"></script><script>const cpn = {template: '#a',data() {return {categories: [{id: 1, name: '热门推荐'},{id: 2, name: '手机数码'},{id: 3, name: '家用家电'},{id: 4, name: '电脑办公'},]}},methods: {btnClick(item) {// 产生事件:自定义事件this.$emit('itemclick', item);}}}const app = new Vue({el: '#app', data: {},components: {cpn},methods: {cpnClick(item) {console.log(item)}}})</script>
</body>
</html>
上面代码的含义如下:
- 父组件监听
itemclick
事件,该事件产生时,执行cpnClick
方法 - 点击子组件内部的按钮时,执行
btnClick
方法 btnClick
方法内部,产生itemclick
事件- 由此便完成了子组件向父组件的数据传递
1.8 组件访问
有时候,我们需要父组件直接访问子组件,子组件直接访问父组件,或者是子组件访问根组件。
- 父组件访问子组件:使用
$children
或$refs
- 子组件访问父组件:使用
$parent
父组件访问子组件
children
this.$children
是一个数组类型,它包含所有子组件对象
<!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>
</head>
<body><div id="app"><cpn></cpn><button @click="btnClick">点击</button></div><template id="cpn"><div><h2>我是子组件</h2></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {},methods: {btnClick() {console.log(this.$children);this.$children[0].showMessage();}},components: { cpn: {template: '#cpn',methods: {showMessage() {console.log("showMessage")}}}},})</script>
</body>
</html>
可以看到,我们通过this.$children
成功访问了cpn
组件,并且调用了cpn
所拥有的methods
。当然也可以访问cpn
的其他属性。
refs
通过this.$children
存在这样一个问题,便是我们要访问一个组件时,可能并不知道其索引,需要进行遍历查找。
而this.$refs
的作用相当于给组件一个id
,这样我们便能根据这个id
直接找到对应的组件了。
<!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>
</head>
<body><div id="app"><cpn ref="aaa"></cpn><button @click="btnClick">点击</button></div><template id="cpn"><div><h2>我是子组件</h2></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {},methods: {btnClick() {console.log(this.$refs);console.log(this.$refs.aaa);this.$refs.aaa.showMessage();}},components: { cpn: {template: '#cpn',methods: {showMessage() {console.log("showMessage")}}}},})</script>
</body>
</html>
子组件访问父组件
this.$parent
获得父组件this.$root
获得根组件
<!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>
</head>
<body><div id="app"><cpn></cpn></div><template id="cpn"><div><h2>我是子组件</h2><button @click="btnClick">点击</button></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {},methods: {showMessage() {console.log("showMessage")}},components: { cpn: {template: '#cpn',methods: {btnClick() {console.log(this.$parent);this.$parent.showMessage();// 访问根组件console.log(this.$root);}}}},})</script>
</body>
</html>
1.9 插槽
slot
翻译为插槽:
- 在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽。口插槽的目的是让我们原来的设备具备更多的扩展性。
- 比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等。
组件的插槽︰
- 组件的插槽也是为了让我们封装的组件更加具有扩展性。
- 让使用者可以决定组件内部的一些内容到底展示什么。
例子∶移动网站中的导航栏。
- 移动开发中,几乎每个页面都有导航栏。
- 导航栏我们必然会封装成一个插件,比如
nav-bar
组件。一旦有了这个组件,我们就可以在多个页面中复用了。
如何去封装这类的组件呢?
- 它们也很多区别,但是也有很多共性。
- 如果,我们每一个单独去封装一个组件,显然不合适∶比如每个页面都返回,这部分内容我们就要重复去封装。
- 但是,如果我们封装成一个,好像也不合理∶有些左侧是菜单,有些是返回,有些中间是搜索,有些是文字,等等。
如何封装合适呢?抽取共性,保留不同。
- 最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽。
- 一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容。
- 是搜索框,还是文字,还是菜单。由调用者自己来决定。
这就是为什么我们要学习组件中的插槽slot
的原因。
slot
<!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>
</head>
<body><!-- 1、插槽的基本使用 <slot></slot>2、插槽的默认值 <slot>button</slot>3、如果有多个值,同时放入到组件进行替换时,一起作为替换元素--><div id="app"><cpn><button>按钮</button></cpn><cpn><div>哈哈哈</div></cpn><cpn><a href="">百度</a></cpn><cpn></cpn></div><template id="cpn"><div><h2>我是组件</h2><div>我是组件,哈哈哈</div><slot></slot><!-- 可以给 slot 默认值,如果父组件没有插入,则使用默认值 --><!-- <slot><button>按钮</button></slot> --></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {},components: {cpn: {template: '#cpn',}}})</script>
</body>
</html>
在上面的代码中,我们在组件中使用<slot></slot>
创建插槽,当我们使用该组件时,组件标签内的内容会自动替换掉<slot></slot>
。
具名插槽
当子组件的功能复杂时,子组件的插槽可能并非是一个。
- 比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边。
- 那么,外面在给插槽插入内容时,如何区分插入的是哪—个呢?
- 这个时候,我们就需要给插槽起一个名字
如何使用具名插槽呢?
- 非常简单,只要给
slot
元素一个name
属性即可<slot name='myslot'> </slot>
我们来给出一个案例︰
- 这里我们先不对导航组件做非常复杂的封装,先了解具名插槽的用法。
<!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>
</head>
<body><div id="app"><cpn><span slot="center">标题</span></cpn></div><template id="cpn"><div><slot name="left"><span>左边</span></slot><slot name="center"><span>中间</span></slot><slot name="right"><span>右边</span></slot></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {},components: {cpn: {template: '#cpn',}}})</script>
</body>
</html>
在上面的代码中,我们在组件中创建了三个具名插槽,分别为left
、center
、right
.
我们使用该组件时,通过slot="center"
指定要将内容插入到center
的插槽。
作用域插槽
在了解作用域插槽之前,我们需要西安了解一个概念:编译作用域。
官方对于编译的作用域解析比较简单,我们自己来通过一个例子来理解这个概念:
我们来考虑下面的代码是否最终是可以渲染出来的︰
<my-cpn v-show="isShow"></my-cpn>
中,我们使用了isShow
属性。isShow
属性包含在组件中,也包含在Vue
实例中。
答案︰最终可以渲染出来,也就是使用的是Vue
实例的属性。
为什么呢?
- 官方给出了一条准则∶父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
- 而我们在使用
<my-cpn v-show="isShow"></my-cpn>
的时候,整个组件的使用过程是相当于在父组件中出现的。 - 那么他的作用域就是父组件,使用的属性也是属于父组件的属性。
- 因此,
isShow
使用的是Vue
实例中的属性,而不是子组件的属性。
<!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>
</head>
<body><div id="app"><cpn v-show="isShow"></cpn></div><template id="cpn"><div><h2>我是组件</h2><div>我是组件,哈哈哈</div><button v-show="isShow">按钮</button></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {isShow: true},components: {cpn: {template: '#cpn',data() {return {isShow: false}}}}})</script>
</body>
</html>
作用域插槽是slot
—个比较难理解的点,而且官方文档说的又有点不清晰。
这里,我们用一句话对其做一个总结,然后我们在后续的案例中来体会︰
- 父组件替换插槽的标签,但是内容由子组件来提供。
我们先提一个需求︰
- 子组件中包括一组数据:比如:
pLanguages: ['JavaScript', 'Python', 'Swift', 'Go','C++']
- 需要在多个界面进行展示:
- 某些界面是以水平方向展示的
- 某些界面是以列表形式展示的
- 某些界面直接展示一个数组
- 内容在子组件,希望父组件告诉我们如何展示,怎么办呢?
- 利用slot作用域插槽就可以了
<!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>
</head>
<body><div id="app"><cpn></cpn><cpn><!-- 目的是获取子组件中的 pLanguages --><template slot-scope="slot"><span v-for="item in slot.data">{{item}} - </span></template></cpn></div><template id="cpn"><div><h2>我是组件</h2><slot :data="pLanguages"><ul><li v-for="item in pLanguages">{{item}}</li></ul></slot></div></template><script src="../js/vue.js"></script><script>const app = new Vue({el: '#app', data: {},components: {cpn: {template: '#cpn',data() {return {pLanguages: ['Python', 'Java', 'Go', 'C++']}}}}})</script>
</body>
</html>
Vue.js 组件化开发相关推荐
- Vue.js组件化开发实践
Vue.js组件化开发实践 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了一下的内容.首先会对使用Vue进行开发的一 ...
- VUE.JS 组件化开发实践
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模 ...
- React.js组件化开发第一步(框架搭建)
开始前 安装 node.js; 安装 cnpm; 安装 yarn; 安装完成yarn后, 将镜像替换成国内的: $ yarn config set registry 'https://registry ...
- Vue/React组件化开发的一些思考
组件化开发的优势 组件化开发利用了面向对象的威力,易于构建规模比较大的应用并且获得比较高的可维护性,可扩展性.Vue.React厂商及社区不但提供了组件化开发的框架,而且提供了易于起步并包含了从编码. ...
- html 组件化 编辑器,vue.js组件化使用百度富文本编辑器(一)
注意: 本文采用的编辑器为:idea 1.下载百度富文本编辑器,地址:https://ueditor.baidu.com/website/download.html#ueditor 2.加入到stat ...
- Vue.js组件化笔记
局部调用 <template><my-page></my-page> </template><script> import MyPage f ...
- Vue | Vue.js 组件化基础 - 脚手架
- 【Vue.js 知识量化】组件化开发 + 前端模块化
Vue.js 组件化开发 组件化 认识组件化 注册组件 全局组件和局部组件 父子组件 组件数据 父子组件的通信 父->子:props 子->父:$emit() 父子组件的访问方式 $chi ...
- Vue.js教程-组件化开发
Vue.js教程-组件化开发 前言 Vue组件化 什么是组件化 Vue单页面开发的解释 组件化思想 组件的使用 原理 实际开发中的使用-父子组件 父子组件传递数据 父传子-props用法 子传父-th ...
最新文章
- Go语言学习笔记 - PART11 - 面向对象
- [iOS] 在UIToolBar中增加UILabel等控件(xib/storyboard图形界面方式)
- 织梦防html5,最近织梦DEDECMS被注入漏洞,如何做好防护措施。
- 查看coo_matrix的shape
- “宝藏”大会NVIDIA GTC Digital来袭!这些AI前沿课程不容错过
- spring boot 跨域请求_SpringBoot 系列教程 web 篇之自定义请求匹配条件 RequestCondition...
- Angular自学笔记(?)结构型指令
- Django的各种初识
- vs2005新建类,自定义模板信息(转载)
- 软考系统架构师笔记-综合知识重点(二)
- 效果直逼flash的Div+Css+Js菜单
- Alpha版本冲刺(一)
- SQL Server数据库 - 安装教程
- 浏览器自定义横向滚动条_自定义滚动条–跨浏览器解决方案
- Bugku:杂项 一枝独秀
- 常用的四大绩效考核方法以及优缺点
- 微信小程序的版本更新机制是什么?
- Visual Studio2013 调试报错:该文件没有与之关联的程序来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置...
- 腾讯视频显示网络连接服务器失败怎么办,腾讯视频不能投屏怎么回事 腾讯视频无法投屏的解决方法...
- 深度学习系列 -- 神经网络和深度学习(Neural Networks and Deep Learning)(一):深度学习引言以及神经网络编程基础