一:该例使用到的知识点
效果图:
1. 注意子组件引用时名称的书写方式 eg:
Vue.component(‘vInput’,{}), 这里子组件名称为vInput, 则引用时需要这样书写:
<v-input :username="username" v-model="username" v-focus='jujiao' ref="names"></v-input>
否则会报错: make sure to provide the ‘name’ option
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181213140413196.png)
2:v-model的用法:
v-model是数据双向绑定,对于自定义的input标签应该这样实现:
一:template模板下:
(1)对于子组件 :1,模板中需要注册input事件,2,需要动态绑定value,3,通过$emit(‘input’,’’)将数据传递给父组件。
其中value对应子组件的value值,也是input输入框的值。
Vue.component('vTextarea',{
template: `<textarea placeholder='请输入留言内容' @input="uContent" :value="value"></textarea>`,
props: ['message','value'],
data: function () {
return {
dmessage: this.message
}
},
methods: {
uContent: function (event) {
this.$emit('input', event.target.value)
}
},
});
(2):然后v-model进行接收该数据。其实v-model= v-on:input=“fucnction(){}”,代码如下:
content对应父类的data中content变量
<v-textarea :message="content" v-model="content" ></v-textarea>
二:对于render函数v-model数据双向绑定如下:
需要设置的地方有两个 1:domprops 2:on,
render: function (createElement) {
var _this = this;
return createElement('textarea',{
domProps: {
value: this.value // 这就相当于 :value="value"
},
on: {
input: function(event){ // 子组件的input方法
_this.value = event.target.value;
_this.$emit('input',event.target.value); //传递给父类
}
}
})
},
(2):然后调用子组件:
<v-textarea v-model="message" ref="message"></v-textarea>
三:避免 v-if与v-for用于同一元素,这样 可能会导致v-else失效
四:父子组件之间的访问
父类访问子组件 如果代码如下:
子组件设置ref
<v-input :username="username" v-model="username" v-focus='jujiao' ref="names"></v-input>
template:`<div><input type='text' @input="uName" :value="value" ><span></span></div>`,
父类应该这样访问:
console.log(this.$refs.names) //VueComponent{}对象
console.log(this.$refs.names.$el.children[0]) // <input type='text'>
下面这张图可以说明一切:
4:所以父类控制子组件聚焦可以用以下代码:
this.$refs.names.$el.children[0]:focus()
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>留言板template模板实现</title>
</head>
<body>
<!-- 万物皆组件 -->
<div id="app">
<div>
<v-input :username="username" v-model="username" v-focus='jujiao' ref="names"></v-input>
<v-textarea :message="content" v-model="content" ></v-textarea>
<button @click="addInfo">发布</button>
<v-list :list="list" @okl="handle"></v-list>
</div>
</div>
<script src="vue.js"></script>
<!-- 存在重复无用的代码,主要是为了测试功能 -->
<script>
//input组件 v-model=“ **” ,这里是父元素 注册用驼峰式的写法,引用-
Vue.component('vInput',{
template:`<div><input type='text' @input="uName" :value="value"><span></span></div>`, //这里方法如果加括号就会报错 ,,v-model的几种实现方式
props:['username','value','jujiao'],
data: function () {
return {
name: this.username
}
},
methods: {
uName: function (event) {
this.$emit('input', event.target.value)
},
},
})
//textarea组件
Vue.component('vTextarea',{
template: `<textarea placeholder='请输入留言内容' @input="uContent" :value="value"></textarea>`,
props: ['message','value'],
data: function () {
return {
dmessage: this.message
}
},
methods: {
uContent: function (event) {
this.$emit('input', event.target.value)
}
},
});
//留言板组件
Vue.component('vList',{
//v-if与v-for应避免用在同一元素上, 本例应用后v-esle不起作用了
template: `<div><div v-if="vlist!==0"><p v-for="(item,index) in list"><span v-if="item.hui=== false">{{item.name}}: </span><span v-else>{{item.name}}:回复@{{list[index-1].name}} </span><span>{{item.message}}</span></p><button @click="hufu()">回复</button></div><div v-else><p>开始你的留言吧</P></div></div>`,
props:['list'],
data: function () {
return {
vlist: this.list.length,
}
},
methods: {
hufu: function () {
//与父组件通信
this.$emit('okl')
//input聚焦
// var a = document.getElementsByTagName('input')[0]
// a.focus();
}
},
watch: {
list: function () {
//props属性是与父类同步的,但是data属性却不同步,需要进行监听props属性的变化,来更新data数据
this.vlist = this.list.length
}
},
})
var app = new Vue ({
el: '#app',
data:{
username:'',
content:'',
biaoji: false, // 为了实现留言板的两种文字方式,name: name : @name
list:[],
jujiao: ''
},
methods: {
//发布按钮的功能
addInfo: function () {
if (this.username === '') {
alert ('用户名不能为空')
return
}else if (this.content==='') {
alert ('内容怎么能不写呢')
return
}
this.list.push({
name: this.username,
message: this.content,
hui: this.biaoji
});
this.content='';
this.username='';
this.biaoji=false;
this.jujiao = false;
},
handle: function(){
this.jujiao = true
this.biaoji = true;
// this.$refs.names.$el.focus()
console.log(this.$refs.names.$el.children[0])
}
},
//iuput模板首次插入时触发自定义指令
directives:{
focus: {
inserted: function (el, value) {
if (value) {
el.focus()
}
}
}
}
})
</script>
</body>
</html>