vue学习回顾第三天
2018-12-03 本文已影响0人
xinhongwu
Vue组件
组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。所有的 Vue 组件同时也都是 Vue 的实例,所以可接受相同的选项对象 (除了一些根级特有的选项) 并提供相同的生命周期钩子。
组件的创建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./vue2.js"></script>
</head>
<body>
<!--模板要在不受vue控制的地方创建-->
<template id="three">
<div>方式3通过模板</div>
</template>
<!--模板的第二种使用方式-->
<script type="x-template" id="three2">
<div>模板的另一种使用方式</div>
</script>
<div id="app">
<!--组件的使用与HTML标签一样-->
<index-a></index-a>
<index-b></index-b>
<index-c></index-c>
<index-d></index-d>
</div>
</body>
<script>
// 注意:1. 模板template中只能有一个根节点;2. 组件的名字,如果采用驼峰命令的话,在使用的时候,就要加上 “-”,比如组件名字叫indexA,那么在使用的时候就叫index-a
// 第一种:使用Vue.extend()和Vue.component()两个方法创建
// Vue.extend()函数会返回一个组件的构造器,它里面包含一个参数,它是一个对象,里面是一些配置项
// Vue.component()函数会利用Vue.extend()返回的构造器创建一个组件的实例,它有两个参数,一个是组件的名字,另一个组件的构造器
let Index=Vue.extend({
template:"<div>我是首页</div>"
});
//第一个参数为组件名字,第二个为组件构造器
Vue.component("indexA",Index);
//方式二创建组件:使用Vue.component()创建,本质上还是调用vue.extend()方法
Vue.component("indexB",{
template:"<div>第二种方式创建</div>"
});
//第三种方式创建
//通过指定模板创建,适用于模板内容特别多的时候
Vue.component("indexC",{
template:"#three"
});
Vue.component("indexD",{
template:"#three2"
});
let vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
组件中使用事件和指令
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>组件中使用事件和指令</title>
<script src="vue2.js"></script>
</head>
<body>
<div id="app">
<click></click>
</div>
</body>
<script>
//注册组件
// 构造 Vue 实例时传入的各种选项大多数都可以在组件里使用,但注意data必须是一个函数
Vue.component("click",{
template:"<div>{{msg}}<button @click='change'>改变</button></div>",
//data必须是一个函数
data(){
return{msg:"hello"
}
},
methods:{
change(){
this.msg="world"
}
}
})
let vm=new Vue({
el:'#app',
data:{
}
})
</script>
</html>
父子组件
- 父子组件的创建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父子组件的创建</title>
<script src="vue2.js"></script>
</head>
<body>
<div id="app">
<father>
</father>
<!-- <son></son>错误用法,子组件在父组件中使用-->
</div>
</body>
<script>
//创建父组件
Vue.component("father",{
//子组件要在父组件中使用
template:'<div>我是父组件<son></son></div>',
//通过components创建子组件
components:{
//son就是子组件的名字
son:{
template:"<div>我是子组件</div>"
}
}
})
let vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
- 组件之间的传值
1父组件传值给子组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>子组件获取父组件中的值</title>
<script src="vue2.js"></script>
</head>
<body>
<div id="app">
<father></father>
</div>
</body>
<script>
Vue.component("father",{
// 2. 在使用子组件的地方,通过v-bind指令给子组件中的props赋值
template:'<div>我是一个父亲,我儿子的名字叫{{mySonName}}<p><son :myName="mySonName"></son></p></div>',
data(){
return{
mySonName:"小明"
}
},
components:{
son:{
// 1. 声明props,它的作用是:用来接收从父组件传递过来的值
// props可以跟一个数组,数组里面的值是一个一个的字符串,这个字符串可以当成属性来使用
props:['myName'],
template:'<div>我是儿子,我爸爸给我起名叫{{myName}}</div>'
}
}
});
let vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
2 子组件传值给父组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父组件获取子组件中的值</title>
<script src="vue2.js"></script>
</head>
<body>
<div id="app">
<father></father>
</div>
</body>
<script>
Vue.component("father",{
//通过监听事件获取数据
template:'<div>我是爸爸,我儿子告诉我他的名字是{{mySonName}}<p><son @tellMyName="getMySonName"></son></p></div>',
data(){
return{
mySonName:""
}
},
methods:{
//获取子组件上传的数据,默认参数代表子组件上传的数据
getMySonName(data){
this.mySonName=data;
}
},
components:{
son:{
template:'<button @click="emitMyName">告诉我父亲我的名字</button>',
data(){
return{
myName:"小花"
}
},
methods:{
//传递数据给父组件使用$emit方法,有两个参数,一个是事件名,另一个是要传递的数据
emitMyName(){
this.$emit("tellMyName",this.myName)
}
}
}
}
})
let vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
3 兄弟组件之间传值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>兄弟组件之间传值</title>
<script src="vue2.js"></script>
</head>
<body>
<div id="app">
<father>
</father>
</div>
</body>
<script>
//1 创建一个空的vue实例,作为事件总线
let eventBus=new Vue();
Vue.component("father",{
template:`<div>父组件
<son></son>
<daughter></daughter>
</div>`,
components:{
son:{
data(){
return{
mySisterName:""
}
},
template:`<div>我妹妹的名字叫{{mySisterName}}</div>`,
mounted(){
// 3 通过eventbus的$on()方法去监听兄弟节点发射过来的事件
//两个参数,事件名称和回调函数,参数就是传过来的数据
eventBus.$on('tellBroMyName',data=>{
this.mySisterName=data;
})
}
},
daughter:{
data(){
return{
myName:"小红"
}
},
template:`<button @click="emitMyName">点击就告诉哥哥我的名字叫{{myName}}</button>`,
methods:{
emitMyName(){
//2 通过事件总线的$emit方法发送一个事件和传递的数据
eventBus.$emit("tellBroMyName",this.myName)
}
}
}
}
})
let vm=new Vue({
el:"#app",
data:{
}
})
</script>
</html>
动态组件
<body>
<div id="app">
<ul>
<li @click="currentCom='index'"><a href="#">首页</a></li>
<li @click="currentCom='productType'"><a href="#">蔬菜</a></li>
<li @click="currentCom='productType'"><a href="#">水果</a></li>
<li @click="currentCom='productType'"><a href="#">肉类</a></li>
</ul>
<!-- 利用component标签创建动态组件,它的is属性指向谁,就显示哪个组件 -->
<component :is="currentCom"></component>
</div>
<script>
// 首页组件
Vue.component('index', {
template: '<div>首页</div>'
})
Vue.component('productType', {
template: '<div>这里显示商品编号</div>'
})
var vm = new Vue({
el: '#app',
data: {
currentCom: ''
}
})
</script>
</body>
局部过滤器和局部指令
<body>
<div id="app">
<one></one>
<two></two>
</div>
<script>
// 全局自定义指令可以在任何组件中使用
Vue.directive('mycolor', {
inserted(el, binding) {
console.log(binding);
// binding.value可以获取传入自定义指令中的属性的值
el.style.color = binding.value
}
})
// 不管是局部自定义指令还是局部过滤器都只能在当前组件内使用,脱离当前组件无效
// 局部过滤器通过在组件内部使用filters属性创建
Vue.component('one', {
data () {
return {
time: new Date(),
color: 'red'
}
},
template: `
<div>
<p>{{time | fmtTime}}</p>
<input type="text" v-mycolor="color">
</div>
`,
//filters创建局部过滤器
filters: {
fmtTime(time) {
console.log(time);
var y = time.getFullYear();
var m = time.getMonth() + 1;
var d = time.getDate();
return y + '/' + m + '/' + d
}
}
})
// 局部自定义指令通过在组件内部使用directives属性创建
Vue.component('two', {
data () {
return {
time: new Date(),
color: 'red'
}
},
template: `
<div>
<p>{{time}}</p>
<input type="text" v-myfocus v-mycolor="color">
</div>
`,
directives: {
myfocus: {
inserted(el, binding) {
console.log(el);
console.log(binding);
el.focus()
}
}
}
})
var vm = new Vue({
el: '#app',
data: {
}
})
</script>
</body>
生命周期钩子
<body>
<div id="app">
<p>{{info}}</p>
<button @click="info='hello1'">更新info</button>
<button @click="destroy">销毁实例</button>
</div>
<script>
var myVm = new Vue({
el: "#app",
data: {
info: "hello"
},
// 在实例初始化之后,数据观测 (data observer) 和 event/watcher 配置之前被调用。
beforeCreate: function () {
console.log("===============beforeCreate============================================")
// $el表示Vue 实例使用的根 DOM 元素。
console.log('$el', this.$el);
// $data Vue 实例观察的数据对象
console.log('$data', this.$data);
console.log("info:", this.info)
},
// 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,dom还未生成,$el 属性目前不可见。
created: function () {
console.log("===============created=======================================")
console.log('$el', this.$el);
console.log('$data', this.$data);
console.log("info:", this.info)
},
// 模板编译挂载之前调用,首先会判断对象是否有el选项。如果有的话就继续向下编译,如果没有el选项,则停止编译,也就意味着停止了生命周期,直到在该vue实例上调用vm.$mount(el)。接着判断是否有template属性,有的话就以template属性中的值作为模板,如果没有的话,就以el属性指向的作为模板。这里会生成vm.$el,但指令尚未被解析
beforeMount: function () {
console.log("===============beforeMount=========================================")
console.log('$el', this.$el);
console.log('$data', this.$data);
console.log("info:", this.info)
},
// 模板编译挂载之后调用,vm.$el替换掉el指向的dom
mounted: function () {
console.log("===============mounted===========================================")
console.log('$el', this.$el);
console.log('$data', this.$data);
console.log("info:", this.info)
},
// 数据变更导致虚拟DOM重新渲染之前调用
beforeUpdate: function () {
console.log("===============beforeUpdate============================================");
},
// 数据变更导致虚拟DOM重新渲染之后调用
updated: function () {
console.log("===============updated======================================================");
},
// 实例销毁之前调用,在这一步,实例完全可用
beforeDestroy: function () {
console.log("===============beforeDestroy===============================================")
console.log('$el', this.$el);
console.log('$data', this.$data);
console.log("info:", this.info)
},
// vue实例指向的所有东西解除绑定,包括watcher、事件、所以的子组件,后续就不再受vue实例控制了
destroyed: function () {
console.log("===============destroyed================================================")
console.log('$el', this.$el);
console.log('$data', this.$data);
console.log("info:", this.info)
},
methods: {
destroy() {
// 表示销毁组件
this.$destroy()
},
udpateinfo() {
this.info = 'hello2'
}
}
})
</script>
</body>