Vue基础学习笔记02-实现markdown实时

接着上篇博客地址 简书地址 继续

class与style绑定

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

绑定class

对象表示

可以用对象来表示,active类的有无取决于isActive的truthiness

<div id="app" v-bind:class="{ active: isActive }">
        <p @click='changeActive'>{{msg}}</p>
        
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                isActive: true
            },
            methods:{
                changeActive(){
                    this.isActive = !this.isActive;
                    
                }
            },
        })
    </script>

这个例子:点击p标签会触发changeActive事件,从而切换isActive的布尔值,达到active类添加和删除的效果。

绑定计算属性

可以将class绑定在计算属性中,class中的对象也可以定义在data中的

<style type="text/css">
        .active{
            background-color: rgb(127,199,211);
        }
        
    </style>
<div id="app" v-bind:class="ActiveClass">
        <p @click='changeActive'>{{msg}}</p>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                isActive: true
            },
            computed:{
                ActiveClass(){
                    return {active:!this.isActive}
                }
            }
        })
    </script>

数组表示

对象语法是用一个对象来表示,key为类名,value则为布尔值控制该类是否可以显示。而数组方式是把类名添加到数组中,从而添加该类。

<style type="text/css">
        .active{
            background-color: rgb(127,199,211);
        }
        .myCenter{
            text-align: center;
        }
    </style>
<div id="app" v-bind:class="classList">
        <p @click='changeActive'>{{msg}}</p>
        
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                classList: []
            },
            methods:{
                changeActive(){
                    this.classList.push("active");
                    this.classList.push("myCenter")
                }
            },
            
        })
    </script>

该例,点击p标签触发绑定事件changeActive从而将active和myCenter push到classList变量中,v-bind:class因为classList变化从而渲染类的效果。

还可以把对象嵌入到数组中交叉运用。

内联样式绑定

可以直接绑定class,当然可以也可以对style样式做手脚了。

对象语法

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。

<div id="app" >
        <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">{{msg}}</div>

    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                activeColor: 'rgb(127,199,211)',
                fontSize: 30
            },  
        })
    </script>

可以直接绑定到一个对象上,如这样

<div id="app" >
        <div v-bind:style="styleObj">{{msg}}</div>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                styleObj:{
                    color: 'rgb(127,199,211)',
                    fontSize: '30px'
                }
            },
        })
    </script>

数组语法

这个就是把上面的对象添加到数组中

<div id="app" >
        <div v-bind:style="[styleObj, ]">{{msg}}</div>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                styleObj:{
                    color: 'rgb(127,199,211)',
                    fontSize: '30px'
                }
            },
        })
    </script>

条件渲染

上篇基础博文中初步讲过v-if的使用,这里再来记录一些

v-if

简单if,还有else,当然了还有else-if,必须要紧挨着才能识别

<div id="app" >
        <div v-if="status == 'good'">{{'if分支' + status}} </div>
        <div v-else-if="status == 'bad'">{{'else-if分支' + status}} </div>
        <div v-else="status == 'verygood'">{{'else分支' + status}} </div>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                status: 'good'
            },
            
        })
    </script>

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>

用key管理可复用元素

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

<div id="app" >
        <template v-if="loginType === 'username'">
          <label>用户名</label>
          <input placeholder="Enter your username">
        </template>
        <template v-else-if="loginType === 'email'">
          <label>邮箱</label>
          <input placeholder="Enter your email address">
        </template>
        <button @click='toggleType'>切换</button>
        
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                loginType: 'username',
                typeList:['username', 'email']
            },
            methods:{
                toggleType(){
                    index = this.typeList.indexOf(this.loginType);
                    if (index === this.typeList.length-1) {
                        this.loginType = this.typeList[0];
                        return;
                    }else{
                        this.loginType = this.typeList[index + 1];
                    }
                }
            },
            
        })
    </script>

该例子中输入在input框中的内容将不会被清除,从而重用,直接显示label和input的placeholder值。

这是key不显示设置唯一才生效的,如果显式设置两个key不唯一,则在切换的时候会清除input框内容

<template v-if="loginType === 'username'">
          <label>用户名</label>
          <input placeholder="Enter your username" key='username-input'>
        </template>
        <template v-else-if="loginType === 'email'">
          <label>邮箱</label>
          <input placeholder="Enter your email address" key='email-input'>
        </template>

模板这样修改就会清除input框了,但是label还是会重用的!

v-show

v-show也可以根据条件来展示元素的,但是和v-if不同的是,它只是简单的切换元素的css属性display而已,在页面载入时,已经被渲染,但是根据条件可能没有显示,而if是完全惰性的,真正条件渲染。

这个是上面if的例子,用show改写,注意show没有if

<div id="app" >
        <div v-show="status">{{msg}} </div>
        
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                status: false
            },      
        })
    </script>

初始设置为false,则载入页面时,我们将看不到div中的msg变量内容,但是整个dom元素中是存在的

show

注意:v-show 不支持 <template> 元素,也不支持 v-else

v-if和v-show

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

事件处理

监听事件

上节笔记中记录过v-on的相关用法,v-on还可以缩写为@

这个例子以click事件为例

    <div id="app" >
        <div>{{msg + count}} </div>
        <button @click='addCount'>点击count加1</button>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                count: 0,
            },
            methods:{
                addCount(){
                    this.count += 1;
                }
            }
            
        })
    </script>

methods中是定义函数的地方,上例子中的addCount其实为addCount:function(){},这里运用es6单例模式写法。

v-on:click='count + 1'这样直接做操作也是可以的

传值

    <div id="app" >
        <div>{{msg + count}} </div>
        <button @click='addCount(5)'>点击count加1</button>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                count: 0,
            },
            methods:{
                addCount(num){
                    this.count += num;
                }
            }
            
        })
    </script>

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

    <div id="app" >
        <div>{{msg + count}} </div>
        <button @click='addCount($event)'>点击count加1</button>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                msg: 'I will be better',
                count: 0,
            },
            methods:{
                addCount(event){
                    this.count += 1;
                    console.log(event);
                }
            }
            
        })
    </script>

事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

按键修饰符

在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">

记住所有的 keyCode 比较困难,所以 Vue 为最常用的按键提供了别名:

<!-- 同上 -->
<input v-on:keyup.enter="submit">

<!-- 缩写语法 -->
<input @keyup.enter="submit">

全部的按键别名:

  • .enter
  • .tab
  • .delete (捕获“删除”和“退格”键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

表单输入绑定

使用v-model可以做到数据和元素双向绑定,在表单等输入控件内输入内容,会自动更新数据渲染元素。其本质不过是语法糖。

支持以下表单元素:

  • <input>
  • <textarea>
  • <select>

文本框input

    <div id="app" >
        <input v-model='message'>
        <p>{{message}}</p>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                message: 'I will be better',
            },
        })
    </script>

封装前实现方式

v-model可以简单实现这个效果,但其实是语法糖(官网是说了),用绑定事件方法还是可以实现的,如下面

    <div id="app" >
        <input @input='changeValue($event)'>
        <p>{{message}}</p>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                message: 'I will be better',
            },
            methods:{
                changeValue(event){
                    this.message = event.target.value;
                    console.log(event.target.value);
                }
            }
        })
    </script>
input实现方法

多行文本textarea

    <div id="app" >
        <textarea v-model='message'></textarea>
        <p>{{message}}</p>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                message: 'I will be better',
            },
        })
    </script>

复选框

直接多个复选框吧,要绑定到一个数组

    <div id="app" >
        <input type="checkbox"  value="Jack" v-model="message">
          <label for="jack">Jack</label>
          <input type="checkbox"  value="John" v-model="message">
          <label for="john">John</label>
          <input type="checkbox"  value="Mike" v-model="message">
          <label for="mike">Mike</label>
          <br>
          <span>Checked names: {{ message }}</span>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                message: [],
            },
        })
    </script>
vuemodel.jpg

单选框

上例改变

    <div id="app" >
        <input type="radio"  value="Jack" v-model="message">
          <label for="jack">Jack</label>
          <input type="radio"  value="John" v-model="message">
          <label for="john">John</label>
          <input type="radio"  value="Mike" v-model="message">
          <label for="mike">Mike</label>
          <br>
          <span>Checked names: {{ message }}</span>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                message: '',
            },
        })
    </script>

选择框

还是上面的例子,继续改变

    <div id="app" >
        <select v-model='message'>
            <option>Jack</option>
            <option>John</option>
            <option>Mike</option>
        </select>
          <span>Checked names: {{ message }}</span>
    </div>
    <script src="vue.min.js"></script> 
    <script>
        var App = new Vue({
            el:"#app",
            data:{
                message: '',
            },
        })
    </script>

修饰符

.lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转变为使用 change事件进行同步:

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >

.number

如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

<input v-model.number="age" type="number">

这通常很有用,因为即使在 type="number" 时,HTML 输入元素的值也总会返回字符串。如果这个值无法被 parseFloat() 解析,则会返回原始的值。

.trim

如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

<input v-model.trim="msg">

markdown实时效果

利用v-model可以简单实现markdown书写实现效果,当然我们要引入markdown的语法解析js。其实markdown就是提供了我们简单的语法,然后转换成HTML代码加上部分的样式。

我这里不用import的方法引入了,直接引入js文件

marked:https://www.npmjs.com/package/marked

npm中解析markdown的包

渣渣代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue基础</title>
    <style type="text/css">
        #app{
            top:0;
            bottom: 0;
            left: 0;
            right: 0;
            position: absolute;
        }
        .markleft{
            height: 100%;
            width: 50%;
            float: left;
        }
        textarea{
            height: 100%;
            width: 100%;
            background: black;
            color: white;
            overflow: scroll;
            font-family: 'Monaco', 'Menlo';
            
        }
        .showright{
            height: 100%;
            width: 50%;
            float: right;
            overflow: scroll;
            
        }
    </style>
</head>
<body>
    <div id="app" >
        <div class="markleft">
            <textarea v-model='message'></textarea>
        </div>
        <div class="showright" v-html='marked(message)'></div>
    </div>
    <script src="vue.min.js"></script> 
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
    <script>

        var App = new Vue({
            el:"#app",
            data:{
                message: 'I will be better',
            },
            methods:{
                changeValue(event){
                    this.message = event.target.value;
                    console.log(event.target.value);
                }
            }
        })
    </script>
</body>
</html>
markdown
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • vue概述 在官方文档中,有一句话对Vue的定位说的很明确:Vue.js 的核心是一个允许采用简洁的模板语法来声明...
    li4065阅读 7,185评论 0 25
  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,044评论 0 29
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,982评论 4 129
  • 1. Vue 实例 1.1 创建一个Vue实例 一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实...
    王童孟阅读 1,013评论 0 2
  • 最近好忙好忙,忙的不记得日期,给自己放了一天假,出来跟朋友释放疯癫,看了比利林恩,立马情绪被带进了另一个画风,当下...
    SophiaC阅读 206评论 0 0