组件和表单的基本使用
v-model
用于数据的双向绑定
你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
原理
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
text 和 textarea 元素使用 value property 和 input 事件;
checkbox 和 radio 使用 checked property 和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="box">
<input type="text" v-model = 'msg'><br>
<p>{{ msg }}</p>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#box',
data(){
return {
msg:"come on let's do it"
}
},
})
</script>
</body>
</html>
全局组件的使用
全局组件在任何地方都可以直接使用,不用挂载
// 定义全局组件
Vue.component('xxx',{ // 第一个参数为组件的名字,第二个参数为组件的内部的属性
data(){},
methods:{},
template:`xxx` //组件的模板,用于渲染数据
})
new Vue({ // 当vue对象里有el和template时,template的优先级高于el,所以template会优先显示
el:'xx',
...
template:`<xxx/>`
})
局部组件的使用
口诀:定子,挂子,用子
// 定义局部组件
let App = {
...
template:`balabala`
}
new Vue({
...
components:{
App // 挂子,当key和value都一样时,可以只写key
}
template:`<App/>` // 用子
})
切记:模板里必须要有一个根元素,不然会报错
slot 内容分发
<slot> 元素作为组件模板之中的内容分发插槽。<slot> 元素自身将被替换。
<alert-box>
Something bad happened. // 插槽的内容
</alert-box>
Vue.component('alert-box', {
template: `
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot> // 占位符
</div>
`
})
父往子传值
通过props 和在子组件绑定相关的属性进行传值
let Vsub = { //定义子组件
data(){
return {}
},
props:['title'],// 获取父组件传来的值
template:`
<div>{{ title }}</div> // 使用值
`
}
let Vbase = {
data(){
return {
myTitle:'hello world'
}
},
components:{ //加载子组件
Vsub
},
template:`
<Vsub :title = 'myTitle'></Vsub> //通过模板绑定属性来传值
`
}
子往父传值
1.给子组件中的某个按钮绑定原声事件,。我们可以调用内建的 this.$emit('自定义的事件名','传递的数据'),来向父级组件触发一个自定义的事件.
2.在父组件中的子组件标签中 要绑定自定义的事件,
let Vsub = { //定义子组件
data(){
return {
text:'wohsinibaba'
}
},
template:`
<button @click = 'clickHandler'>不会吧</button> //在子组件定义事件
` ,
methods:{
clickHandler(){
this.$emit('passValue',this.text) //发送相关的数据到父组件
}
}
}
let Vbase = {
data(){
return {
myTitle:'hello world'
}
},
components:{ //加载子组件
Vsub
},
template:`
<Vsub @passValue='getValue'></Vsub> //父组件在子组件定义自定义事件,不能与内置的事件冲突
`,
methods:{
getValue(value){ // 在方法中获取子组件传来的值
alert(value)
}
}
}
new Vue({
el:'#box',
components:{
Vbase
},
template:`<Vbase/>`
})
平行组件的传值
平行组件的传值不同于父子之间的传值,需要通过一个公共的组件引导进行传值
需要用$emit(声明的事件名,传递的值)和$on(绑定的事件名,function接受的值)来绑定和传送.
注意:绑定和传送的对象都必须是同一个
let Vbus = new Vue()
Vue.component('Demo',{
data(){
return{
num:1
}
},
template:`<button @click = 'clickHandler'>{{ num }}</button>`,
methods: {
clickHandler() {
this.num++
Vbus.$emit('passValue', this.num) //发送相关的数据到父组件
}
}
})
Vue.component('Demo1',{
data(){
return{
text:null
}
},
created(){
Vbus.$on('passValue',(val)=>{
this.text = val
})
},
template:`<span>{{ text }}</span>`
})
new Vue({
el:'#box',
data() {
return {}
},
template:`<div><Demo/><Demo1/> // 要在该处使用平行的组件
</div>
`
})