组件
组件实现
组件可用以下方式实现,其实组件都是以extend方法生产的,代码如下:
组件可分为全局组件和局部组件
全局组件使用Vue.component注册
局部组件在Vue实例中使用component属性进行注册
<body>
<div id="app">
<cpn></cpn>
</div>
<div id="appTwo">
<cpn></cpn>
</div>
<script src="../vue.js"></script>
<script>
const cpns = Vue.extend({
template: ` <ul>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
<li>hello world</li>
</ul>`
});
Vue.component('cpn', cpns);
const app = new Vue({
el: '#app',
// components: {
// cpn: cpns
// }
});
const appTwo = new Vue({
el: '#appTwo',
});
</script>
</body>
组件语法糖
组件同样也有语法糖写法
第一种写法为template,它将extend方法省去,简化了代码
<body>
<div id="app">
<cpn></cpn>
</div>
<script src="../vue.js"></script>
<script>
// Vue.component('cpn', {
// template: `<div>
// <h1>hello papa</h1>
// <p>how you doing</p>
// </div>`
// });
const app = new Vue({
el: '#app',
components: {
cpn: {
template: `<div>
<h1>hello papa</h1>
<p>how you doing</p>
</div>`
}
}
});
</script>
</body>
Vue还提供了另外一种语法糖,这种语法糖可以很好的模板代码与js代码进行分离
<body>
<div id="app">
<cpn></cpn>
</div>
<script src="../vue.js"></script>
<!-- <script type="text/x-template" id="cpn">-->
<!-- <div>-->
<!-- <h1>hello daddy</h1>-->
<!-- <p>how you doing</p>-->
<!-- </div>-->
<!-- </script>-->
<template id="cpn">
<div>
<h1>hello daddy</h1>
<p>how you doing</p>
</div>
</template>
<script>
Vue.component('cpn', {
template: `#cpn`
});
const app = new Vue({
el: '#app',
});
</script>
</body>
组件数据处理
其实组件的结构和vue实例很相似,甚至可以将vue实例当作一个根组件,因此vue实例中的属性在template中也能使用
<body>
<div id="app">
<cpn></cpn>
<cpn></cpn>
<cpn></cpn>
</div>
<script src="../vue.js"></script>
<template id="cpn">
<div>
<div>
<h1>当前计数:{{count}}</h1>
<button @click="subCount"> -</button>
<button @click="addCount"> +</button>
</div>
</div>
</template>
<script>
Vue.component('cpn', {
template: `#cpn`,
data() {
return {
count: 0
}
},
methods: {
addCount() {
this.count++;
},
subCount() {
this.count--
}
}
});
const app = new Vue({
el: '#app'
});
</script>
</body>
但是得记住,template中的data是一个函数,返回值是一个对象,这样做是为了让各个组件实例的数据不相互影响
props属性
props属性常常用于父组件向子组件传递数据,刚刚说到vue实例其实也可看做一个组件,因此常用于vue实例向组件传递数据
但实际上官方文档是这样说的:
Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
也就是说prop是我们在组件上自定义的属性,我们可以直接给这个属性赋值,它是可以显示在模板语法中的,也可以通过绑定的方式,将属性与vue实例的data属性中的值进行绑定,这样模板语法中渲染出来的值就是来自其他节点的
<body>
<div id="app">
<cpn :name="name" :movies="movies"></cpn>
</div>
<template id="cpn">
<div>
<h1>hello: {{name}}</h1>
<p>see movies: {{movies}}</p>
</div>
</template>
<script src="../vue.js"></script>
<script>
Vue.component('cpn',{
template: `#cpn`,
props: ['name', 'movies']
});
const app = new Vue({
el: '#app',
data() {
return {
name: 'justin timberlake',
movies: ['千与千寻', '星际穿越', '龙猫']
};
}
});
</script>
</body>
$emit方法
官方文档给出的解释是:
触发当前实例上的事件。附加参数都会传给监听器回调。
可以这样理解,emit相当于将事件监听与模板实例里面的方法绑定起来,在触发模板实例时,便会回调emit所在的方法,并将方法的参数传递给模板实例的方法,随后进行数据的处理
<body>
<div id="app">
<cpn @get-item="btnClick" :movies="movies"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in movies" @click="$emit('get-item', item)">{{item}}</button>
</div>
</template>
<script src="../vue.js"></script>
<script>
const cpn = {
template: `#cpn`,
data() {
return {
}
},
props: ['movies']
// methods: {
// btnClick(item) {
// this.$emit('get-item', item);
// }
// }
}
const app = new Vue({
el: '#app',
data:{
movies: ['taylor', 'justin', 'rihanna', 'pink']
},
components: {
cpn
},
methods: {
btnClick(item) {
console.log(item);
}
}
});
</script>
</body>
获取父子组件
获取子组件
获取子组件有两种方法,分别是$children和$refs
不同的是,$children获取的是所有子节点,以数组形式存储
$refs获取含有ref属性的节点,以对象的形式存储,也是较为常用的一种方式
<body>
<div id="app">
<cpn ref="first"></cpn>
<cpn></cpn>
<cpn></cpn>
<button @click="getChild()">获取子节点数据</button>
</div>
<template id="cpn">
<h1>i am son node</h1>
</template>
<script src="../vue.js"></script>
<script>
const app = new Vue({
el: '#app',
methods: {
getChild() {
// console.log(this.$children[0].message);
console.log(this.$refs.first);
}
},
components: {
cpn: {
template: `#cpn`,
data() {
return {
message: 'you got me!'
}
}
}
}
});
</script>
</body>
获取父组件
获取父组件也有两种方法,分别是$parents和$root
$parent是获取所有的父节点
$root是获取根节点
这两种方法都较为少用
<body>
<div id="app">
<cpn></cpn>
</div>
<template id="cpn">
<div>
<h1>hello world</h1>
<ccpn></ccpn>
</div>
</template>
<template id="ccpn">
<div>
<h1>i am child</h1>
<button @click="getFather()">访问父节点</button>
<button @click="getRoot()">访问根节点</button>
</div>
</template>
<script src="../vue.js"></script>
<script>
const app = new Vue({
el: '#app',
date: {
message: 'hello!!!'
},
components: {
cpn: {
template: `#cpn`,
components: {
ccpn: {
template: `#ccpn`,
methods: {
getFather() {
console.log(this.$parent);
},
getRoot() {
console.log(this.$root)
}
}
}
}
}
}
});
</script>
</body>

浙公网安备 33010602011771号