vue实现双向绑定其他元素以及自定义表单控件

更新日期: 2018-04-20 阅读: 3.8k 标签: 控件

之前我们学过用 v-model 进行双向数据绑定:

<div id="root">
    <textarea class="textarea" v-model="comment"></textarea>
</div>

<script>

    var vm = new vue({
        el:"#root",
        data:{
            comment:"这是一条评论"
        }
    });

</script>


而且,提到过,v-model 只能用于表单控件,如果用于其他元素,比如 p:

<p contenteditable="true" v-model="comment"></p>


那么就会报错:

v-model is not supported on this element type. If you are working with contenteditable, it's recommended to wrap a library dedicated for that purpose inside a custom component.

它会提示用 custom component,即自定义组件。在使用自定义组件之前,先来看看 v-model 的另外一种等价写法:

<textarea :value="comment" @input="comment = $event.target.value"></textarea>


该过程很好理解,首先,动态绑定输入控件的 value 属性到 comment 变量上,然后对 input 事件进行监控,实时同步 comment 的值。

如果用这种写法,就可以对 p 等元素进行双向绑定了。由于 p 元素没有 value 属性,可以使用 v-text 或者插值:

<p contenteditable="true" @input="comment = $event.target.innerText">{{ comment }}</p>

或者:

<p contenteditable="true" v-text="comment" @input="comment = $event.target.innerText"></p>


现在,我们对评论的内容进行过滤,效果如下:


可以使用自定义组件,比如:

<comment v-model="comment"></comment>


如何让组件的 v-model 生效呢?需要按照 Vue 的约定:

  1. 接受一个 value 属性

  2. 在有新的 value 时触发 input 事件


跟我们之前的写法类似:

Vue.component('comment',{
    props:['value'],
    template:`
        <textarea :value="value" @input="filterComment($event.target.value)"></textarea>
    `,
    methods: {
        filterComment(comment){
            this.$emit('input',comment)
        }
    }
});


这样就可以实现简单的双向绑定了,而且我们可以在 filterComment 方法中定义过滤规则:

filterComment(comment){
    var filterRst = (comment.indexOf('敏感词') >= 0 ? comment.replace(\敏感词\g,"河蟹") : comment);
    this.$emit('input',filterRst)
}


完整示例:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/vue/2.2.6/vue.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.1/css/bulma.css">
</head>
<body>
    <div id="root" class="container">
        <comment v-model="comment"></comment>
    </div>

    <script>
        Vue.component('comment',{
            props:['value'],
            template:`
                <textarea class="textarea" :value="value" @input="filterComment($event.target.value)"></textarea>
            `,
            data(){
                return {
                    sensitiveList:['包子','蛤蛤'],
                    replaceWord:'河蟹'
                }
            },
            methods: {
                filterComment(comment){
                    var that = this;
                    this.sensitiveList.forEach(function(word){
                        var regex = new RegExp(word,'g');;
                        comment = (comment.indexOf(word) >= 0 ? comment.replace(regex,that.replaceWord) : comment);
                    })
                    this.$emit('input',comment)
                }
            }
        });
    
        var vm = new Vue({
            el:"#root",
            data:{
                comment:'这是一条评论'
            }
        });
    </script>
</body>


转载来源:https://segmentfault.com/a/1190000009225098

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/article/detial/681

Vue实现Tab控件

使用Vue实现Tab功能。创建一个tab.vue文件,内容如下:其中change方法和tabs需要父组件中定义,tabs的格式如下:为确保正确渲染,id需要保证唯一性。

Flutter 之基本控件

Flutter 中有很多 UI 控件,而文本、图片和按钮是 Flutter 中最基本的控件,构建视图基本上都要使用到这三个基本控件;文本是视图系统中的常见控件,用于显示一段特定样式的字符串

element ui tree控件父节点和子节点之间的关联问题

问题描述:当需改的时候如果父节点为选中状态子节点不是全选中这样会显示为子节点为全选中状态;在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false ;

Flutter 设置控件是否可见

共有两种实现比较简单的方式,第一种比较好理解,将一个控件的透明度设置成0,打到隐藏的目的。第二种办法是使用 SDK 自带的 Offstage 控件包裹。

B/S端开发工具DevExtreme Angular控件 - 常见功能

服务器端渲染 (SSR) 在服务器上生成静态页面来减少应用程序的加载时间。SSR 仅用于 Angular Universal 应用程序,但对于 DevExtreme 组件,Angular Universal 和普通 Angular 应用程序没有区别

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!