- 一个简单的组件
eg:
var app = new Vue({
el:"#app", //用来指定id属性
data: {//组件存储的数据
message: "Hello vue!"
}
})
- v-bind:title=”message” :用来绑定id指定组件中data的message属性的值 几秒之后显示
eg:
<div id="app-2">
<span v-bind:title="me">
message
</span>
</div>
<script>
var app2 = new Vue({
el:"#app-2",
data:{
me:"Hello"
}
})
</script>
PS:可以使用v-bind:class=”“本意用来指定修饰的类,可以用来函数对其中为true的选项进行选择器类的装置 使用v-bind:style=”“可以设定style的样式,也可以用函数来将其分割形成指定的样式
- v-if: 用来进行控制如果组件中指定信息为true/1/其他那么将会显示这个DOM, 如果为false /0/null/NAN 等将会不显示DOM
eg: 绑定调用的要是直接父元素, 否则将会报错
<div id="app2">
<ol>
<li v-for="todo in todos">
{{todo.title}}
</li>
</ol>
</div>
<script>
var vm = new Vue({
el:"#app2",
data:{
todos:[
{title:"hehehe"},
{title:"hahaha"},
{title:"xixixi"}
]
}
});
</script>
- v-on:XXX 将为组件添加一个事件监听器
eg:
<div id="app">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">逆转消息</button>
</div>
<script src="index.js">
var app = new Vue({
el:"#app",
data:{
message:"ss"
},
methods:{
reverseMessage:function(){
this.message = this.message.split("").reverse().join("")
}
}
});
</script>
- v-bind 例子:
<div id="app-7"> <!--绑定id为#app-7所有其中定义的data和方法将会在rootDom元素作用域范围内生效--!>
<ol>
<todo-item <!--使用Vue创建的组件todo-item--!>
v-for="item in groceryList" <!--指定了循环为将groceryList展现,每个item是其中的一个条目--!>
v-bind:todo="item"<!--绑定了todo-item其中的todo:名为id 以使得组件内部渲染正确--!>
v-bind:key="item.id"><!--绑定key--!>
</todo-item>
</ol>
</div>
//定义组件
Vue.component('todo-item', {
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: '随便其它什么人吃的东西' }
]
}
})
- vue 的 渲染: vue的渲染是双向绑定的在组件初始化中包含的数据信息都会被vue进行自动渲染,但是创建后加入的变量将不会被渲染
- 在使用Object.freeze(obj) 的时候模板渲染刷新将会失效
- vue 将一些实例和方法接口暴露出来(以$开头)和用户区分
eg:
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
PS: vue 使用过程中div将会阻断vue实例的信息的传递
- 生命周期钩子
created钩子用来执行在一个实例被创建之后执行的代码:
eg:
new Vue({
data: {
a: 1
},
created: function(){
dosomething...
}
})
PS: () => {} 是和父级进行绑定的, this将不会是预期的Vue, 将会导致错误发生
- 生命周期钩子调用顺序
beforeVreated -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeDestroy -> destroyed
- vue前端模板语法
- 文本: 最常用的使用
<span>Message: {{msg}}</span>
此时vue将会对这里的数据进行自动渲染, 当msg变化的时候msg渲染也将自动变化, 可以添加v-once指令使得信息不会自动渲染<span v-once>{{msg}}</span>
- 普通HTML表现: 如果想使用{{msg}}的普通文本应该如下书写:
<span v-html="rawHtml">
,PS:1.rawHtml应该是一个属性 2.可以使用rawHtml: “This should be red.” 然后使用 v-html=”rawHtml”就可以显示红色的This should be red. PS:注意使用插值渲染将会导致XSS攻击,所以对用户不应该提供插值的内容 - Mustache语法不能直接作用在HTML特性上
- 模板可以使用表达式,但是不支持语句(如定义语句),不支持流控制,应该使用三元表达式
- PS: 模板表达式中只能访问
- 文本: 最常用的使用
- 指令:
- v- 前缀特殊特征,指令特性的值期望的是单个的JavaScript表达式(除了v-for) 表达式的值变更的时候,将产生连带影响,响应式的作用域DOM节点。
- 参数: 在指令后面有些可以用”:”绑定一个参数 如
<a v-bind:href="url">...</a>
就会将href特性与表达式url的值进行绑定 - 修饰符: 以 . 连接后面的后缀表示以一个特殊的方式进行绑定。如 .prevent修饰符告诉v-on:click 不会触发 a标签或者button标签的自动刷新(调用event.preventDefault())
- .stop:组织了时间的继续传播 阻止了它的捕获和冒泡过程(stopProgagation())
<div v-on:click="gett">外部点击
<div v-on:click.stop="tz">内部点击</div>
</div>
- .prevent: 阻止了默认事件的发生 event.preventdefault()
- .capture: 添加时间监听器时使用事件捕获模式,即在捕获模式下触发实例:
- .stop:组织了时间的继续传播 阻止了它的捕获和冒泡过程(stopProgagation())
<div v-on:click.capture="gett">外部点击
<div v-on:click="tz">内部点击
<div v-on:click="set">点击</div>
</div>
</div>
点击最内层的时候将会按照 gett -> tz -> set的顺序进行调用
- .self 当前元素自身触发时才会触发函数
- .once 只触发一次
- 缩写: vue为 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>
- 计算属性和侦听器
- 计算属性: 本义就是为了避免在模板内使用表达式运算,因为会使得模板混入过多的逻辑而使得模板过重难以维护,所以应该使用computed:
eg:
- 计算属性: 本义就是为了避免在模板内使用表达式运算,因为会使得模板混入过多的逻辑而使得模板过重难以维护,所以应该使用computed:
<div id="example">
<span>{{message}}</span><br>
<span>{{reversedMessage}}</span>
</div>
var app = new Vue({
el: '#example',
data: {
message: 'Hello Vue!'
},
computed:{
//计算属性的getter(不能对这个属性进行设置)
reversedMessage: function(){
return this.message.split("").reverse().join("")
}//reversedMessage的值始终根据message变化
}
});
- 计算属性缓存 vs 方法 : 首先我们在前端模板表达式中直接调用方法{{reversedMessage()}} 也可以达到同样的效果 但是计算属性是基于它们的依赖进行缓存额。计算属性只有在依赖关系发生改变的时候才会重新求值。就是message没有改变reversedMessage计算属性会立即返回之前的计算结果不用再次执行函数。(PS:这样来看 ```computed:now:function(){return Date.now()}```就和方法一样每次重新渲染都要执行函数一次因为没有相关的依赖)<br>然而方法调用则会每次都会重新渲染<br>由此可得我们使用缓存的理由,如果使用一个性能开销很大的计算属性A, 需要遍历一个大数组并做大量计算的话,我们可能有其他属性依赖于A,如果没有缓存我们需要多次执行A的getter(如果使用计算方法的话就可以利用缓存)
- 侦听属性 : 有些数据需要根据其他的数据变动而变动的时候,可以使用watch进行侦听. 就是对在watch中对data中的变量进行侦听, 在其变动的时候触发一些事件。
PS:侦听属性在没有变化的时候哪怕进行了赋值操作也不会触发,更不会产生副作用。
侦听器在数据变化时候执行异步或者开销较大的操作的时候是有用的。
侦听器的参数有curVal, oldVal 但是如果观察的数据为对象或者数组的时候, curVal和oldVal的值是相等的, 因为这两个形参指向的是同一个引用
eg:
<div id="watchExample">
<input type="text" v-model="firstname">
<input type="text" v-model="lastname">
<br>
<span>fullName: {{fullname}}</span>
</div>
var app2 = new Vue({
el: '#watchExample',
data: {
firstname: "Sui",
lastname: "Lin",
fullname: ""
},
watch: {
firstname: function(value){
this.fullname = value+" "+this.lastname
},
lastname: function(value){
this.fullname = this.firstname+" "+value
}
},
//下面对比一下使用计算方法的实现
//引用的时候使用{{computed}}即可
computed: {
fullNameGet:function(){
return this.firstname+" "+this.lastname
}
}
});
//app2.$data.lastname = "Li";//使用侦听方法的时候测试是否外部修改就可以改变, 然后PS:data暴露在外面但是要通过$获取
//侦听器的另外一个例子(体现异步操作时候的便利性)
<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>
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
</p>
<p>
{{answer}}
</p>
</div>
var watchExample = new Vue({
el: "#watch-example",
data: {
question: "",
answer: "I cannot give you an answer until you ask a question!"
},
watch: {
question: function(newValue,oldValue){
this.answer = "Waiting for you to stop typing...";
this.debouncedGetAnswer();//在created阶段进行了debouncedGetAnswer函数的绑定,绑定的来源是_.debouncedGetAnswer()
}
},
created: function(){
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500); //_.debounce` 是一个通过 Lodash 限制操作频率的函数 有类似的函数 _.throttle
},
methods: {
getAnswer: function(){
//要求在question中要包含? 如果不包含的话将会显示提示信息
if(this.question.indexOf('?') === -1){
this.answer = 'Questions usually contain a question mark. ;-)';
return;
}
this.answer = "thinking";
var vm = this;//使得vm指向watchExample
//使用axios 异步发送请求 使用Promise进行后续的处理
axios.get('https://yesno.wtf/api').then(response => {
vm.answer = _.capitalize(response.data.answer);
}).catch(error => vm.answer = 'Error! Could not reach the API. ' + error)
}
}
});
- 计算属性的setter: 计算属性默认只有getter 但是在需要的时候可以提供一个setter
eg:
test:{
get: function(){
dosomething;
return something;
},
set: function(newValue){
dosomething;
}
}
PS: v-if 和 v-show 的区别:
首先来说两者对于页面展示的效果都为显示隐藏的控制
区别:
1.v-if 为 true时候 显示div, 当值为false的时候 元素消失,代码也会消失,相当于代码删除(也就是说vue框架将不会对该模块进行渲染) 而当再次改为true的时候,页面将会重新渲染成为div.
v-show 控制隐藏和显示是通过将CSS 属性修改为display: none或block 实现的
2.v-if后面还有v-else和 v-else-if 进行条件的渲染, PS:注意v-else 和 v-else-if要紧跟着v-if才有效