is特性的使用
当模板为某种标签的子元素 比如table的tr ul的li
<body>
<div id="app">
<component-tr></component-tr>
</div>
<script>
var componentTr = {
template: "<tr><td>学号</td><td>姓名</td></tr>"
}
var vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
components: {
"component-tr": componentTr
}
})
</script>
</body>
渲染出来的页面tr没有在table标签内包裹 ,虽然还是能够渲染出页面,但这并不符合w3c标准
如果要解决这个问题需要用到is属性的特性
<div id="app">
<table>
<tr is='component-tr'></tr>
</table>
</div>
这样的话就符合w3c标准了。
注意:外面的table标签一定要加上,然后把自定义组件名作为is的属性值再次运行
text/x - template 类型应用
之前写过的定义模板的方式都是为模板设置模板字符串,也称之为内联模板字符串
这种写法的缺点就是如果模板字符串中的HTML代码很多,那么写起来就非常的不方便并且不好换行。
Vue中还有另一种自定义模板的方式,也就是写在script元素中,并为其带上text/x-template的类型,通过一个id对模板进行引用。其实就是相当于前面全局组件中内置template的写法。
注意:x-template模板需要定义在Vue所属的DOM元素外,与DOM元素并列
<!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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<tr is='component-tr'></tr>
</table>
</div>
<script type="text/x-template" id="tmp1">
<tr>
<td>学号</td>
<td>姓名</td>
</tr>
</script>
<script>
var componentTr = {
template: "#tmp1"
}
var vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
components: {
"component-tr": componentTr
}
})
</script>
</body>
</html>
在script标签的属性中写进type=“text/x-template” ,就可以在其中写组件的模板,注册组件的时候就只需要在template选项中引用这个模板的id就可以了(注意要加引号)。
在注册组件时,还可以添加data属性,然后就可以引用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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<tr is='component-tr'></tr>
</table>
</div>
<script type="text/x-template" id="tmp1">
<tr>
<td>{
{
num}}</td>
<td>{
{
name}}</td>
</tr>
</script>
<script>
var componentTr = {
template: "#tmp1",
data: function () {
return {
num: 12,
name: "xiaoming",
}
}
}
var vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
components: {
"component-tr": componentTr
}
})
</script>
</body>
</html>
如果数据是后端返回的一个数据的集合,如对象数组,那么如何处理动态显示出所有数据呢?
<!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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<tr is='component-tr'></tr>
</table>
</div>
<script type="text/x-template" id="tmp1">
<div>
<tr v-for="item in stulist">
<td>{
{
item.num}}</td>
<td>{
{
item.name}}</td>
</tr>
</div>
</script>
<script>
var componentTr = {
template: "#tmp1",
data: function () {
return {
stulist: [
{
id: 12, name: 'xiaoming' },
{
id: 13, name: 'xiaozhang' },
{
id: 14, name: 'xiaoli' },
]
}
}
}
var vm = new Vue({
el: "#app",
data: {
msg: "hello"
},
components: {
"component-tr": componentTr
}
})
</script>
</body>
</html>
父子组件的定义及使用
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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<my-comp1></my-comp1>
<!-- 在这里直接使用my-comp2这个子组件会报错,因为他是在my-comp1这个组件里面,也就是没有在根组件下注册 -->
</div>
<script type="text/x-template" id="comp1">
<div>
<h3>我是comp1父组件</h3>
<hr>
<my-comp2></my-comp2>
</div>
</script>
<template id="comp2">
<div>
<h3>我是comp2子组件</h3>
</div>
</template>
<script>
var vm = new Vue({
//根组件
el: "#app",
data: {
},
components: {
//父组件
'my-comp1': {
data() {
return {
msg: "123456",
name: "zhangsan",
age: 19,
user: {
id: 11, username: "zhangsan" }
}
},
template: "#comp1",
components: {
//子组件
'my-comp2': {
template: "#comp2"
}
}
},
}
})
</script>
</body>
</html>
渲染结果如下:
结论:子组件只能在其父组件中使用,这里id为app 的div 就是根组件,同时也是comp1的父组件
同时comp1也是comp2的父组件, 子组件只能够在父组件中去使用
- 每个组件的作用域是独立的
在上面例子斜体代码下面增加如下代码(在自己的组件中访问自己的数据):
<h3>访问自己组件中的数据:{
{
msg}} {
{
name}} {
{
age}}</h3>
可以看到在父组件中访问到了父组件data属性储存的数据
如果在子组件中输入这样的代码则会产生报错,这是因为正常情况下子组件无法访问到父组件中的数据。当然父组件也无法访问子组件中的数据,每个组件实例的作用域是相互独立的。
子组件访问父组件中的数据
子组件访问父组件中的数据的步骤如下:
1、在调用子组件时,绑定想要获取的父组件的数据
2、在子组件的内部,使用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>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<my-comp1></my-comp1>
<!-- 在这里直接使用my-comp2这个子组件会报错,因为他是在my-comp1这个组件里面,也就是没有在根组件下注册 -->
</div>
<script type="text/x-template" id="comp1">
<div>
<h3>我是comp1父组件</h3>
<h3>访问自己组件中的数据:{
{
msg}} {
{
name}} {
{
age}}</h3>
<hr>
//调用子组件时,绑定想要获取的父组件的数据,这里绑定的message是自己取得名称,这里为了区分先取名为message
<my-comp2 :message='msg'></my-comp2>
</div>
</script>
<template id="comp2">
<div>
<h3>我是comp2子组件</h3>
<h4>访问父组件的数据{
{
message}}</h4>
</div>
</template>
<script>
var vm = new Vue({
//根组件
el: "#app",
data: {
},
components: {
//父组件
'my-comp1': {
data() {
return {
msg: "123456",
name: "zhangsan",
age: 19,
user: {
id: 11, username: "zhangsan" }
}
},
template: "#comp1",
components: {
//子组件
'my-comp2': {
template: "#comp2",
//在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据 采用字符串数组形式
props: ['message']
}
}
},
}
})
</script>
</body>
</html>
注意:在子组件内部,使用props选项声明获取的数据,即接收来自父组件的数据 采用字符串数组形式
调用子组件时,绑定想要获取的父组件的数据,这里绑定的message是自己取得名称,这里为了区分先取名为message
组件中props选项用法深入
props接收父组件中的选项的数据采用的是简单的方式,即采用字符串数组的形式。
props可以是简单的数组,或者使用对象作为替代,对象允许配置最高级的选项,如类型检测、自定义验证和设置默认值。props对象可以有以下选项:
- type:x
- default:any
- required:Boolean
- validator:Function
第一种中的x可以是原生构造函数中的一种,也可以是自定义构造函数或以上内容组成的数组。设置prop就会检查prop是否为给定的类型,否则会抛出警告
第二种中的选项是为prop指定一个默认值,如果该prop没有被传入,则换用这个值。对象或数组的默认值必须从一个工厂函数返回。
第三种中的是定义prop是否为必填项。在非生产环境中,如果这个值为true且该prop没有被传入,则会报出警告
自定义验证函数会将该prop的值作为唯一的参数代入。在非生产环境下,如果该函数返回了一个false值,就会出警告
父组件访问子组件中的数据
子组件通过props选项可以接收父组件中的数据,父组件同样也可以访问子组件中的数据
父组件访问子组件中的数据基本用法
父组件访问子组件数据的总体思路:把子组件中的数据发送到父组件中,主要有两个步骤:
1、在子组件中使用vm.$emit(事件名,要发送的数据)触发一个自定义事件,事件名自定义。要发送多个数据,直接用逗号隔开
2、父组件在使用子组件的地方监听子组件触发的事件,并在父组件中定义方法获取数据。