vue component组件 - 幕布
- vue component组件
- 全局化注册组件 (全局组件) Vue.component
全局组件可在多个构造器的作用域中使用;
例子:
<h1>component-1</h1>
<hr>
<div id="app">
<jspang></jspang>
</div>
<script type="text/javascript">
//注册全局组件
Vue.component('jspang',{
template:`<div style="color:red;">全局化注册的jspang标签</div>`
})
var app=new Vue({
el:'#app',
data:{
}
})
</script>
- 局部注册组件(局部组件)
局部注册的组件只能在组件注册的作用域里进行使用,其他作用域使用无效。
例子:
<body>
<h1>component-1</h1>
<hr>
<div id="app">
<panda></panda>
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:red;">局部注册的panda标签</div>`
}
}
})
</script>
</body>
注意:构造器里的components 是加s的,而全局注册是不加s的。还有components对象中的组件名称需要加‘’,需为字符串,不然后报错称未定义;
- 组件和指令的区别
组件注册的是一个标签,而指令注册的是已有标签里的一个属性。在实际开发中我们还是用组件比较多,指令用的比较少。因为指令看起来封装的没那么好,这只是个人观点。 - component组件props属性设置
- 定义属性并获取属性值
定义属性我们需要用props选项,加上数组形式的属性名称,例如:props:[‘here’]。在组件的模板里读出属性值只需要用插值的形式,例如{{ here }}.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../assets/js/vue.js"></script>
<title>component-2</title>
</head>
<body>
<h1>component-2</h1>
<hr>
<div id="app">
<panda here="China"></panda>
</div>
<script type="text/javascript">
var app=new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:red;">Panda from {{ here }}.</div>`,
props:['here']
}
}
})
</script>
</body>
</html>
上面的代码定义了panda的组件,并用props设置了here的属性值,在here属性值里传递了China给组件。
最后输出的结果是红色字体的Panda from China.
- 属性中带有 ' - ' 的处理方式
我们在写属性时经常会加入’-‘来进行分词,比如:<panda from-here=”China”></panda>,那这时我们在props里如果写成props:[‘form-here’]是错误的,我们必须用小驼峰式写法props:[‘formHere’]。
html文件:
<panda from-here="China"></panda>
<panda from-here="China"></panda>
javascript文件:
var app=new Vue({
el:'#app',
components:{
"panda":{
template:`<div style="color:red;">Panda from {{ fromHere }}.</div>`,
props:['fromHere']
}
}
})
PS:因为这里有坑,所以还是少用-为好。
- 在构造器里向组件中传值
把构造器中data的值传递给组件,我们只要进行绑定就可以了。就是我们第一季学的v-bind:xxx.
我们直接看代码:
Html文件:
<panda v-bind:here="message"></panda>
javascript文件:
var app=new Vue({
el:'#app',
data:{
message:'SiChuan'
},
components:{
"panda":{
template:`<div style="color:red;">Panda from {{ here }}.</div>`,
props:['here']
}
}
})
- component父子组件关系
- component组件中的data书写方式
component中的data 不能像实例中直接使用 data:{},这样选项的方式进行设置,
因为作为一个组件肯定会被多个地方复用,如果使用 data:{}设置的话,一个组件修改了data的值,其他的组件也会跟着改变,因为他们引用的是同一个data;
所以 需要使用 data() {return { }} 的方式, 因该是闭包的应用,这个不太懂,标记下 - 动态组件,根据传的值不同加载不同的组件内容
通过使用保留的 <component> 元素,动态地绑定到它的 is 特性,我们让多个组件可以使用同一个挂载点,并动态切换:
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
<component v-bind:is="currentView">
<!-- 组件在 vm.currentview 变化时改变! -->
</component>
也可以直接绑定到组件对象上:
var Home = {
template: '<p>Welcome home!</p>'
}
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})
- 组件间传值
- 父子组件间通信
- 父组件 → 子组件 props
父组件向子组件传值主要是通过 props
https://cn.vuejs.org/v2/api/#props
props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义校验和设置默认值。
// 简单语法
Vue.component('props-demo-simple', {
props: ['size', 'myMessage']
})
// 对象语法,提供校验
Vue.component('props-demo-advanced', {
props: {
// 只检测类型
height: Number,
// 检测类型 + 其他验证
age: {
type: Number,
default: 0,
required: true,
validator: function (value) {
return value >= 0
}
}
}
})
- 子组件 → 父组件 event
子组件向父组件传递数据时,就只能用$emit $on相结合的方式,
由子组件触发自定义事件,由父组件监听改事件,并接受数据;
注意:这里有个坑,就是你绑定自定义事件的位置必须在该子组件上,比如下面的
<hello @newNodeEvent="parentLisen" />,绑定在了hello子组件上,如果把@newNodeEvent="parentLisen" 放到外层,或者其他不在子组件上的位置,则无法监听到子组件的$emit
ps:App.vue 父组件
Hello.vue 子组件
<!--App.vue :-->
<template>
<div id="app">
<hello @newNodeEvent="parentLisen" />
</div>
</template>
<script>
import hello from './components/Hello'
export default {
name: 'app',
'components': {
hello
},
methods: {
parentLisen(evtValue) {
//evtValue 是子组件传过来的值
alert(evtValue)
}
}
}
</script>
<!--Hello.vue :-->
<template>
<div class="hello">
<input type="button" name="" id="" @click="chilCall()" value="子调父" />
</div>
</template>
<script>
export default {
name: 'hello',
'methods': {
chilCall(pars) {
this.$emit('newNodeEvent', '我是子元素传过来的')
}
}
}
</script>
- 非父子组件间通信
有时候两个组件也需要通信 (非父子关系)。在简单的场景下,可以使用一个空的 Vue 实例作为中央事件总线:
var bus = new Vue()
// 触发组件 A 中的事件
bus.$emit('id-selected', 1)
// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
// ...
});
在复杂的情况下,我们应该考虑使用专门的状态管理模式 vuex.
注意:如果使用了vue-cli创建的项目,就需要在外面创建一个新的vue实例,然后分别在两个组件中引用这个,才能实现同一vue实例的中央事件总线;
比如: 新建一个eventBus.vue 里面的内容为新建一个vue实例,供其他组件引入
```
import Vue from 'vue'
export default new Vue();
```
之后就可以在 componentA 和componentB中import进来:
```
componentA:
import bus from 'eventBus.vue'
bus.$emit('myevent', '这是传递的数据');
```
```
componentB:
import bus from 'eventBus.ves'
mounted() {
let _this = this;
bus.$on('myevent', function(msg) {
_this.msg = msg; //注意 这里的this已经不是指向含有data的实例的,而是bus新实例化出的中央事件总线,所以在上面需要使用 let _this = this;来转换
})
//也可以使用 bind(this)来须将 this 绑定在组件实例上。如果不使用 bind , 也可以使用箭头函数。代码如下:
bus.$on('myevent', function(msg) {
this.msg = msg;
.bind(this))
}
- slot 分发 (插槽)
用于父级组件内容向子组件中特定位置插入父级已有的HTML代码
```
//父级组件:
<template>
<div>
<ul>
<my-li :title="list[0]" v-on:remove="list.splice(index, 1)">
<p>这是修改后的slot</p>
</my-li>
</ul>
</div>
</template>
//子组件
<template>
<li>
{{title}}
<div>
<slot>默认slot</slot>
</div>
</li>
</template>
```
<slot></slot>标签中可以写入默认值,如果父级在 <my-li></my-li>中没有内容,则会显示默认值;
**具名slot**
<slot></slot>标签可以设置 name属性,然后通过父组件中的 slot=“”属性进行分别绑定
```
//父级组件:
<template>
<div>
<ul>
<my-li :title="list[0]" v-on:remove="list.splice(index, 1)">
<p slot="header">这是header slot</p>
<p slot="footer">这是footer slot</p>
</my-li>
</ul>
</div>
</template>
//子组件
<template>
<li>
{{title}}
<div>
<slot name="header">默认herder slot</slot>
<slot name="footer">默认footer slot</slot>
</div>
</li>
</template>
```
posted @
2017-07-30 13:16
milo_蓝色大飞机
阅读(
750)
评论()
编辑
收藏
举报