组件的介绍:
1.组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。
2.所有的Vue组件同时也都是Vue的实例,所以可接受相同的选项对象(除了一些根级特有的选项)并提供相同的生命周期钩子。
全局组件:
——Vue.component(tagName, options)
——Vue.component('my-component', {
——template: '<div>A custom component! </div>'
——})
1.对于自定义标签的命名Vue.js 不强制遵循W3C规则(小写,并且包含一个短杠),尽管这被认为是最佳实践。
2.组件在注册之后,便可以作为自定义元素<my-component></my-component>在一个实例的模板中使用。
局部组件:(属于实例中的一个对象,在compones中的都是局部组件)
——通过某个Vue实例/组件的实例选项components注册仅在其作用域中可用的组件。
——var Child = {templa: '<div>A custom component!</div>'}
——new Vue({
——components: {
——// <my-component>将只在父组件模板中可用
——'my-component':Child
——}
——})
(1)实例中创建(首字母大写,严格区分语义化,高版本区分字母的大小写,)
(2)单文件去创建,后缀名是.vue
单文件组件
1.全局组件缺点
-全局定义(Global definitions)强制要求每个component 中的命名不得重复。
-字符串模板(String templates)缺乏语法高亮,在HTML有多行的时候,需要用到丑陋的。
-不支持CSS (No CSS support)意味着当HTML 和JavaScript组件化时,CSS明显被遗漏。
-没有构建步骤(No build step)限制只能使用HTML和ES5JavaScript,而不能使用预处理器,如 Pug (formerly Jade)和Babel.(只能用es5来写,不能使用less、less等)。
2.定义:文件扩展名为.vue 的 single-file components(单文件组件)
优势:
(1)完整语法高亮.
(2)CommonJS模块(cmd).
(3)组件作用域的CSS.
dom模板的注意事项
DOM模板遵循html代码规范;首先是先完成挂载,再完成动态内容;
Template模板是不受限制的,data必须是函数,redux可以使用全局的变量。
组件组合:
在Vue中,父子组件的关系可以总结为prop 向下传递,事件向上传递。父组件通过prop给子组件下发数据,子组件通过事件给父组件发送消息
prop传递数据
-prop是父组件用来传递数据的一个自定义属性。
-父组件的数据需要通过props把数据传给子组件,子组件需要显式地用props选项声明"prop"
-如果使用DOM模板时,驼峰命名的props的名称要转为短横分隔命名
-如果数据是来自父级的动态数据,可以使用指令v-bind来动态绑定props的值,当父组件发生变化时,也会传递给子组件。
-vue2.x和vue1.x,较大的改变是vue2通过Props传递数据是单向的,也就是父组件变化时会传给子组件,但是反过来不行。vue1里提供了.sync修饰符来支持双向绑定.
■父子组件传值
-父组件可以使用props 把数据传给子组件
-子组件可以使用$emit触发父组件的自定义事件
Vm.$emit( event,arg) //触发当前实例上的事件
· vmSon(event, fn )//监听event事件后运行fn(通常接受emit传递过来的自定义事件)
·注:传值命名时全部小写(vue新版本大小写不敏感)
非父子组件通信
-非父子通信有两种,兄弟组件好跨多级组件
- vue1.x通过$dispathch0和$broadcast()向上级派发事件,只要是它父级(一级或多级以上),都可以在vue实例的events选项中接受.
- vue2x废除了上面的两个方法。通过空的vue实例作为中央事件总线.
- vue2.x写法也适合vue1.x
1.父亲通过自定义属性传给儿子,
2.儿子接受:通过props属性(通常用数组方式)接收父亲的属性名
3.动态属性用v-bind,静态属性用v-on来绑定。
1.父传子
用props来接收参数,props是数组形式。
index.html:
<!doctype html>
<html>
<head>
<title>VUE练习</title>
<link rel="stylesheet" href="./css/index.css" type="text/css">
</head>
<body>
<div id="e">
<App message="我是父亲的值"></App>
<App1></App1>
<App2></App2>
<App3></App3>
</div>
<script src="./bundle.js"></script>
</body>
</html>
App.vue:
<template>
<div class="app1">
<h2>{{message}}</h2>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
text: ''
}
},
props:["message"],
methods:{
}
}
</script>
<style scoped>
.app1 {
width: 100%;
height: 100px;
background: rgb(240, 141, 141);
}
</style>
最终效果图:
2.子传父
通过emit调用父亲传来的自定义事件,把儿子计算后num作为参数传给父亲
App.vue:
<template>
<div class="app1">
<h2>{{ message }}</h2>
<input type="button" value="加一" v-on:click="add" />
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
text: "",
num: 0,
};
},
props: ["message"],
methods: {
add: function () {
this.num++; //儿子自己计算num值
this.$emit("addclick", this.num); //通过emit调用父亲传来的自定义事件,把儿子计算后num作为参数传给父亲
},
},
};
</script>
<style scoped>
.app1 {
width: 100%;
height: 100px;
background: rgb(240, 141, 141);
}
</style>
index.html:
<!doctype html>
<html>
<head>
<title>VUE练习</title>
<link rel="stylesheet" href="./css/index.css" type="text/css">
</head>
<body>
<div id="e">
<App message="我是父亲的值" v-on:addclick="getnum"></App>
{{sum}}
<App1></App1>
<App2></App2>
<App3></App3>
</div>
<script src="./bundle.js"></script>
</body>
</html>
index.js:
import _ from 'lodash';
import Vue from 'vue';
import App from './App.vue';
import App1 from './A1.vue';
import App2 from './A2.vue';
import App3 from './A3.vue';
new Vue({
el: "#e",
data: {
sum: 0,
},
methods: {
getnum: function (n) {
this.sum = n;
}
},
components: { App, App1, App2, App3 },
// template: '<App />'//不写会覆盖原来的内容,写的话会插入到原来的内容里面
})
最终效果图:(点击按钮,下面的数值就会增加)
3.子传子
index.html:
<!doctype html>
<html>
<head>
<title>VUE练习</title>
<link rel="stylesheet" href="./css/index.css" type="text/css">
</head>
<body>
<div id="e">
<App message="我是父亲的值" v-on:addclick="getnum"></App>
<App1 v-bind:message1="sum"></App1>
<App2></App2>
<App3></App3>
</div>
<script src="./bundle.js"></script>
</body>
</html>
A1.vue:
<template>
<div class="app1">
<p>{{ message1 }}</p>
</div>
</template>
<script>
export default {
name: "App1",
data() {
return {
text: "",
};
},
props: ["message1"],
};
</script>
<style scoped>
.app1 {
width: 100%;
height: 100px;
background: rgb(134, 238, 143);
}
</style>
最终效果图:
4、非父子组件传值
A1.vue:
<template>
<div id="content1">
A1
<input type="button" value="传值" v-on:click="postmsg" />
</div>
</template>
<script>
import bus from "./bus";
export default {
name: "A1",
data() {
return {};
},
methods: {
postmsg: function () {
bus.$emit("sclick", "A1");
},
},
};
</script>
<style >
</style>
A2.vue:
<template>
<div id="content1">
A2中A1的传值: {{message}}
</div>
</template>
<script>
import bus from "./bus.js";
export default {
name: "A2",
data() {
return {
message: "",
};
},
mounted: function () {
var _s = this;
//在实例化时,监听来自bus实例的事件
bus.$on("sclick", function (msg) {
_s.message = msg;
});
},
};
</script>
<style >
</style>
bus.js:
import Vue from 'vue';
var bus = new Vue();
export default bus;
最终效果图:
传值:
1.超链接传值.
2.表单.
3.react中cookie和local story.
4.路由传值.
5.redux(数据多,大).
6.单独的vue实例去传值.(非父子之间的传值).