数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令
<span v-html="rawHtml"></span>
v-bind 特性被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊特性。
可能你已经猜到了,它们会在渲染的 DOM 上应用特殊的响应式行为。
在这里,该指令的意思是:“将这个元素节点的 title 特性和 Vue 实例的 message 属性保持一致”。
v-for 指令可以绑定数组的数据来渲染一个项目列表:
<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: '学习 JavaScript' },
{ text: '学习 Vue' },
{ text: '整个牛项目' }
]
}
})
v- 前缀作为一种视觉提示,用来识别模板中 Vue 特定的特性。
当你在使用 Vue.js 为现有标签添加动态行为 (dynamic behavior) 时,v- 前缀很有帮助,然而,对于一些频繁用到的指令来说,就会感到使用繁琐。
同时,在构建由 Vue.js 管理所有模板的单页面应用程序 (SPA - single page application) 时,v- 前缀也变得没那么重要了。
因此,Vue.js 为 v-bind 和 v-on 这两个最常用的指令,提供了特定简写:
v-bind 缩写
<!-- 完整语法 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
v-on 缩写
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
它们看起来可能与普通的 HTML 略有不同,但 : 与 @ 对于特性名来说都是合法字符,在所有支持 Vue.js 的浏览器都能被正确地解析。
而且,它们不会出现在最终渲染的标记中。缩写语法是完全可选的,但随着你更深入地了解它们的作用,你会庆幸拥有它们。
v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。
v-on 指令添加一个事件监听器,
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
通过它调用在 Vue 实例中定义的方法:
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">逆转消息</button>
</div>
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue.js!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
vuejs is not detected
如果用了production/minified的vue,devtools的选项是默认关闭的所以没法用
如果页面是要用file://打开,需要到chrome设置->扩展应用->把“允许访问文件网址”的选项打开,才能读取到内容使用
我直接引用vue.js文件,不能使用。使用官网提供的脚手架开发就可以了。
1 必须放到服务器
2 使用vue.js
3 重启调试面板
https://cn.vuejs.org/v2/guide/computed.html#基础例子
所有现代浏览器都支持 JSON 对象,有两个非常有用的方法来处理 JSON 格式的内容:
JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象。
JSON.stringify(obj) :接受一个 JavaScript 对象并将其转换为一个 JSON 字符串。
<html> <head> <script src="https://unpkg.com/vue"></script> <!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 --> <!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 --> <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script> </head> <body> <div id="app"> {{message}} </div> <div id="app-2"> <span v-bind:title="message"> 鼠标悬停几秒种查看此处动态绑定的提示信息! </span> </div> <div id="app-3"> <p v-if="seen">现在你看到我了</p> </div> <div id="app-4"> <ol> <li v-for="todo in todos"> {{todo.text}} </li> </ol> </div> <div id="app-5"> <p>{{message}}</p> <button v-on:click="reverseMessage">逆转消息</button> </div> <div id="app-6"> <p>{{message}}</p> <input v-model="message"> </div> <div id="app-7"> <ol> <!-- 创建一个todo-item组件的实例 --> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id" > </todo-item> </ol> </div> <div id="example"> </div> <div id="mustaches"> <span> Message:{{msg + 'world'}} </span> <span v-once>这个将不会改变:{{msg}}</span> <p>Using mustaches: {{rawHtml}}</p> <p>Using v-html directive: <span v-html="rawHtml"></span> </p> <!-- js expression --> <p> Number compute:{{number+1}} </p> <p>boolean:{{ ok?'YES':'NO'}}</p> <p> {{ message.split('').reverse().join('') }} </p> <p> Original message:"{{message}}"</p> <p>Computed reversed message:"{{reverseMessage}}" </p> <p> Reversed message:"{{ reverseMessage2() }}" </p> <!-- 这是语句,不是表达式 --> <!-- <span>{{ var a = 1 }}</span> --> <!-- 流控制也不会生效,请使用三元表达式 --> <!-- <span>{{ if (ok) { return message } }}</span> --> </div> <div id='watchDemo'> <p>fullName:{{ fullName }}</p>fullNameComputed <p>fullName methods :{{ fullNameMethod() }}</p> <p>fullName computed :{{ fullNameComputed }}</p> <p>firstName setter :{{firstName}}</p> <p>lastName setter :{{lastName}}</p> </div> <div id="watch-example"> <p> Ask a yes/no question: <input v-model="question"> </p> <p>{{ answer }}</p> <ol v-for=" data in answer"> <li>{{data.id}}==>{{data.name}}</li> </ol> </div> <script> var app=new Vue({ el:'#app', data:{ message:'Hello Vue!' } }); var app2=new Vue({ el:'#app-2', data:{ message:'页面加载于'+new Date().toLocaleString() } }); var app3=new Vue({ el:'#app-3', data:{ seen:true } }); var app4=new Vue({ el:'#app-4', data:{ todos:[ {text:'学习JavaScript'}, {text:'学习Vue'}, {text:'整个牛项目'}, ] } }); var app5=new Vue({ el:'#app-5', data:{ message:'Hello Vue.js' }, methods:{ reverseMessage:function(){ this.message=this.message.split('').reverse().join('') } } }); var app6=new Vue({ el:'#app-6', data:{ message:'Hello Vue!' } }); // 定义名为 todo-item 的新组件 Vue.component('todo-item',{ //todo-item组件现在接受一个“prop”,类似于一个自定义特性 //这个prop名为todo props:['todo'], template:'<li>{{todo.text}}</li>' }); var app7=new Vue({ el:"#app-7", data:{ groceryList:[ {id:0,text:'蔬菜'}, {id:1,text:'奶酪'}, {id:2,text:'随便其它人什么好吃的东西'} ] } }); //定义一个数据对象 var data={a:1} //该对象被加入到一个Vue实例中 var vm=new Vue({ el:'#example', data:data }) //data和vm引用相同的对象 console.log(vm.a===data.a); //设置vm对象的属性也会影响原始数据 vm.a=2; console.log(data.a) //设置data对象的属性,vm中的属性值也会发生变化 data.a=3 console.log(vm.a) //Vue实例暴露了一些有用的实例属性与方法,它们都有前缀$,以便与用户定义的属性区分开来 console.log("vm.$data===data : "+(vm.$data===data)) var domExample=document.getElementById('example'); console.log("vm.$el===domExample : "+(vm.$el===domExample)) //$watch是一个实例方法 vm.$watch('a',function(newValue,oldValue){ //这个回调将在'vm.a'改变后调用 console.log("value changed: newValue=>" +newValue +" , oldValue="+oldValue); }); new Vue({ data:{a:1}, created:function(){ //this指向vm实例. //如果使用箭头函数(==>)时, //this就不是所在的vm实例,因为箭头函数是和父级上下文绑定在一起的 //this不会是预期的Vue实例 console.log('a is :'+this.a); } }); var mustachesApp=new Vue({ el:'#mustaches', data:{ msg:'<b>hello</b>', rawHtml:'<b>hello</b>', number:10, ok:'', message:'hello vue' }, computed:{ reverseMessage:function(){ // this指向vm实例 return this.message.split('').reverse().join(''); } }, methods:{ reverseMessage2:function(){ return this.message.split('').reverse().join('') } } }); console.log(mustachesApp.reversedMessage) mustachesApp.message="Goodbye" console.log(mustachesApp.reversedMessage) var watchDemo=new Vue({ el:'#watchDemo', data:{ firstName:'Foo', lastName:'Bar', fullName:'Foo Bar default value' }, watch:{ firstName:function(val){ this.fullName=val+''+this.lastName }, lastName:function(val){ this.fullName=this.firstName+''+val } }, methods:{ fullNameMethod:function(){ return this.firstName+' methods ' +this.lastName } }, //然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调 computed:{ fullNameComputed:function(){ return this.firstName +' computed '+this.lastName }, fullNameGetSet:{ //getter get:function(){ return this.first+ ' ' +this.lastName }, //计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter : //setter set:function(newValue){ var names=newValue.split(' ') this.firstName=names[0] this.lastName=names[names.length-1] } } } }); watchDemo.fullNameGetSet='John Doe' var watchExampleVM=new Vue({ el:'#watch-example', data:{ question:'', answer:'I cannot give you an answer until you ask a question' }, watch:{ //如果question发生改变,这个函数就会运行 question:function(newQuestion){ this.answer='Waiting for you to stop typing ', this.getAnswer() } }, methods:{ //_.debounce是一个通过Lodash限制操作频繁的函数。 //在这个例子中,我们希望限制访问 yesno.wtf/api的频率 //AJAX请求直到用户输入完毕才会发出。 //想要了解更多关于_.debounce函数(及其近亲_.throttle)的知识, //请参考 https://lodash.com/docs#debounce getAnswer:_.debounce( function(){ if(this.question.indexOf('?')===-1){ this.answer='Question usually contain a question mark.;-)' return } this.answer='Thinking...' var vm=this axios.get('http://youhuale.cn/api/v4/cover/dev-lang') .then(function(response){ console.log("response "+response.data.code) var data=response.data.data data.forEach(function(item){ console.log(item+",id:"+item['id']+",name:"+item['name']); }) vm.answer=_.capitalize(response.data.data) }) .catch(function(error){ console.log("error "+error) vm.answer='Error!Could not reach the API.'+error }) }, //这是为判定用户停止输入等待的毫秒数 500 ) } }); </script> </body> </html>