1、挂载点、模版和实例
⑴ 挂载点
Vue实例中的el属性所对应的id的DOM节点
⑵ 模版
在挂载点内部的内容,统称为模版内容
模版可以写在挂载点内部,也可以写在Vue实例的template属性当中
示例:
<div id="app">
<h1>Hello {{message}}</h1>
</div>
<script type="text/javascript">
var vue = new Vue({
el: '#app',
data: {
message: 'Vue!'
}
});
</script>
和
<div id="app"></div>
<script type="text/javascript">
var vue = new Vue({
el: '#app',
template: '<h1>Hello {{message}}</h1>',
data: {
message: 'Vue!'
}
});
</script>
这2个的效果是一样的,一般是写在挂载点当中
注意:Vue实例的template属性,必须是一个节点元素,如果单纯的是文字,则会报错,Vue无法正常渲染
[Vue warn]: Error compiling template:
- Component template requires a root element, rather than just text.
⑶ 实例
Vue实例(new Vue()),结合模版(template)和数据(data),来生成最终要展示的内容,并放到挂载点(el)所对应的页面DOM元素当中
2、数据、指令、方法和事件
⑴ 数据
Vue实例的data属性,可以定义任意的名值对,在挂载点中通过两个大括号来引用,这种语法规则叫 插值表达式
⑵ 指令
⒈ v-text
给某元素添加 v-text的Vue指令,可以将data对应的数据内容,插入到改元素当中
示例:
<span v-text="message"></span>
和
<span>{{message}}</span>
这2个的效果是一样的
⒉ v-html
和v-text不同的时,它会更新元素的innerHTML。内容是按照普通HTML插入,而不会作为Vue模版进行编译
注意:在网站上动态渲染任意HTML是非常危险的,因为容易导致XSS攻击。只能在可信任内容上使用v-html,永远不要用在用户提交的内容上头
示例:
new Vue({
data: {
number: '<font>1234</font>'
}
});
<span v-text="number"></span>
会展示为:<font>1234</font>
而
<span v-html="number"></span>
会展示为:1234
⑶ 方法
写到Vue实例的methods 属性当中
⑷ 事件
通过 v-on: 指令,后面跟着Function,来给元素添加对应的事件
示例:【给元素添加单击事件,单击并改变div的内容】
<div v-on:click="handleClick">{{message}}</div>
new Vue({
data: {
message: '单击这里'
},
methods: {
handleClick: function() {
alert(1234);
this.message = '1234';
}
}
});
注意:
handleClick方法中的this.message代表Vue实例中的data属性中的message。而且需要添加this,否则无法定位到该属性,而无法改变message数据
这是面向数据编程
Tips:
v-on: 可以缩写为 @
即 v-on:click 可以缩写为 @click
3、属性绑定和双向数据绑定
⑴ 属性绑定
通过 v-on: 指令,后面跟着元素的属性
示例1:v-on:title 绑定元素的title属性
v-on: 可以缩写为 :
即 v-on:title 可以缩写为 :title
<span :title="'你好 ' + message">鼠标悬浮上来</span>
new Vue({
data: {
message: 'Vue!'
}
});
示例2::class 添加样式
<style type="text/css">
.item{color:orange;cursor:pointer;}
.background{background:yellow;}
.big{font-size:47px;}
</style>
<h1 class="item" :class="{'background':background, 'big':big}"
@click="background=!background, big=!big">点这里!</h1>
new Vue({
data: {
background: false,
big: false
}
});
Tips:绑定class样式,只是添加或移除新的样式,对旧样式不会造成影响
⑵ 双向数据绑定
单向绑定:数据决定页面的显示,但页面无法决定数据的内容
双向绑定:数据和页面可以互相决定
通过 v-model 指令,跟着data里的数据内容的key
示例:【改变input的内容,同步更新div的内容】
<input type="text" v-model="val" />
<div>{{val}}</div>
new Vue({
data: {
val: ''
}
});
4、计算属性与监听器
⑴ 计算属性
通过Vue实例的computed属性来实现,传入Function
只有当依赖的数据发生改变时,计算的结果才会被改变,否则它使用上次结果的缓存值
示例:【综合2个输入框的内容】
<input type="text" v-model="first" />
<input type="text" v-model="second" />
<h1>{{result}}</h1>
new Vue({
computed: {
result: this.first + '' + this.second;
}
});
⑵ 监听器
通过Vue实例的watch属性来实现,传入Function
针对某些数据值的改变,来进行一些操作
示例:【监听输入的变化次数】
<input type="text" v-model="first" />
<input type="text" v-model="second" />
<h1>{{result}}</h1>
<h1 v-text="count"></h1>
new Vue({
data: {
first: '',
second: '',
count: 0
},
computed: {
result: this.first + '' + this.second;
},
watch: {
first: function() {
this.count++;
},
second: function() {
this.count++;
},
result: function() {
this.count--;
}
}
});
这里的result数据会一直是0,因为watch监听器同样适用于计算后的结果
5、其他常用指令
⑴ v-if
控制元素的显示和隐藏。当隐藏时,它会把元素变为 <!---->
⑵ v-show
控制元素的显示和隐藏。当隐藏时,它会给元素添加 display: none; 的属性
如果频繁地对元素进行显示和隐藏操作时,明显地v-show要比v-if的效率要高
⑶ v-for
循环遍历数组数据内容
示例:
<ul><li v-for="item in items">{{item}}</li></ul>
new Vue({
data: {
items: [1, 2, 3, 4, 5]
}
});
Tips:
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。
建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
修改上面的例子:
<ul><li v-for="(item, index) in items" :key="index">{{item}}</li></ul>
这里的index是索引下标,它复合唯一的理想标准
6、模块
⑴ 全局注册
Vue.component('自定义标签名', {
props: ['参数名1', '参数名2'],
template: '模版内容'
});
Tips:对于自定义标签的命名 Vue.js 不强制遵循 W3C 规则 (小写,并且包含一个短杠),尽管这被认为是最佳实践。
每一个组件都是一个实例,它也可以添加诸如methods属性,来给自定义模版添加上事件
关于传参:
通过 :参数名 来实现
示例:
Vue.component('my-component', {
props: ['content']
template: '<font>{{content}}</font>'
});
<my-component :content="传参"></my-component>
注意:确保在初始化根实例之前注册组件
即Vue.component() 要写在 new Vue() 之前
⑵ 局部注册
可以不必把每个组件都注册到全局。通过某个 Vue 实例/组件的实例的 components 属性,注册在其作用域中可用的组件
var 变量名 = {
props: ['参数名1', '参数名2'],
template: '模版内容'
}
new Vue({
components: {
'自定义标签名': 变量名
}
});
7、组件给根实例传值,并触发事件
⑴ 给组件的模版添加事件
例如添加点击事件:
<div><my-component></my-component></div>
Vue.component('my-component', {
props: ['arg']
template: '<span @click="handleClick" :arg="参数"></span>',
methods: {
handleClick () {
// 单击事件逻辑
}
}
});
⑵ 触发当前实例【模版元素】上的事件
vm.$emit( event, […args] )
接着上头的例子继续:
单击事件的逻辑
this.$emit('handle', arg)
<div @handle="handleMethod"><my-component></my-component></div>
⑶ 触发根实例的事件
new Vue({
methods: {
handleMethod (arg) {
alert(arg)
}
}
});
【完整例子】
<div id="app">
<my-component @handle="handleFunction" :arg="argument"></my-component>
</div>
<script type="text/javascript">
Vue.component('my-component', {
props: ['arg'],
template: '<span @click="handleClick">单击这里!</span>',
methods: {
handleClick () {
this.$emit('handle', this.arg)
}
}
});
const vue = new Vue({
el: '#app',
data: {
argument: '参数'
},
methods: {
handleFunction (arg) {
alert(arg)
}
}
});
</script>
8、过滤器
过滤器用于格式化文本。可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)
通过在文本后面添加 | 管道符号来调用
⑴ 局部定义过滤器
<div>{{number | numberFormatter}}</div>
<script type="text/javascript">
new Vue({
data () {
return {
number: 123
}
},
filters: {
numberFormatter (num) {
return '结果:' + num;
}
}
});
</script>
⑵ 全局定义过滤器
<div :title="number | numberFormatter('单位')">{{number}}</div>
Vue.filter("numberFormatter", function(num, unit) {
return '结果:' + num + unit;
});
9、set赋值数据
vm.$set(target, key, value)
示例:
<style type="text/css">
.color{background:red;}
</style>
<h1 @click="handleClick">点这里!</h1>
<ul><li v-for="(item, index) in arr" :key="index"
:class="{color:item.color}">{{item.name}}</li>
</ul>
new Vue({
data: {
arr: [
{'name':'张三'},
{'name':'李四'},
{'name':'王五'}
]
},
methods: {
handleClick () {
this.arr.forEach((item, index) => {
this.$set(item, 'color', true)
})
}
}
});