Vue.js备忘记录(二) {{}}, 指令 ,v-bind, watch监听浏览器本地存储, 路由状态切换

一. 模板语法

1. 文本

<span>Message: {{ msg }}</span>

msg属性发生了改变,插值处的内容都会更新。

如果只想更新一次: v-once

<span v-once>这个将不会改变: {{ msg }}</span>

2. HTML

双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用f="https://cn.vuejs.org/v2/api/#v-html">v-html指令

例如:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <p>Using mustaches: {{ rawHtml }}</p>
        <!-- 这个会被解析成文本 -->
        <p><span v-html='rawHtml'></span></p>
        <!-- 这个会被解析成HTML -->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                rawHtml:'<span style="color: red;">this should be red</span>'
            },
        })
    </script>
</body>

</html>

3.绑定标签属性

Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用f="https://cn.vuejs.org/v2/api/#v-bind">v-bind指令

<div  v-bind:id="dynamicId"></div>

对于布尔 attribute (它们只要存在就意味着值为true),v-bind工作起来略有不同,在这个例子中:

<button  v-bind:disabled="isButtonDisabled">Button</button>

如果isButtonDisabled的值是null、undefined或false,则disabledattribute 甚至不会被包含在渲染出来的<button>元素中。

4. {{}} 和v-bind其实都可以用JavaScript表达式

有个限制就是,每个绑定都只能包含单个表达式

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

-------------------------------------------------------------------------------------
<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}

<!-- 流控制也不会生效,请使用三元表达式 -->
{{ if (ok) { return message } }}

二. 指令

指令 (Directives) 是带有v-前缀的特殊 attribute。比如: v-on v-if v-bind 等等

<p  v-if="seen">现在你看到我了</p>

1. 参数

一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind指令可以用于响应式地更新 HTML attribute

<a  v-bind:href="url">...</a>  

在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。

另一个例子是 v-on 指令,它用于监听 DOM 事件:

<a v-on:click="doSomething">...</a>

2.修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():


<form  v-on:submit.prevent="onSubmit">...</form>

3.v-bind

v-bind是Vue中绑定属性的指令 (M到V的单向绑定)


<!-- 完整语法 -->  
<a  v-bind:href="url">...</a>  
<!-- 缩写 -->  
<a  :href="url">...</a>

4. v-on


<!-- 完整语法 -->  
<a  v-on:click="doSomething">...</a>  
<!-- 如果需要传参 -->  
<a  v-on:click="doSomething(arg)">...</a>  
<!-- 缩写 -->  
<a  @click="doSomething">...</a>

v-on这种写法只是提供了便捷的绑定事件方式,并没有改变原生的JS事件,所以所有的原生JS事件都是支持的

事件参考​developer.mozilla.org
图标

v-on可以绑定多个事件,当绑定多个事件时,需要传入一个对象,对象的键名就是事件名,对象的键值就是对应事件要执行的方法。


<div class="app">
    <button v-on="{mouseenter:onenter,mouseleave:leave}">click me</button>
</div>    

如果调用的函数需要触发事件对象,可以直接形参接收,默认就传


<a  v-on:click="doSomething">...</a> methods: {
        doSomething(e) {   
          console.log(e);
        }
      },

如果调用的函数有参数,同时需要触发事件对象,如何接收? 此时触发事件必须用$event传入

<button  @click=doSomething(reslut,$event)>OK</button> methods: {
        doSomething(arg,e) {   
          console.log(arg);
          console.log(e);
        }
      },

5. v-text

v-text是绑定文本数据的另一种形式,

但在浏览器渲染方面略有不同,因为通常都是window onload之后vue才会接管

v-text 确保 vue出问题时也不会把{{xxx}}显示出来,快速刷新也不会闪屏

<h1>{{msg}}</h1>  
<h1  v-text=msg></h1>

6. v-cloak

v-text比较麻烦,{{}}又怕出丑,有没有一举两得的方法呢??? 有啊 v-cloak

v-cloak写在vue入口组件上,它会伪装一个样式,让浏览器将错误隐藏掉

在下面的例子中,#app组件上 加载了v-cloak 它可以被浏览器视为一个带有v-cloak属性的标签, 那么我们为带有v-cloak属性的标签设计一个样式,使其隐藏起来

当vue接管页面后,它会识别v-cloak 组件,并重新渲染出来

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>

<body>
    <div id="app" v-cloak>
        <h1>{{msg}}</h1>
        <h1>{{msg}}</h1>
        <h1>{{msg}}</h1>
        <h1 v-text=msg></h1>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            data: {
                msg: 'hello'
            }
        }).$mount('#app')

    </script>
</body>

</html> 

7.v-pre //跳过该组件的编译

跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。


<div  v-pre>{{ this will not be compiled }}</div>

咋一看仿佛没有什么意义,其实它是为了加快Vue对网页解析渲染速度.

上例中如果div里面是无数的图片和文字的一篇新闻稿,那Vue完全应该跳过对他们的渲染,因为他们都是原生html而已,,有了v-pre,Vue会跳过他们,都不看任何一眼.

8.v-once //只绑定一次

<p  v-once>{{msg}}</p> //即使是双向数据绑定,也只修改一次

9.v-html //将内容按照html解析


<div  v-html="url"></div> 
在data中:  url:'<a  href="https://www.baidu.com">百度一下</a>'

三. v-bind绑定样式

1. 绑定class

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用v-bind处理它们

我们可以传给 v-bind:class 一个对象,以动态地切换 class:


<div  v-bind:class="{ active: isActive }">
</div>

比如:我们设计一个样式,当todo.done为true时触发这个样式,

    <style>
        .done{
            text-decoration: line-through;
            color: #aaa;
        }
    </style>

当todo.done为true时触发这个样式,则


<span v-bind:class="{done:todo.done}">{{todo.title}}</span>

class里传入一个对象,其实是个键值对,对象的键名就是class类名,键值是一个布尔值,布尔值为真时,执行这个样式,布尔值为假,不执行这个样式.

2. 数组语法

我们可以把一个数组传给v-bind:class,以应用一个 class 列表:


<div  v-bind:class="[activeClass, errorClass]"></div> data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

渲染为:


<div  class="active text-danger"></div>

如果你也想根据条件切换列表中的 class,可以用三元表达式:


<div  v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

不过,当有多个条件 class 时这样写有些繁琐。所以在数组语法中也可以使用对象语法:


<div  v-bind:class="[{ active: isActive }, errorClass]"></div>

我们可以即为class传入普通类名,同时传入数据绑定对象


<h1 :class=['red','thin',{'italic':isItalic}]></h1>

3.绑定内联样式

v-bind:style的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:


<div  v-bind:style="{  color: activeColor,  fontSize: fontSize + 'px'  }"></div> data: {
  activeColor: 'red',
  fontSize: 30
}

鉴于它其实是对象,干脆写成对象: 这会让模板更清晰


<div  v-bind:style="styleObject"></div> data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

v-bind:style的数组语法可以将多个样式对象应用到同一个元素上


<div  v-bind:style="[baseStyles, overridingStyles]"></div>

四. 不用双向数据绑定来获取input标签的内容

我们知道,如果我们用双向数据绑定获得input的内容时,还需要一个中间变量


<input  class="new-todo"  placeholder="What needs to be done?"  autofocus  v-on:keyup.enter="handleIn"  v-model="add"> var app = new Vue({
        el: ".todoapp",
        data: {
            add:'',
        },
        methods: {
            handleIn(){
                const addTodo={
                    done:false,
                    seen:true
                }
                addTodo.title=this.add  
                                //需要中间变量过度以下以防一个数据源绑定多条数据,如下图
                todos.push(addTodo)
                this.add=''             
            })

第四条是我新增的数据

增加第五条时,第四条也变了,因为双向绑定

上面的情况,可以通过局部中间变量的过渡解决,那么双向数据绑定还有什么意义?

所以,建议通过获取调用方法的元素的方式解决

调用方法时,方法会默认传入一个参数,event

我们用编写方法时接收这个event

 handleIn(e){
                console.log(e);         
            },

此时,我们得到一个event对象

查看对象属性,我们发现有一个target属性,其实就是调用这个方法的input

查看target的属性,我们发现有个value格外显眼,这就是我们想要的内容~所以

上面的程序可以弃用双向数据绑定,改用查询DOM属性的方式

 handleIn(e){
                todos.push({
                    title:e.target.value,
                    done:false,
                    seen:true
                })
                                this.add=''     
            },

以此类推,如果input是checkbox, 我们可以去target中找checked

注意:上面的方法我们都用了一个参数叫event,但如果调用函数里面有形参,这个参数是无法获取的,如果想既传参又传event 则需要在调用时强烈的声明!!!!并在写函数时做好形参接收工作!

<input class="new-todo" 
placeholder="What needs to be done?" 
autofocus v-on:keyup.enter="handleIn(index,$event)" 
v-model="add">

handleIn(index,e){

}

五. watch监听浏览器本地存储

1.浏览器本地存储

window.localStorage.setItem(键,值)

浏览器本地存储必须是键值对,且值为字符串,如果我们存储对象,则:

window.localStorage.setItem("a",JSON.stringify(obj))

2.浏览器取值

window.localStorage.setItem(键,值)

如果取得是对象,需要转换一下

JSON.parse(window.localStorage.getItem(键))

3.应用在vue里,我们本地存储一个对象叫todos,每次vue接管时取出

    data: {
        todos: JSON.parse(window.localStorage.getItem('todos')||'[]'),
    },

4.如何存储???

我们对数据操作这个频繁,难道要每个位置添加存储语句吗?

更理想的方法是监听内存中的Vue对象的todos属性的变化

因为todos是一个对象, 所以我们需要深度监听

    watch: {
        todos:{
            handler(){
                console.log('jilule')
                window.localStorage.setItem('todos',JSON.stringify(this.todos))
            }
        },
        deep:true,
    }

六. 路由状态切换

举例:我们想点击底下的3个按钮切换上面的显示内容 我们需要做那些工作?

  • 获取路由状态

  • 将状态与Vue对象联系起来

  • 按条件渲染上面的页面

  1. 获取路由状态

我们知道浏览器有一个onhashchange方法可以判断url的哈希值

window.onhashchange=function (){
    console.log(window.location.hash);
}

2. 将状态与Vue对象联系起来

window.onhashchange = function () {
    var hashv = window.location.hash
    switch (hashv) {
        case '#/':
            this.app.filterText = 'all'
            break;
        case '#/active':
            this.app.filterText = 'undone'
            break;
        case '#/completed':
            this.app.filterText = 'done'
            break;
        default:
            break;
    }
}
window.onhashchange()

注意一个问题:

此方法只有在页面哈希值变化时才变化,如果我们第一次打开页面,将app的filterText 改为undone,关闭页面在打开时,不会触发window.onhashchange,所以会显示 #/页面,但此时app的filterText其实是undone. 所以我们需要在加载页面时执行一次window.onhashchange()

3. 使用计算属性 将要显示的列表显示出来

列表渲染 —https://cn.vuejs.org/v2/guide/list.html#%E6%98%BE%E7%A4%BA%E8%BF%87%E6%BB%A4-%E6%8E%92%E5%BA%8F%E5%90%8E%E7%9A%84%E7%BB%93%E6%9E%9C

<div  v-for="(todo, index) in filterTodos" :key="index" v-show=todo.seen >

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