一、模板template的三种写法
第一种写法,Vue完整版,写在.html里
引入vue的完整版
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
<!-- 引入vue的完整版 -->
</body>
.html
<div id = xxx>
{{n}}
<button @click="add">+1</button>
</div>
以下代码把上述<div>变成含有n的值的dom节点,写在main.js里面
new Vue({
el: "#xxx",//挂载点
data:{n:0},//data 可以改成函数
methods:{add(){}}
})
第二种写法,Vue完整版,写在选项里new Vue(options)
.html
<div id=app>
<!-- 这一部分内容写在new Vue的template``里面 -->
</div>
main.js
new Vue({
template:`
<div id = xxx>
{{n}}
<button @click="add">+1</button>
</div>
`
//注意一个细节:div#app被替代为template里面的div
data:{n:0},//data 可以改成函数
methods:{add(){this.n +=1}}
}).$mount("#app")
注意一个细节:div#app被替代为template里面的div
'.$mount("#app")'是element的替换写法
第三种写法,Vue非完整版,配合xxx.vue文件
引入vue的运行时版
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
<!-- 引入vue的运行时版 -->
</body>
xxx.vue里的<template>标签
<template>
<div >
<!-- div 不需要写 id = xxx -->
<!-- id是用来让其他元素挂载到我这里,而这里的div已经是内容,不需要被挂载,所以不需要写id -->
{{n}}
<button @click="add">+1</button>
</div>
</template>
id是用来让其他元素挂载到我这里,而这里的div已经是内容,不需要被挂载,所以不需要写id。
<template> </template>里面不是HTML,而是XML语法。
因为XML语法代替松散的HTML,更容易写编译器,写出的解析器体积更小一些。
HTML和XML的区别
<input name = "username"> -HTML
<input name = "username" /> -XML
<div></div> -HTML
<div /> -XML
xxx.vue里的<script>标签
<script>
export default {
//不需要再写template
data(){ return {n:0}},
//这里的环境是组件xxx.vue,所以data必须是函数;data函数返回一个data对象。
methods:{add(){this.n += 1}}
}
<script>
<style> 这里写 css </style>
在main.js里面导入组件xxx.vue
import Xxx from "./xxx.vue"
//Xxx 是一个 options 对象//组件Xxx首字母一般大写,防止与原生组件冲突
new Vue({
render: h => h(Xxx)
//把Xxx组件传给Vue的render函数
}).$mount("#app")
二、template里面重要的语法
template:是用来表示HTML结构的字符串。
展示内容-template里面的内容三种展示方法如下:
1、表达式:{{展示里面的内容}}
new Vue({
template:`
<div id = xxx>
{{object.a}}//把构造选项options的data{}里面的object.a显示到HTML里面
{{ n + 1 }}//任何运算
{{不支持写if else}}//vue不认识if else语句
如果值为undefined或null就不显示
</div>
`
}).$mount("#app")
{{}}表达式的另一种写法为<div v-text= '表达式'> </div>
2、HTML内容:允许展示内容显示html标签效果
hi
假设 data.x 值为 <strong>hi</strong>
<div v-html = 'x'></div>即可显示粗体的hi
3、展示包括花括号在内的内容 {{ n }}
<div v-pre>{{ n }}</div>
v-pre 不会对template内容进行编译。
绑定属性v-bind
<img v-bind:src = 'x' /> //绑定src
<img :src='x' /> //可省略v-bind
<div
:style='{border: '1px solid red', height:100}'>
<!-- 这里可以把'100px'写成100 -->
</div>
绑定事件v-on
<button v-on:click="add">+1</button>
//点击之后,Vue会运行add()
<button v-on:click="xxx(1)">xxx</button>
//点击之后,Vue会运行xxx(1)
缩写
<button @click="add">+1</button>//v-on缩写为@
template语法总结
Vue模板主要特点:
- 使用XML语法
- 使用{{}}插入表达式
- 使用v-html v-on v-bind等指令操作DOM(这些声明式编程会被vue转化为DOM操作指令,即命令式编程)
- 使用v-if v-for等指令实现 条件判断 和 循环
- v-show实现显示或隐藏
<div v-show="n%2===0">n 是偶数 </div>
//近似等于
<div :style = "{display:n%2===0?'block':'none'}"> n 是偶数 </div>
//注意:显示的元素display不只有block
//table的display为table
//li的diplay为list-item
命令式编程:
div.innerHTML = x//在div里面插入一个x
img.src = x
button.onclick = add
声明式编程:
<div v-html = 'x'></div>//div里面有一个x
<img :src=x />
<button @click = 'add'/>
三、指令与修饰符
指令
v-on:click
v-bind:src
v-model
v-if
v-for
还没有讲的指令
- v-model
- v-slot
- v-cloak
- v-once
修饰符
指令后面可以接修饰符
@click.stop = "add"//表示阻止事件传播/冒泡
@click.prevent = "add"//表示阻止默认动作
@click.stop.prevent = "add"//同时表示两种意思
重点了解 .sync 修饰符(同步数据)
项目示例 codesandbox.io/s/boring-td…
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.sync="total"/>
//等价于<Child :money="total" v-on:update:money = "total = $event"/>
//"Child :money='total' "表示组件App.vue给子组件Child.vue传一个变量money='total'
//规定必须用"update:money"来表示事件名
//"update:money"是一个字符串,中间没有空格
//也就是,我把数据money传给你,但是你子组件Child.vue要改的话要通知我App.vue来改,子组件不能自己改
//v-on用于监听
//$event用于获取$emit('update:money',money-100)后面的参数"money-100",$event是一个单独的变量,不属于this。
//$event将触发事件后变化的参数"money-100",传回给total,total再传回给"update:money"
//然后组件App.vue再将变化后的变量money='total'传回给子组件Child.vue
//由于<Child :money="total" v-on:update:money = "total = $event"/>语句太长,于是封装了一个修饰符'.sync'来简化代码
//即把"total -> money -> 'money-100' -> $emit -> $event -> total -> money"这样一个数据闭环简写为.sync
</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)">
<!-- <button @click="this.$emit('update:money', money-100)"> -->
//在vue.template里面,this表示当前实例,当前实例继承了eventbus,可以触发事件。
//在vue.template里面,不要写this.直接用$emit
<span>花钱</span>
</button>
</div>
</template>
<script>
export default {
props: ["money"]
};
</script>
<style>
.child {
border: 3px solid green;
}
</style>
回顾知识点1、eventbus
eventBus主要用于对象间通信。它使得M和V,C互相不知道对方的细节,但是却可以调用对方的功能。即满足最小知识原则。 详见 juejin.cn/post/684490…
回顾知识点2、$emit
在项目中,自定义了一个组件App.vue,在点击子组件Child.vue时,触发选中事件,并通过$emit,将子组件的数据传递给父组件。
<button @click="$emit('update:money', money-100)">
//在点击子组件时,触发选中事件
Vue规则(不用问为什么,直接使用)
- 组件不能修改props外部数据(比如Child.vue不能修改App.vue传给它的money数据)
this.$emit可以触发事件,并传参$event可以获取$emit的参数
<Child :money.sync="total"/>
//等价于<Child :money="total" v-on:update:money = "total = $event"/>
什么叫语法糖?
.sync这种写法叫语法糖,API糖,因为使用起来很甜,像吃糖一样。
重点记忆四个修饰符
@click.stop="xxx"
@click.prevent="xxx"
@keypress.enter="xxx"
:money.sync="total"
更多修饰符参见: