Vue 模板、指令与修饰符

Vue的模版语法

我们把HTMl模版叫做template。

template的3种写法

1' Vue完整版,写在HTML里

html
<div id=xxx>
  {{n}}
  <button @click="add"> + 1 </button>
</div>

new Vue({ //把html变成DOM节点
  el:'#xxx',
  data:{n:0}, //data可以改成函数
  methods:{
    add(){}
  }
})

2' Vue完整版,写在选项里

<div id='app'>
</div>

new Vue({
  template:`
  <div>
  {{n}}
  <button @click="add"> + 1 </button>
  </div>
  `,
  data:{n:0}, //data可以改成函数
  methods:{ add(){ this.n +=1 } }
}).$mount('#app')

注意细节:
(1)div#app会被替代
new Vue({})运行后,template里面的<div>会替换掉页面的<div id='app'>,渲染完后就没有id='app'<div>了。
(2) el:'#xxx'可以替换成new Vue({}).$mount('#app')

3' Vue非完整版,配合xxx.vue文件

第1步.写xxx.vue文件
<template>
  <div> //这里一般不需要id,id一般是用来挂载的,这里不需要
    {{n}}
    <button @click="add">
      +1
    </button>
  </div>
</template>
注意:<template>里面不是HTML而是 XML
<script>
  export default { //默认导出一个选项(构造选项)
    data(){ return {n:0} },//data必须为函数,这个函数返回的对象就是我们要用的data
    methods:{add(){ this.n += 1 }}
  }
</script>
<style>
  这里写 CSS 
</style>

第2步.在另外一个地方写如下代码
import Xxx from './xxx.vue' 
//首字母大写防冲突,Xxx是一个options对象
new Vue({
  render: h => h(Xxx) //Xxx传给Vue的render函数
  }).$mount('#app')

Xxx就是导出的对象 export default { 对象 }

HTML与XML的区别:
XML书写更严格:所有空标签都可以直接闭合,比如<div />,必须写/。
因此XMl语法更容易写编译器。

模版里有哪些语法?

一.展示内容

1.表达式

{{ object.a }} 表达式。data里面的object.a
{{ n+1 }} 可以写任何运算。但不支持if...else
{{ fn(n) }} 可以调用函数。默认在methods里找叫fn的函数,并传了参数n
当值是`undefined 或 null`时,它就什么都不展示,它不会显示undefined和
null,这是Vue的特殊处理。
另一种写法为<div v-text="表达式"></div> 很少有人用

2.HTMl内容

指令v-html="",支持内容里有html标签。

假设data.x值为<strong>hi</strong>
<div v-html="x"></div>即可显示粗体的hi
3.我就想在页面中展示{{n}}怎么办?

<div v-pre> {{ n }} </div> //v-pre不会对模版进行编译

二.绑定属性

1.绑定字符串
绑定src:<img :src="x" />
补充:<img v-bind:src="x" />其中v-bind:可以简写为:
2.绑定对象

<div
 :style="{border:'1px solid red',height:100}">
</div>
//注意在这里可以把'100px'写成100
//补充:JS中100就是100px div.style.height=100 //'100px'
//这种写法会在div上写一个内联样式

三.绑定事件 v-on

v-on就是在什么时候触发事件。

v-on:事件名
[图片上传失败...(image-a9684b-1649271111233)]
缩写<button @click=""add> +1 </button>

四.条件判断 v-if

<div v-if="x>0">
  x大于0
</div> 
<div v-else-if="x===0">
  x为0
</div> 
<div v-else>
  x小于0
</div> 

v-if是什么时候出现在DOM树里。

五.循环 v-for

for(value,key)in 对象或数组
注意:每一个v-for必须有:key="" 绑定一个变量,不写就会有警告!

数组的例子
<ul>
  <li v-for="(u,index) in users" :key="index"> 
    索引:{{index}} 值:{{u.name}}
  </li>
</ul>

对象的例子
<ul>
  <li v-for="(value, name) in obj" :key="name">
    属性名:{{name}},属性值:{{value}}
  </li>
</ul>

六.显示、隐藏 v-show

<div v-show="n%2===0"> n是偶数 </div>
//表达式如果是真的就显示<div>,负责就不显示<div>。if...else的简化版
//如果是假的<div>就不会出现在页面

v-show是什么时候展示出来,是通过css隐藏的。

七.v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 有子元素 -->
<div v-once>
  <h1>comment</h1>
  <p>{{msg}}</p>
</div>
<!-- 组件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
  <li v-for="i in list" v-once>{{i}}</li>
</ul>

总结

Vue模版主要特点有
1.使用XML语法(不是HTML)
2.使用{{}}插入表达式
3.使用v-html、v-on、v-bind等指令操作DOM
4.使用v-if、v-for等指令实现条件判断和循环

指令与修饰符

一.指令Directive
1.什么是指令
v-开头的东西就是指令。
2.语法
[图片上传失败...(image-ec6998-1649271111233)]

<a @click.prevent href="">百度</a>

二.修饰符

用来修饰一个指令的就叫修饰符,比如.prevent
有些指令支持修饰符,但有些不支持,看文档。
[图片上传失败...(image-5fcfa2-1649271111233)]

1.添加修饰符
v-on支持的修饰符最多,比如.keycode
需求:如果用户打回车就单独给它个逻辑。

new Vue({
  template: `
  <div>
    <input @keypress.13="y"/> 
<!--<input @keypress.enter="y"/>-->  
  </div>
  `,
  methods: {
    y(e) {
      console.log(e);
      console.log("用户打了回车键"); 
    }
  }
}).$mount("#app");
<input @keypress.13="y"/>或者<input @keypress.13=y /> 

2.缩写alias
键盘编码难记可以用缩写alias,查看支持的按键码

 <input @keypress.enter="y"/> //给13取个别名enter

[图片上传失败...(image-70e4f3-1649271111233)]

上面这几个都不用记编码,可以直接用别名。

事件修饰符.self(很少用)
用户点的元素正好是你监听的那个元素才会触发,如果是元素里面的元素不会触发。

知识点
1.事件
input输入事件
只要输入东西到input里都会触发事件<input @input="y"/>
keypress键盘按下事件
只要按下键盘就会触发事件y <input @keypress="y"/>
2..prevent阻止默认动作

<a @click.prevent='x' href="https://www.baidu.com/">百度</a>

3..stop阻止事件传播/冒泡

@click.stop='add'

.sync 修饰符(重要)

main.js
// 此处是非完整版vue
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue
<template>
  <div class="app">
    App.vue 我现在有 {{total}}
    <hr>
    <Child :money="total" v-on:update:money="total = $event"/>
  //<Child :money.sync="total" />
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  data() {
    return { total: 10000 };
  },
  components: { Child: Child }
};
</script>

<style>
.app {
  border: 3px solid red;
  padding: 10px;
}
</style>

Child.vue 
//子组件
<template>
  <div class="child">
    {{money}}
    <button @click="$emit('update:money', money-100)">
      <span>花钱</span>
    </button>
  </div>
</template>

<script>
export default {
  props: ["money"]
};
</script>

<style>
.child { border: 3px solid green; }
</style>

解析:
1.main.js渲染了App,App是个组件。
2.App.vue
红色边框是App组件。
<Child />是子组件从文件Child.vue来的,import Child from "./Child.vue"; 使用时要声明下components: { Child: Child }告诉它总金额就1万total: 10000再多没有。
3.Child.vue
<Child />需要接收这笔钱,props: ["money"]外部数据money,所以App.vue<Child :money="total" />把总金额告诉Child.vue。

当点击button时就是要花钱,花的是他爸的钱(操作外部数据)所以不能<button @click="money -=100">自己操作数据。
MVC章节讲过订阅发布系统eventBus,Vue内置了eventBus,所以我们可以使用当前实例this,this就是当前实例,当前实例继承了eventBus,所以它可以触发一个事件。所以@click="this.$emit",因为在Vue template里this可以删掉所以<button @click="$emit('useMoney',money-100)">

他爸就要监听他儿子要不要钱,如果发现儿子触发了我要钱,那就把他花的钱赋值给我的data的total,那我怎么知道儿子给我的钱是多少呢?尤雨溪把这个值存到变量上,你只要使用这个就可以了,这个变量就是$event。原理:把它的那个值先存到我的组件$event上,用时自己取。所以App.vue<Child :money='total' v-on:useMoney = "total = $event"/>
尤雨溪规定要把事件名改为'update:money'
有人在<Child/>上调用了on,有人在<Child/>上调用了$emit,这就是事件的发布和订阅。

这种方法很常见,v-on:update:money = "total = $event"监听事件(update:money)获取$event,所以被封装成了修饰符.sync
写法

<Child :money.sync='total'/>
//等于<Child :money='total' v-on:useMoney = "total = $event"/>

.sync这种写法就是一个语法糖或者API糖。

总结

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

推荐阅读更多精彩内容