Vue基础入门讲义-组件化
Posted IT-熊猫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue基础入门讲义-组件化相关的知识,希望对你有一定的参考价值。
文章目录
1.引言
在大型应用开发的时候,页面可以划分成很多部分。往往不同的页面,也会有相同的部分。例如可能会有相同的头部导航。
但是如果每个页面都独自开发,这无疑增加了开发的成本。所以会把页面的不同部分拆分成独立的组件,然后在不同页面就可以共享这些组件,避免重复开发。
2.定义全局组件
通过Vue的component方法来定义一个全局组件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//定义组件
const counter =
template: "<button @click='num++'>你点击了num次;我记住了</button>",
data()
return num: 0
;
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("counter", counter);
var app = new Vue(
el: "#app"
);
</script>
</body>
</html>
- 组件其实也是一个Vue实例,因此它在定义时也会接收:data、methods、生命周期函数等
- 不同的是组件不会与页面的元素绑定,否则就无法复用了,因此没有el属性。
- 但是组件渲染需要html模板,所以增加了template属性,值就是HTML模板
- 全局组件定义完毕,任何vue实例都可以直接在HTML中通过组件名称来使用组件了
- data的定义方式比较特殊,必须是一个函数。
效果:
3.组件的复用
定义好的组件,可以任意复用多次:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
//定义组件
const counter =
template: "<button @click='num++'>你点击了num次;我记住了</button>",
data()
return num: 0
;
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("counter", counter);
var app = new Vue(
el: "#app"
);
</script>
</body>
</html>
你会发现每个组件互不干扰,都有自己的num值。怎么实现的?
组件的data属性必须是函数!
当定义这个 <counter>
组件时,它的data 并不是像这样直接提供一个对象:
data:
num: 0
取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function ()
return
num: 0
如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!
4.局部注册
一旦全局注册,就意味着即便以后你不再使用这个组件,它依然会随着Vue的加载而加载。
因此,对于一些并不频繁使用的组件,会采用局部注册。
在外部定义一个对象,结构与创建组件时传递的第二个参数一致:
然后在Vue中使用它:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<counter></counter>
<counter></counter>
<counter></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
//定义组件
const counter =
template: "<button @click='num++'>你点击了num次;我记住了</button>",
data()
return num: 0
;
//全局注册组件;参数1:组件名称,参数2:组件
//Vue.component("counter", counter);
var app = new Vue(
el: "#app",
//局部注册组件
components:
counter: counter
);
</script>
</body>
</html>
-
components就是当前vue对象子组件集合。
- 其key就是子组件名称
- 其值就是组件对象的属性
-
效果与刚才的全局注册是类似的,不同的是,这个counter组件只能在当前的Vue实例中使用
5.组件通信
通常一个单页应用会以一棵嵌套的组件树的形式来组织:
- 页面首先分成了顶部导航、左侧内容区、右侧边栏三部分
- 左侧内容区又分为上下两个组件
- 右侧边栏中又包含了3个子组件
各个组件之间以嵌套的关系组合在一起,那么这个时候不可避免的会有组件间通信的需求。
5.1.父向子传递props
比如有一个子组件:
Vue.component("introduce",
// 直接使用props接收到的属性来渲染页面
template:'<h3>title</h3>',
props:[title] // 通过props来接收一个父组件传递的属性
)
- 这个子组件中要使用title属性渲染页面,但是自己并没有title属性
- 通过props来接收父组件属性,名为title
父组件使用子组件,同时传递title属性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<!--使用定义好的全局组件-->
<introduce :title="msg"></introduce>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
//定义组件
const introduce =
//使用props属性title的值渲染模版
template: "<h2>title</h2>",
//定义接收来自父组件的属性
props: ["title"]
;
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("introduce", introduce);
var app = new Vue(
el: "#app",
data:
msg: "父组件中的msg属性的内容"
);
</script>
</body>
</html>
效果:
5.2.传递复杂数据
定义一个子组件:
const myList =
template: '\\
<ul>\\
<li v-for="item in items" :key="item.id">item.id : item.name</li>\\
</ul>\\
',
props: // 通过props来接收父组件传递来的属性
items: // 这里定义items属性
type: Array,// 要求必须是Array类型
default: [] // 如果父组件没有传,那么给定默认值是[]
;
- 这个子组件可以对 items 进行迭代,并输出到页面。
- 但是组件中并未定义items属性。
- 通过props来定义需要从父组件中接收的属性
- items:是要接收的属性名称
- type:限定父组件传递来的必须是数组,否则报错;type的值可以是Array或者Object(传递对象的
时候使用) - default:默认值,
- type:限定父组件传递来的必须是数组,否则报错;type的值可以是Array或者Object(传递对象的
- items:是要接收的属性名称
default,如果是对象则需要写成方法的方式返回默认值。如:
default()
return "xxx":"默认值";
页面内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<h2>学习的课程有:</h2>
<!-- 接受来自父组件的属性值,使用v-bind指向父组件的属性lessons;注意使用my-list -->
<my-list :items="lessons"></my-list>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
//定义组件
const myList =
//可以使用双引号、单引号或者如下使用的 ` 飘号
template: `
<ul>
<li v-for="item in items" :key="item.id">item.id--item.name</li>
</ul>
`,
//定义接收来自父组件的属性
props:
//定义模版中使用的属性
items:
//必须为数组类型
type: Array,
//默认为空数组
default: []
;
var app = new Vue(
el: "#app",
data:
msg: "父组件中的msg属性的内容",
lessons: ["id": 1, "name": "Java",
"id": 2, "name": "php",
"id": 3, "name": "前端"
]
,
//注册组件
components:
//如果组件key和value一致可以简写如下
myList
);
</script>
</body>
</html>
效果:
5.3.子向父的通信
来看这样的一个案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<h2>num = num</h2>
<!--使用定义好的全局组件-->
<counter :snum="num"></counter>
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
//定义组件
const counter =
//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮
template: `
<div>
<button @click="snum++">+</button>
<button @click="snum--">-</button>
</div>
`,
props: ["snum"]
;
//全局注册组件;参数1:组件名称,参数2:组件
Vue.component("counter", counter);
var app = new Vue(
el: "#app",
data:
num: 0
);
</script>
</body>
</html>
- 子组件接收父组件的num属性
- 子组件定义点击按钮,点击后对num进行加或减操作
尝试运行,好像没问题,点击按钮试试:
子组件接收到父组件属性后,默认是不允许修改的。怎么办?
既然只有父组件能修改,那么加和减的操作一定是放在父组件:
var app = new Vue(
el: "#app",
data:
num: 0
,
methods:
//父组件中定义操作num的方法
numPlus()
this.num++;
,
numReduce()
this.num--;
);
但是,点击按钮是在子组件中,那就是说需要子组件来调用父组件的函数,怎么做?
可以通过v-on指令将父组件的函数绑定到子组件上:
<div id="app">
<h2>num = num</h2>
<!--使用定义好的全局组件-->
<counter @plus="numPlus" @reduce="numReduce" :snum="num"></counter>
</div>
然后,当子组件中按钮被点击时,调用绑定的函数:
//定义组件
const counter =
//组件只能是一个元素里面包裹其他元素;如下面,一个div包含两个按钮
template: `
<div>
<button @click="incrNum">+</button>
<button @click="decrNum">-</button>
</div>
`,
props: ["snum"],
methods:
//点击模板中使用的方法
incrNum()
return this.$emit("plus");
,
decrNum()
return this.$emit("reduce");
;
完成页面如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vuejs测试</title>
</head>
<body>
<div id="app">
<h2>num = num</h2>
<!--使用定义好的全局组件-->
<counter @plus="numPlus" @reduce="numReduce" :snum="num"></counter>
</div>
<script src="node_modules/vue/dist/vue.js">以上是关于Vue基础入门讲义-组件化的主要内容,如果未能解决你的问题,请参考以下文章