目录
mustache是胡须的意思,因为{{}}像胡须,又叫大括号语法。
在vue对象挂载的dom元素中,{{}}不仅可以直接写变量,还可以写简单表达式。
- <body>
- <div id="app">
- <h2>{{message}}h2>
- <h2>{{message}},worldh2>
-
- <h2>{{firstName+'-'+lastName}}h2>
- <h2>{{firstName}}-{{lastName}}h2>
- <h2>{{firstName+lastName}}h2>
- <h2>{{count*2}}h2>
- div>
- <script>
- Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
- const vm = new Vue({
- el: '#app',
- data(){
- return{
- message: 'hello',
- firstName:'zhang',
- lastName:'san',
- count:2
- }
- }
- })
- script>
- body>

开发中常用的数组有许多数据,需要全部展示或者部分展示,在原生JS中需要使用for循环遍历依次替换div元素,在vue中,使用v-for可以简单遍历生成元素节点。
- <div id='app'>
-
- v-for="数组或对象中的每一个值 in/of 数组或对象本身"
-
-
-
-
-
-
-
- <h2 v-for="item of obj2">{{item.a}}{{item.b}}{{item.c}}h2>
-
- <ul>
- <li v-for="item of obj2">{{item.a}}{{item.b}}{{item.c}}li>
- ul>
-
-
- <h2 v-for="(item,index) in todolists" :key="index">{{item}}--{{index}}h2>
-
- <h2 v-for="item in obj2" :key="item.id">{{item.a}}{{item.b}}{{item.c}}h2>
-
- div>
- <script>
- Vue.config.productionTip = false;
- const vm = new Vue({
- el: '#app',
- data() {
- return {
- todolists: ['篮球', '排球', '羽毛球', '足球'],
- obj: {
- a: '张三',
- b: '李四',
- c: '王五'
- },
- obj2: [{
- id:1,
- a: '张三'
- }, {
- id:2,
- b: '李四'
- }, {
- id:3,
- c: '王五'
- }]
- }
-
- }
- })
- script>
-
item表示当前遍历的元素,index表示元素索引, 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
因为它是 Vue 识别节点的一个通用机制,key 并不仅与 v-for 特别关联。
不要使用对象或数组之类的非基本类型值作为
v-for的key。请用字符串或数值类型的值。

使用vue实现一个小计数器,点击
+按钮,计数器+1,使用-按钮计数器-1。
定义vue对象并初始化一个变量count=0
定义两个方法
add和sub,用于对count++或者count--定义两个button对象,给button添加上点击事件
在vue对象中使用methods表示方法集合,使用
v-on:click的关键字给元素绑定监听点击事件,给按钮分别绑定上点击事件,并绑定触发事件后回调函数add和sub。也可以在回调方法中直接使用表达式。例如:count++和count--。
- <body>
- <div id="app">
-
-
-
- <button type="button" @click="add">+button>
- <h3>{{count}}h3>
- <button type="button" @click="sum">-button>
-
- div>
- <script>
- /* 点击事件
- v-on 监听事件
- */
- Vue.config.productionTip = false;
- new Vue({
- el: '#app',
- data() {
- return {
- count: 0
- }
- },
- methods: { //以后所有的vue中的方法都可以写在methods里面
- /* add:function(){
- // console.log('add');
- this.count++;
- },
- sub:function(){
- // console.log('sub');
- this.count--;
- } */
-
- add() {
- /* console.log(this); */
- this.count++;
- },
- sub() {
- this.count--;
- }
- }
- })
- script>
- body>

v-once表示该dom元素只渲染一次,之后数据改变,不会再次渲染。
- <body>
- <div id="app">
- <h2>{{msg}}h2>
-
- <h2 v-once>{{msg}}h2>
- div>
- <script>
- Vue.config.productionTip = false; //阻止 vue 在启动时生成生产提示。
- const vm = new Vue({
- el:'#app',
- data(){
- return {
- msg:'我就是这么倔强'
- }
- }
- })
- script>
- body>

上述{{msg}}的msg修改后,第一个h2标签数据会自动改变,第二个h2不会。
在某些时候我们不希望直接输出百度一下这样的字符串,而输出被html自己转化的超链接。此时可以使用v-html。
- <div id="app">
- <h2 v-html="url">h2>
- div>
- <script>
- const vm = new Vue({
- el:'#app',
- data(){
- return {
- url:"百度一下"
- }
- }
- })
- script>

v-text会覆盖dom元素中的数据,相当于js的innerHTML方法。
- <div id="app">
- <h2>不使用v-texth2>
- <h2>{{message}},啧啧啧h2>
- <h2>使用v-text,以文本形式显示,会覆盖h2>
- <h2 v-text="message">,啧啧啧h2>
-
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- const app = new Vue({
- el:"#app",
- data:{
- message:"你好啊"
- }
- })
- script>
如图所示,使用{{message}}是拼接变量和字符串,而是用v-text是直接覆盖字符串内容。

有时候我们期望直接输出{{msg}}这样的字符串,而不是被{{}}语法转化的msg的变量值,此时我们可以使用v-pre标签。
- <div id="app">
- <h2>不使用v-preh2>
- <h2>{{msg}}h2>
- <h2>使用v-pre,不会解析h2>
- <h2 v-pre>{{msg}}h2>
- div>
- <script>
- const vm = new Vue({
- el:'#app',
- data(){
- return {
- msg:'我比v-once还要厉害'
- }
- }
- })
- script>
结果如图,使用v-pre修饰的dom会直接输出字符串。

有时候因为加载延时问题,例如卡掉了,数据没有及时刷新,就造成了页面显示从{{message}}到message变量“你好啊”的变化,这样闪动的变化,会造成用户体验不好。此时需要使用到v-cloak的这个标签。在vue解析之前,div属性中有v-cloak这个标签,在vue解析完成之后,v-cloak标签被移除。简单,类似div开始有一个css属性display:none;,加载完成之后,css属性变成display:block,元素显示出来。
- <head>
- <meta charset="utf-8" />
- <title>v-cloak指令的使用title>
- <script src="js/vue.js" type="text/javascript" charset="utf-8">script>
- <style>
- [v-cloak] {
- display: none !important;
- }
- style>
- head>
-
- <body>
- <div id="app" v-cloak>
- <h2>{{msg}}h2>
- div>
- <script>
- //在vue解析前,div中有一个属性cloak
- //在vue解析之后,div中没有一个属性v-cloak
- setTimeout(() => {
- const vm = new Vue({
- el: '#app',
- data() {
- return {
- msg: '你好啊'
- }
- }
- })
- }, 1000)
- script>
- body>
这里通过延时1秒模拟加载卡住的状态,结果一开始不显示message的值,div元素中有v-cloak的属性,1秒后显示message变量的值,div中的v-cloak元素被移除。

某些时候我们并不想将变量放在标签内容中,像这样是将变量h2标签括起来,类似js的innerHTML。但是我们期望将变量{{msg}}
src写在如下位置,想这样导入图片是希望动态获取图片的链接,此时的src并非变量而是字符串src,如果要将其生效为变量,需要使用到一个标签v-bind:,像这样,而且这里也不能使用Mustache语法,类似,这也是错误的。
- <div id="app">
-
-
-
- <img v-bind:src="src" alt="">
- <a v-bind:href="url">a>
-
- <img :src="src" />
- <img :src="url" />
- div>
- <script>
- const vm = new Vue({
- el:'#app',
- data(){
- return {
- src:'https://cn.bing.com/thid=OIP.NaSKiHPRcquisK2EehUI3gHaE8&pid=Api&rs=1',
- url:'img/6.png'
- }
- }
- })
- script>
有时候我们期望对Dom元素的节点的class进行动态绑定,选择此Dom是否有指定class属性。例如,给h2标签加上class="active",当Dom元素有此class时候,变红,在写一个按钮绑定事件,点击变黑色,再次点击变红色。
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>v-bind动态绑定class(对象语法)title>
- <style>
- .active{
- color:red;
- }
- style>
- head>
- <body>
- <div id="app">
-
-
-
-
- <h2 class="title" :class="{active:isActive}">{{message}}h2>
- <h2 class="title" :class="getClasses()">{{message}}h2>
- <button @click="change">点击变色button>
-
- div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js">script>
- <script>
- const app = new Vue({
- el:"#app",
- data:{
- message:"你好啊",
- active:"active",
- isActive:true
- },
- methods: {
- change(){
- this.isActive = !this.isActive
- },
- getClasses(){
- return {active:this.isActive}
- }
- },
- })
- script>
- body>
- html>
定义两个变量active和isActive,在Dom元素中使用:class={active:isActive},此时绑定的class='active',isActive为true,active显示,定义方法change()绑定在按钮上,点击按钮this.isActive = !this.isActive,控制Dom元素是否有class='active'的属性。

使用v-for和v-bind实现一个小demo,将电影列表展示,并点击某一个电影列表时候,将此电影列表变成红色。
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Documenttitle>
- <script src="js/vue.js" type="text/javascript" charset="utf-8">script>
- <style>
- .active {
- color: #f00;
- }
- style>
- head>
- <body>
- <div id="app">
- <ul>
-
- <li v-for="(item,index) in movies" :key="index" :class="currentIndex==index?'active':''" @click="change(index)">{{item}}li>
- ul>
- div>
- <script>
- const vm = new Vue({
- el: '#app',
- data() {
- return {
- currentIndex: 0,
- movies: ["海王", "海贼王", "火影忍者", "复仇者联盟"]
- }
- },
- methods: {
- change(i) {
- /* this.currentIndex = i */
- if (this.currentIndex == i) return
- this.currentIndex = i
- }
- }
- })
- script>
- body>
- html>
v-for时候的index索引,给每行绑定事件点击事件,点击当行是获取此行索引index并赋值给currentIndex,使用v-bind:绑定class,当index===currentIndexDom元素有active的class,颜色变红。

class属性中可以放数组,会依次解析成对应的class。
- <div id="app">
- <h2 :class="['active','aaa']">我们正在学习vueh2>
- <h2 :class="[active,aaa]">我们正在学习vueh2>
- <h2 :class="getStyle()">我们正在学习vueh2>
- div>
- <script>
- /* 数组中加引号和不加引号有区别
- 加引号:表示字符串 是固定的,
- 不加引号:表示变量是不固定的 */
- const vm = new Vue({
- el: '#app',
- data() {
- return {
- active: 'isactive',
- aaa: 'bbb'
- }
- },
- methods: {
- getStyle() {
- return [this.active, this.aaa]
- }
- }
- })
- script>

- <div id="app">
-
-
-
- <h2 :style="{fontSize:'50px'}">我们爱学习h2>
-
-
- <h2 :style="{fontSize:fontsize}">我们爱学习h2>
- <h2 :style="getStyle()">我们爱学习h2>
- div>
- <script>
- const vm = new Vue({
- el:'#app',
- data(){
- return {
- fontsize:40+'px'
- }
- },
- methods:{
- getStyle(){
- return {fontSize:this.fontsize}
- }
- }
- })
- script>

- <div id="app">
- <h2 :style="[baseStyle]">我们爱学习h2>
- <h2 :style="['baseStyle']">我们爱学习h2>
- <h2 :style="getStyle()">我们爱学习h2>
- div>
- <script>
- const vm = new Vue({
- el:'#app',
- data(){
- return {
- baseStyle:{background:'#f00'}
- }
- },
- methods:{
- getStyle(){
- return [this.baseStyle]
- }
- }
- })
- script>

类似绑定class,绑定style也是一样的。