Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。Vue 只关注视图层, 采用自底向上增量开发的设计。
在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<div id="app">
  <p>{{ message }}</p>
</div>

<script>
    new Vue({
      el: '#app',
      data: {
        message: 'Hello Vue.js!'
      }
    })
</script>
每个 Vue 应用都需要通过实例化 Vue 来实现。
语法格式:
var vm = new Vue({ // 选项 })
vue构造器中所需要的参数:{{ }} 用于输出对象属性和函数返回值
<div id="vue_det">
    <h1>site : {{site}}</h1>
    <h1>url : {{url}}</h1>
    <h1>{{details()}}</h1>
</div>
<script type="text/javascript">
    var vm = new Vue({
        el: '#vue_det',                //el参数为dom中的id,意味着改动全部在<div>内部
        data: {                        //data定义属性,实例中分别为site,url,alexa三个属性
            site: "vue学习",
            url: "www.vue.com",
            alexa: "10000"
        },
        methods: {                    //用于定义函数,可以通过return返回函数值
            details: function() {
                return  this.site + " - 学的不仅是技术,更是梦想!";
            }
        }
    })
</script>

Vue.js 模板语法

插值

文本  使用{{...}}
<div id="app">
  <p>{{ message }}</p>
</div>
Html
<div id="app">
    <div v-html="message"></div>      //v-html指令用于输出html代码
</div>
    
<script>
    new Vue({
      el: '#app',
      data: {
        message: '<h1>vue学习</h1>'
      }
    })
</script>

属性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
    </head>
    <style>
        .class1{
          background: #444;
          color: #eee;
        }
    </style>
    <body>
        <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>

        <div id="app">
          <label for="r1">修改颜色</label><input type="checkbox" v-model="use" id="r1">
          <br><br>
          <div v-bind:class="{'class1': use}">
            v-bind:class 指令                 //HTML 属性中的值应使用 v-bind 指令。           </div>
        </div>

        <script>
            new Vue({
                el: '#app',
              data:{
                  use: false
              }
            });
        </script>
    </body>
</html>
表达式
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
	{{5+5}}<br>
	{{ ok ? 'YES' : 'NO' }}<br>
	{{ message.split('').reverse().join('') }}
	<div v-bind:id="'list-' + id">菜鸟教程</div>
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
	ok: true,
    message: 'RUNOOB',
	id : 1
  }
})
</script>
指令 v- 前缀的特殊属性用于在表达式的值改变时,将某些行为应用到 DOM 上
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
    <p v-if="seen">现在你看到我了</p>     // v-if 指令将根据表达式 seen 的值(true 或 false )来决定是否插入 p 元素     <template v-if="ok">
      <h1>菜鸟教程</h1>
      <p>学的不仅是技术,更是梦想!</p>
      <p>哈哈哈,打字辛苦啊!!!</p>
    </template>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    seen: true,
    ok: true
  }
})
</script>
参数:在指令后以冒号指明 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定
<div id="app">
    <pre><a v-bind:href="url">菜鸟教程</a></pre>  //href参数,通过下面的vue实力进行赋值
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    url: 'http://www.runoob.com'
  }
})
</script>
用户输入,在input输入框中可以使用v-model指令实现双向数据绑定 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。
<div id="app">
    <p>{{ message }}</p>
    <input v-model="message">
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  }
})
</script>
点击按钮反转字符串
<div id="app">
    <p>{{ message }}</p>
    <button v-on:click="reverseMessage">反转字符串</button>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')
    }
  }
})
</script>

过滤器

被用作一些常见的文本格式化
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  {{ message | capitalize }}   //过滤器可以串联。{{message|filterA|filterB}}
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
	message: 'runoob'
  },
  filters: {
    capitalize: function (value) {     //过滤器是一个函数,可以接受参数
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)   //对第一个字符转为大写
    }
  }
})
</script>
</body>
</html>
v-bind缩写为空,v-on缩写为@
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>

Vue.js 条件与循环

v-if   v-else
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
	<div v-if="Math.random() > 0.5">
	  Sorry
	</div>
	<div v-else>
	  Not sorry
	</div>
</div>
	
<script>
new Vue({
  el: '#app'
})
</script>
多个条件
<div id="app">
    <div v-if="type === 'A'">
      A
    </div>
    <div v-else-if="type === 'B'">
      B
    </div>
    <div v-else-if="type === 'C'">
      C
    </div>
    <div v-else>
      Not A/B/C
    </div>
</div>
    
<script>
new Vue({
  el: '#app',
  data: {
    type: 'C'
  }
})
</script>
v-show 使用 v-show 指令来根据条件展示元素
<div id="app">
    <h1 v-show="ok">Hello!</h1>
</div>
	
<script>
new Vue({
  el: '#app',
  data: {
    ok: true
  }
})
</script>

使用 v-for指令可以绑定数据到数组来渲染一个列表
<div id="app">
  <ol>
    <li v-for="site in sites">
      {{ site.name }}
    </li>
  </ol>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    sites: [
      { name: 'Runoob' },
      { name: 'Google' },
      { name: 'Taobao' }
    ]
  }
})
</script>
第一个参数为值,第二个参数为键名,第三个参数为索引
<div id="app">
  <ul>
    <li v-for="(value, key, index) in object">
     {{ index }}. {{ key }} : {{ value }}
    </li>
  </ul>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    object: {
      name: '菜鸟教程',
      url: 'http://www.runoob.com',
      slogan: '学的不仅是技术,更是梦想!'
    }
  }
})
</script>
计算属性的实例
<div id="app">
  <p>原始字符串: {{ message }}</p>
  <p>计算后反转字符串: {{ reversedMessage }}</p>
</div>
 
<script>
var vm = new Vue({
  el: '#app',
  data: {
    message: 'Runoob!'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
</script>

computed vs methods

效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。

Vue.js 监听属性

<div id = "app">
 <p style = "font-size:25px;">计数器: {{ counter }}</p>
 <button @click = "counter++" style = "font-size:25px;">点我</button>
</div>
<script type = "text/javascript">
     var vm = new Vue({
        el: '#app',
        data: {
           counter: 1
        }
     });
     vm.$watch('counter', function(nval, oval) {           //通过watch实现计数器
        alert('计数器值的变化 :' + oval + ' 变为 ' + nval + '!');
     });
</script>
<html>
<head>
	<meta charset="utf-8">
	<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
	<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
   <body>
      <div id = "computed_props">
         千米 : <input type = "text" v-model = "kilometers">
         米 : <input type = "text" v-model = "meters">
      </div>
	   <p id="info"></p>
      <script type = "text/javascript">
         var vm = new Vue({
            el: '#computed_props',
            data: {
               kilometers : 0,
               meters:0
            },
            methods: {
            },
            computed :{
            },
            watch : {
               kilometers:function(val) {
                  this.kilometers = val;
                  this.meters = this.kilometers * 1000
               },
               meters : function (val) {
                  this.kilometers = val/ 1000;
                  this.meters = val;
               }
            }
         });
         // $watch 是一个实例方法
		vm.$watch('kilometers', function (newValue, oldValue) {
			// 这个回调将在 vm.kilometers 改变后调用
		    document.getElementById ("info").innerHTML = "修改前值为: " + oldValue + ",修改后值为: " + newValue;
		})
      </script>
   </body>
</html>

Vue.js 样式绑定

class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性。
如下:<div class="active"></div>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
    .active {
	    width: 100px;
	    height: 100px;
	    background: green;
    }
</style>
</head>
<body>
<div id="app">
  <div v-bind:class="{ active: isActive }"></div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    isActive: true
  }
})
</script>
可以传入更多属性动态切换多个class
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<style>
.active {
	width: 100px;
	height: 100px;
	background: green;
}
.text-danger {
	background: red;
}
</style>
</head>
<body>
<div id="app">
  <div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
  </div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    isActive: true,
	hasError: false
  }
})
</script>
事件处理器
<div id="app">
  <button v-on:click="counter += 1">增加 1</button>
  <p>这个按钮被点击了 {{ counter }} 次。</p>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    counter: 0
  }
})
</script>
表单:
<div id="app">
  <p>input 元素:</p>
  <input v-model="message" placeholder="编辑我……">
  <p>消息是: {{ message }}</p>
    
  <p>textarea 元素:</p>
  <p style="white-space: pre">{{ message2 }}</p>
  <textarea v-model="message2" placeholder="多行文本输入……"></textarea>
</div>
 
<script>
new Vue({
  el: '#app',
  data: {
    message: 'Runoob',
    message2: '菜鸟教程\r\nhttp://www.runoob.com'
  }
})
</script>