以下:内容主要来源菜鸟教程http://www.runoob.com/vue2/vue-tutorial.html,顺便夹杂一些其他七七八八。 内容仅用于自我记录学习使用。如有错误,欢迎指正。
1. 基本属性:
1. v-text : 用于输出文本值。 简写 {{}}
2. v-html : 与v-text用法相同,不过v-html会解析文本中的html标签。
简单举例:以下输出结果相同,都是"测试"
<div id="app">
<div v-html="message"></div>
<div v-text="message"></div>
<div> {{ message }}</div>
</div>
<script>
new Vue({
el: '#app',
data: {
message: '<h1>测试</h1>'
}
})
</script>
3. v-model: 实现双向数据绑定,即数据的变化时双向的。当data中的msg变化时,input中的msg也随之变化,反之input中的msg变化,data中的也随之变化。
v-model的修饰符:
.lazy:在默认情况下, v-model 在 input 事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步
<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >
.number: 如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值
<input v-model.number="age" type="number">
.trim: 如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model 上过滤输入
<input v-model.trim="msg">
Form表单的绑定Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<script type="text/javascript" src="js/vue.min.js"></script>
<body>
<div id="main">
<div>
<span>文本框的绑定 </span><br/>
<input type="text" v-model="textInfo"><br />
<span>{{ textInfo }}</span>
</div>
<br />
<div>
<span>复选框的绑定 </span><br/>
<!--单个文本框 -->
<input type="checkbox" v-model="checkBoxInfo">
<span>{{ checkBoxInfo }}</span>
<br /><br /><br />
<!--多个文本框 -->
<input type="checkbox" v-model="checkBoxsInfo" value="one">one<br />
<input type="checkbox" v-model="checkBoxsInfo" value="two">two<br />
<input type="checkbox" v-model="checkBoxsInfo" value="three">three<br />
<span>{{ checkBoxsInfo }}</span>
</div>
<br />
<div>
<span>单选按钮的绑定 </span><br/>
<input type="radio" v-model="radioInfo" value="男" />男
<input type="radio" v-model="radioInfo" value="女" />女
<br />
<span>{{ radioInfo }}</span>
</div>
<br />
<div>
<span>下拉列表的绑定 </span><br/>
<select v-model="selectInfo" name="sss">
<option value="one" selected="selected">one</option>
<option value="two">two</option>
<option value="three">three</option>
</select>
<br />
<span>{{ selectInfo }}</span>
</div>
</body>
<script>
var v = new Vue({
el: "#main",
data: {
textInfo: "",
checkBoxInfo: false,
checkBoxsInfo: [],
radioInfo: "",
selectInfo: ""
}
})
</script>
</html>
4. v-if、v-else if 、 v-else, v-show : 条件语句,成立则显示该标签(暂且这样理解),否则不显示
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
<div id='app'>
<p v-if='num > 0 && num < 10'>num在0~10之间</p>
<p v-else-if='num > 10 && num < 20'>num在10~20之间</p>
<p v-else>num > 20</p>
<p v-show ='num >100'>num > 20</p>
</div>
<script>
new Vue({
el : '#app',
data : {
num : 22
}
});
</script>
5. v-bind : 缩写为 : 。用来响应地更新 HTML 属性。一般使用在class,width等属性上。
在这里 href 是参数,告知 v-bind 指令将该元素的 href 属性与表达式 url 的值绑定。即根据Url的变化点击调专业会变化。
<div id="app">
<pre><a v-bind:href="url">测试</a></pre>
<pre><a :href="url" :class="aclass">测试</a></pre> // 缩写形式
</div>
<script>
new Vue({
el: '#app',
data: {
url: 'http://www.baidu.com'
}
})
</script>
<div id="app">
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鸟教程</div>
</div>
6. v-on: 缩写 @。用于监听 DOM 事件。最常用的是@click=“响应事件”。
具有阻止事件冒泡stop。阻止默认事件prevent等属性功能。使用方式如下
eg:
事件修饰符
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a v-on:click.once="doThis"></a>
按键修饰符
<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">
// 别名方式
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
以下实现点击后颜色变橘色
<style>.select{color: orange; font-size: 50px;}</style>
<div id='app'>
<ul>
<a :class='{select:0==idx}' href='javascript:;' v-on:click='tab(0)'>1</a>
<a :class='{select:1==idx}' href='javascript:;' v-on:click='tab(1)'>2</a>
<a :class='{select:2==idx}' href='javascript:;' v-on:click='tab(2)'>3</a>
</ul>
</div>
<script src='../js/vue.js'></script>
<script>
var vm = new Vue({
el : '#app',
data : {
idx : 0
},
methods : {
tab : function(num){
this.idx = num;
}
}
});
/*
:class='{select:0==idx}' 如果0 == idx ,则 :class='{select:true}' 否则 :class='{select:false}'
*/
</script>
8. v-for : 循环语句
使用方式1 : v-for=“item in items”
使用方式2 : v-for=“(value, key) in items”
使用方式2 : v-for=“(value, key, index) in items” // key, value为键值对,index是索引。可以用于遍历输出一个对象中的多个属性
第一种方式的使用:
<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 }} // 依次输出 0,name, 'name'; 1,url, 'http://www.baidu.com';。。。。
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
object: {
name: 'name',
url: 'http://www.baidu.com',
slogan: '啧啧啧'
}
}
})
</script>
9. 自定义指令: 使用Vue的静态方法directive。 Vue.directive(指令的名字, 回调函数)
<div id='app'>
<span v-red>vue</span>
</div>
<script src='../js/vue.js'></script>
<script>
Vue.directive('red', function(){
this.el.style.color = 'red';
});
new Vue({
el : '#app'
});
</script>
2. computed 使用
computed 和method在使用方式上完全一样。可以使用 methods 来替代 computed。区别在于,效果上两个都是一样的,但是 computed 是基于它的依赖缓存,只有相关依赖发生改变时才会重新取值。而使用 methods ,在重新渲染的时候,函数总会重新调用执行。
3. 过滤器的定义和使用
使用Vue的静态方法filter 定义过滤器
// 自定义过滤器 要定义在v前面
Vue.filter("filterName", function(date){
// 这里写过滤器的逻辑
return JSON.stringify(date) + "这是过滤后的结果"; // 返回过滤后的结果
});
过滤器的调用:
{{presons | filterName}} // preson 是值,filterName是过滤器名称
{{ message | filterA | filterB }} // 可以串联调用,将filterA返回的值再传入B
{{ message | filterA(‘arg1’, arg2) }} // message 是第一个参数,字符串 ‘arg1’ 将传给过滤器作为第二个参数, arg2 表达式的值将被求值然后传给过滤器作为第三个参数。
<style>
.red {
color: red;
}
.blue {
color: blue;
}
</style>
<body>
<div id="main" v-bind:class="clazz">
姓名: <input type="text" v-model="newPreson.name" />
<br> 年龄: <input type="text" v-model="newPreson.age" />
<br />
<input type="button" name="create" id="create" value="create" v-on:click="createPreson" />
<table border="1" cellspacing="0px">
<tr>
<td>姓名</td>
<td>年龄</td>
</tr>
<tr v-for="p in presons">
<td>{{p.name}}</td>
<td>{{p.age}}</td>
</tr>
</table>
<br />
<!-- 过滤器的调用-->
<div>{{presons | filterName}}</div>
</div>
</body>
<script>
// 自定义过滤器 要定义在v前面
Vue.filter("filterName", function(date){
// 这里写过滤器的逻辑
return JSON.stringify(date) + "这是过滤后的结果"; // 返回过滤后的结果
});
var v = new Vue({
el: "#main",
data: {
presons: [{
name: "测试",
age: "18"
}],
newPreson: {
name: "",
age: ""
},
clazz: {
red: false,
blue: true
}
},
filters:{
....// 也可以在这定义局部过滤器
}
methods: {
createPreson: function() {
if(this.newPreson.name == "" && this.newPreson.age == "") {
alert("不能为空");
}
this.presons.push(this.newPreson);
this.newPreson = {
name: "",
age: ""
}
}
}
});
</script>
4. 监听函数 $watch: 使用Vue对象的 $watch函数,可以监听某个数据的状态。当这个数据被修改时,则会去调用我们写好的回调函数
<div id='app'>
{{val}}
</div>
<script>
var v = new Vue({
el : '#app',
data : {
val : 0
}
});
v.$watch('val', function(){
alert('val被修改成' + this.val);
});
document.onclick = function(){
v.val = 22;
}
</script>
// 传入{deep:true} 参数实现深度监听,否则则是浅度监听
vm.$watch(‘person’, function(){
alert(‘person的age被修改’);
}, {deep : true});
5. 模板定义和使用
注: 使用组件时必须要通过el绑定标签,才可在绑定标签内使用自定义的模板。
1. 全局定义组件:
<div id="app">
<runoob></runoob>
</div>
<script>
// 注册
Vue.component('runoob', {
template: '<h1>自定义组件!</h1>'
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
2. 局部定义组件
<div id="app">
<runoob></runoob>
</div>
<script>
var Child = {
template: '<h1>自定义组件!</h1>'
}
// 创建根实例
new Vue({
el: '#app',
components: {
// <runoob> 将只在父模板可用
'runoob': Child
}
})
</script>
3. prop 是父组件用来传递数据的一个自定义属性。prop 是父组件用来传递数据的一个自定义属性。
父组件的数据需要通过 props 把数据传给子组件,子组件需要显式地用 props 选项声明 “prop”
需要注意的是: prop 是单向绑定的,即当父组件的属性变化时,将传导给子组件,但是不会反过来。
<body>
<div id="main">
<input type="text" v-model="fatherMessage"/><br />
<!-- hello 通过 动态绑定传值-->
<child message="one" v-bind:hello='fatherMessage'></child>
</div>
</body>
<script type="text/javascript" src="js/vue.min.js"></script>
<script>
Vue.component("child", {
// 父组件传递给子组件需要用Prop来传值
props: ['message', 'hello'],
template: "<h1>{{ message + ' ' + hello}}</h1>"
})
// 必须要绑定一下id,否则不会显示
var v = new Vue({
el: "#main",
data:{
fatherMessage : ""
}
})
</script>
4. Prop的验证 : 组件可以为 props 指定验证要求。
Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
5. 自定义事件: 父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!
我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:
使用 $on(eventName) 监听事件
使用 $emit(eventName) 触发事件
另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
<body>
<div id="main">
<h1 > {{ total }} </h1>
<!-- 通过$emit()发送的函数名对应此处,在对应父组件的sum函数 -->
<child v-on:childevent="sum"></child> +
<child v-on:childevent="sum"></child>
</div>
</body>
<script type="text/javascript" src="js/vue.min.js"></script>
<script>
Vue.component("child", {
template: "<button @click='incrementNum'>{{ counter }}</button>",
// 模板类型data数据要是一个函数返回的data对象,这样使得每个模板都单独的data数据对象。
// 重复使用时不会产生数据冲突
data: function() {
return {
counter: 0
}
},
methods: {
// 子组件点击调用此函数
incrementNum: function() {
this.counter += 1;
// 发送数据,注意这里的函数名可以使用one-two 或纯字母,但不能使用驼峰规则
// 通过这种方式将counter发送给父组件
this.$emit('childevent', this.counter);
}
}
})
// 必须要绑定一下id,否则不会显示
var v = new Vue({
el: "#main",
data: {
total: 0
},
methods:{
// 接收从子组件发送的数据
sum :function(counter){
console.log("这是从子组件传过来的参数值,可以通过这种方式传值 : " + counter)
this.total += 1;
}
}
})
</script>
- 定义组件时,template可以写在外面。只要给template定义一个id,注册组件的时候,引用这个id即可
<template id='aaa'></template>
new Vue({
el : '#app',
components: {
'aaa' : {
template:'#aaa'
}
}
- 父获取子数据:通过$emit和v-on。子获取父数据:通过props和v-bind
6. .Vue文件解析
1. 配置:
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-runtime": "^6.26.0",
"css-loader": "^0.28.9",
"vue-hot-reload-api": "^1.3.2",
"vue-html-loader": "^1.2.4",
"vue-loader": "^8.5.4",
"vue-style-loader": "^3.1.2",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.11.1"
},
"dependencies": {
"vue": "^1.0.28"
}
2. 模板的引用:实际项目中可以创建多个组件文件,创建一个 components 目录,并将每个组件放置在其各自的文件中。
在一个假设的 ComponentB.js 或 ComponentB.vue 文件中: 通过以下操作, 可以将组件A和组件C引入在组件B中使用了。
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
3. .Vue模板的定义:
<template>
<!-- 这里面写样式 -->
<div>
<!-- 使用script里面的数据或者方法 -->
{{ a }}
<slot></slot>
</div>
</template>
<script>
import AA from "...."; // 引入外部文件
export default{
// 定义data数据
data(){
return{
a : ''
}
},
// 定义组件所拥有的方法
methods {
},
// 继续定义别的内容
....
}
</script>
<!-- 不加上 scoped Style设置的属性不起作用似乎-->
<style scoped>
</style>
7. 插槽: 官方解释
1. 匿名插槽(名称与具名插槽相对应而起的名字)。 在组件中只能出现一次
简单代码:
<!-- 自定义组件 -->
<template id="url">
<a :href='url'>
<slot></slot> // 渲染是会将<slot></slot>标签替换成"你好啊"。即父组件中调用时的内容
</a>
</template>
<body>
<div id='main'>
<myurl>你好啊</myurl>
</div>
<script src='js/vue.min.js'></script>
<script>
Vue.component("myurl", {
template : '#url',
data:function(){
return {
url : "https://www.baidu.com"
}
}
});
var v = new Vue({
el: "#main"
})
</script>
</body>
注意: 如果 组件中 没有包含一个 元素,则任何传入它的内容都会被抛弃。
2. 具名插槽: 通过插槽名称来指定将数据插入在何处。
<template id="url">
<!-- 组件要求只能有一个根元素,所以这里必须要加上div作为根元素-->
<div class="container">
<a :href='url'>
<!-- one 这里是默认插槽内容 -->
<slot name="second">one</slot>
</a>
<a :href='url'>
<slot name="first"></slot>
</a>
</div>
</template>
<body>
<div id='main'>
<myurl>
<!-- 将first 放在name为 first 的插槽中-->
<h1 slot="first">first</h1>
<h1 slot="second">second</h1>
</myurl>
</div>
<script src='js/vue.min.js'></script>
<script>
Vue.component("myurl", {
template: '#url',
data: function() {
return {
url: "https://www.baidu.com"
}
}
});
var v = new Vue({
el: "#main"
})
</script>
</body>
2.x版本的写法:
- 作用域插槽: 以上两种父组件需要提供数据和样式,而作用域插槽则是样式由父组件提供,数据则显示由子组件提供的
<body>
<div id="main">
<child>
<template slot-scope="user">
<div>{{ user.data }}</div>
</template>
</child>
</div>
</body>
<!-- 子组件 理论上来说应该将子组件写成Vue文件,然后再引入 -->
<template id="child">
<div>
<h1>这里是子组件</h1>
<div>
<slot :data="data">啊啊啊</slot>
</div>
</div>
</template>
<script type="text/javascript" src="js/vue.min.js"></script>
<script>
var v = new Vue({
el: "#main",
components: {
'child': {
template: "#child",
data: function() {
return {
data:["张三", "李四", "王五"]
}
}
}
}
})
</script>
效果如图