数据绑定最常见的形式就是使用“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/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/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>