Vue-留言列表

一:该例使用到的知识点

效果图:在这里插入图片描述

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}}:&nbsp;&nbsp;</span><span v-else>{{item.name}}:回复@{{list[index-1].name}}&nbsp;&nbsp;</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>

猜你喜欢

转载自blog.csdn.net/qq_35176916/article/details/84988831
今日推荐