首先呢 先注册组件
全局组件注册方式:Vue.component(组件名,{方法})
eg:
<body>
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
<script>
Vue.component("my-component",{
template:"<h1>我是全局组件</h1>"
});
new Vue({
el:"#app"
});
new Vue({
el:"#app1"
})
</script>
</body>
渲染结果:
<div id="app">
<h1>我是全局组件</h1>
</div>
<div id="app1">
<h1>我是全局组件</h1>
</div>
这里需要注意:
1.全局组件必须写在Vue实例创建之前,才在该根元素下面生效;
eg:
<body>
<div id="app">
<my-component></my-component>
</div>
<div id="app1">
<my-component></my-component>
</div>
<script>
new Vue({
el: "#app"
});
Vue.component("my-component", {
template: "<h1>我是全局组件</h1>"
});
new Vue({
el: "#app1"
})
</script>
</body>
这样只会渲染app1根元素下面的,并不会渲染app根元素下面的,并且会报错。
2.模板里面第一级只能有一个标签,不能并行;
<body>
<div id="app">
<my-component></my-component>
</div>
<script>
new Vue({
el: "#app"
});
Vue.component("my-component", {
template: "<h1>我是全局组件</h1>" +
"<p>我是全局组件内标签</p>"
});
new Vue({
el: "#app1"
})
</script>
</body>
这样子会报错,并且只会渲染第一个标签h1;我们应该这样子写:
<body>
<div id="app">
<my-component></my-component>
</div>
<script>
new Vue({
el: "#app"
});
Vue.component("my-component", {
template: "<h1>我是全局组件<p>" +
"我是全局组件内标签</p></h1>"
});
new Vue({
el: "#app1"
})
</script>
</body>
局部组件注册方式,直接在Vue实例里面注册
eg:
<body>
<div id="app1">
<child-component></child-component>
</div>
<script>
new Vue({
el: "#app1",
components:{
"child-component":{
template:"<h1>我是局部组件</h1>"
}
}
});
</script>
局部组件需要注意:
1.属性名为components,s千万别忘了;
2.套路比较深,所以建议模板定义在一个全局变量里,代码看起来容易一点,如下:(模板标签比较多的时候,这样子写更加简洁规整)
<body>
<div id="app1">
<child-component></child-component>
</div>
<script>
var child={
template:"<h1>我是局部组件</h1>"
};
new Vue({
el: "#app1",
components:{
"child-component":child
}
});
</script>
</body>
关于组件中的其他属性,可以和实例中的一样,但是data属性必须是一个函数:
eg:
<body>
<div id="app1">
<child-component></child-component>
</div>
<script>
var child={
template:"<button @click='add2'>我是局部组件:{{m2}}</button>",
data:function(){
return {m2:1}
},
methods:{
add2:function(){
this.m2++
}
}
};
new Vue({
el: "#app1",
components:{
"child-component":child
}
})
</script>
</body>
显示结果:
image.png
组件之间传值有三种方式
1、父传子
2、子传父
3、利用时间总线
子传父
<div id="app">
<h5>当前的计数值为:{{childData}}{{cheran}}</h5>
<c @countadd="coundH" step="3" msg="点击"></c>
<c @countadd="coundH" step="2" msg="你好"></c>
</div>
<script src="./lib/vue.js"></script>
<script>
//组件之间传值 子传父 通过事件派发$emit
//在vue中使用$emit实现事件派发
//父组件向子组件传值,通过props传递
var counter = {
template: `<button @click="plusHandle">step{{step}}当前值为:{{count}}{{dd}}</button>`,
data() {
return {
count: 0,
dd: "",
};
},
props: ['step', "msg"],
methods: {
plusHandle() {
//alert(this.step);
//alert(this.msg);
this.count += this.step * 1;
//参数一表示事件名字
this.dd = this.msg;
//参数二表示传递参数
this.$emit("countadd", this.count, this.dd)
},
},
};
var app = new Vue({
el: "#app",
data: {
childData: 0,
cheran: "",
},
components: {
c: counter,
},
methods: {
coundH(v, a) {
console.log(v)
console.log(a)
this.childData = v;
this.cheran = a;
}
}
});
</script>
父传子
<div id="app">
<h5>我是用来获取子组件的值的{{strchild}}----{{ds}}</h5>
<inp @chuanzhi="chuanzhihandle" msg="你好呀"></inp>
</div>
<script src="./lib/vue.js"></script>
<script>
Vue.component("inp", {
template: `<div>
<input @keyup.enter="chuanzhi" v-model="txt" placeholder="请输入内容" />
</div>`,
data() {
return {
txt: "",
ds: "",
};
},
props: ["msg"],
methods: {
chuanzhi() {
// alert(this.txt);
this.ds = this.msg;
this.$emit("chuanzhi", this.txt, this.ds);
},
},
})
var app = new Vue({
el: "#app",
data: {
strchild: "",
ds: "",
},
methods: {
chuanzhihandle(str, ds) {
this.strchild = str;
this.ds = ds;
}
},
});
</script>
事件总线
用来解决非相关组件之间的传值
使用一个空白的对象单独用来做事件的派发和监听
在vue中通过emit派发
非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。
公共bus.js
//bus.js
import Vue from 'vue'
export default new Vue()
组件A:
<template>
<div>
A组件:
<span>{{elementValue}}</span>
<input type="button" value="点击触发" @click="elementByValue">
</div>
</template>
<script>
// 引入公共的bug,来做为中间传达的工具
import Bus from './bus.js'
export default {
data () {
return {
elementValue: 4
}
},
methods: {
elementByValue: function () {
Bus.$emit('val', this.elementValue)
}
}
}
</script>
组件B:
<template>
<div>
B组件:
<input type="button" value="点击触发" @click="getData">
<span>{{name}}</span>
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
name: 0
}
},
mounted: function () {
var vm = this
// 用$on事件来接收参数
Bus.$on('val', (data) => {
console.log(data)
vm.name = data
})
},
methods: {
getData: function () {
this.name++
}
}
}
</script>