这几天刚学习vue ,组件化这块相比于前面稍微有一点难度,前期的话看了许多人的视频,但都没有从底层讲起,所以很难理解。不过这两天有了灵感 。
组件化的概念
Web 中的组件其实就是页面组成的一部分,好比是电脑中的每一个元件(如硬盘、键盘、鼠标),它是一个具有独立的逻辑和功能或界面,同时又能根据规定的接口规则进行相互融合,变成一个完整的应用,页面就是有一个个类似这样的部分组成,比如导航、列表、弹窗、下拉菜单等。页面只不过是这些组件的容器,组件自由组合形成功能完善的界面,当不需要某个组件,或者想要替换某个组件时,可以随时进行替换和删除,而不影响整个应用的运行。
组件化的优点
提高开发效率
方便重复使用
简化调试步骤
提升整个项目的可维护性
便于协同开发
下面这个例子是使用vue数据双向绑定和vue组件化实现的tolist的小demo
<div id='root'>
<input v-model='inputvalue'>
<button @click='handleclick'>提交</button>
<tolist v-for='item of list' :content=item></tolist>
</div>
//局部的组件,
var Tolist = {
props: ['content'], //将表单里面的值传递至该组件中。
template: '<li>{{content}}</li>', //父传子的方式就是通过父标签传递vue里面的值给儿子
}
new Vue({
el: '#root',
data: {
inputvalue: '',
list: []
},
components: {
'tolist': Tolist
},
methods: {
handleclick: function() {
this.list.push(this.inputvalue);
this.inputvalue = '';
}
}
})
下面这段代码主要讲的是局部组件和全局组件的关系!然后需要注意的地方都在旁边注释了!
<div id='app'>
<hello-World></hello-World>
<hello-World></hello-World>
<hello-World></hello-World>
</div>
//全局组件,意味着只要挂在了,就可以直接使用。局部组件则意味着只有该局部区域有效。
Vue.component('HelloWorld', {
data: function() {
return { //在全局组件中data使用函数,不能在直接对象,因为函数有自己的作用域,
msg: 'hello' //在后期可以单独操作我们的模块
}
},
template: `
<div>
<button @click='handleClick'>点击</button>
<h1>{{msg}}</h1>
</div>
`,
methods: {
handleClick: function() {
this.msg = 'change' //这里的this为该全局组件
}
}
})
new Vue({
el: '#app',
components: {
'helloWorld': {
template: `<div>nihaoa</div>` //局部组件 当局部组件和全局组件重合时,则使用全局组件
}
}
})
需要注意的就是当局部组件和全局组件名重合时,局部组件其作用!
下面这段代码是父组件给子组件传递数据以及子组件如何传递数据到父组件的实例
<div id='app'>
<mycontent v-bind='childINFO' @add='handadd'></mycontent>
<button @click='handleChange'>点击我告诉你我是谁</button>
</div>
let vim = new Vue({
el: '#app',
data: {
childINFO: {
title: '我是谁',
content: '',
number: 0
}
},
methods: {
handadd: function(num) {
this.childINFO.number = num; //这里用于接收子组件传递的值。
},
handleChange: function() {
this.childINFO.content = '我是任佳磊'
}
},
components: {
'mycontent': {
props: {
title: {
type: String, //组件接收属性值的时候可以在这个属性里面进行校验!
default: '任佳磊最帅'
},
content: {
required: true, //必须是父组件传值!
/* validator(val) {
return val > 10000; //返回一个布尔值!
} */
},
number: {
type: Number //不接收父组件的值子组件是用不了这些值的。
}
}, //给子组件传递数据,需要用props属性将上面父组件的值接收下来
template: `
<div>
<h1>{{title}}</h1>
<h1>{{content}}</h1>
<h1>{{number}}</h1>
<h1>{{mynumber}}</h1>
<button @click=handleClick>点击我加一</button>
</div>
`,
data: function() {
return {
mynumber: this.number //将从父组件接收到的值私有化,如果不私有化,这里改变,其余用到父组件值得地方也会改变!
}
},
methods: {
handleClick: function() {
this.mynumber++;
this.$emit('add', this.mynumber) //这里用于向父组件传递值,该函数第一个参数是自定义的事件名,
}, //用于监听子组件是否改变。其余参数都是传递的值。
}
}
}
})
这块需要注意的是如果子组件没有私有化父组件传递下来的数据,则改变子组件里面的值会对父组件里面的值造成影响!
底下这段代码是ref的一个引用实例,也就是在方法里面去引用标签的 方法,比较简单
let vim = new Vue({
el: '#app',
data: {
name: 'renjialei'
},
methods: {
click: function() {
console.log(this.$refs.sss.colors) //这里的$refs相当于是hello这一个组件的实例
}
},
components: {
hello: {
data: function() {
return {
colors: ['green', 'black', 'pink'] //只要有ref引用在底下都可以打印出来
}
},
template: `
<div>
<button v-for="key in colors" :style={backgroundColor:key} @click=handleClick(key) >{{key}}</button>
<div class='s' ref='square'></div>
</div>`,
methods: {
handleClick: function(color) {
let square = this.$refs.square; //以对象形式返回上面的refs的实例
square.style.backgroundColor = color; //现有style属性
},
}
}
}
})