简介
这是跟着官网中文文档走到组件基础之前的记录。(是否已经设计组件一点点了)
开始学习
导航:
- 1.hello world
- 2.指令带有前缀 v-
- 3.控制切换一个元素是否显示也相当简单:v-if
- 4.v-for 指令可以绑定数组的数据来渲染一个项目列表
- 5.v-on 指令添加一个事件监听器
- 6.v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。
- 7.注册组件很简单:
- 8.阻止修改现有的属性
- 9.一些有用的实例属性与方法(先学习了俩个)
- 10.钩子
- 11.插值
- 12.v-bind指令主要用于属性绑定
- 13.内容与属性中使用javascript表达式的方法
- 14.动态参数
- 15.计算属性
- 16.侦听属性
- 17.声明组件
- 18.v-if 条件渲染
- 19.用 key 管理可复用的元素
- 20.v-for指令
- 21.数组更新和数组的方法
- 22.对象更改检测
- 23.想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据
- 24.一段取值范围的 v-for
- 25.利用带有 v-for 的 <template> 渲染多个元素
- 26.不推荐同时使用 v-if 和 v-for 但是可以实现效果如下
- 27.Vue 的修饰符(后面应该有介绍)
- 28.事件处理方法
- 29.事件修饰符 : 由点开头的指令后缀来表示的
- 30.按键修饰符
- 31.用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
- 32.表单输入绑定 v-model
- 33.v-model 的修饰符
- 34.积累的知识点:
首先html模板 一个名字叫 demo.css文件 demo.js文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue.js学习笔记</title>
<!--引入Vue.js-->
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="demo.css" />
</head>
<body>
/*****以下的html板块代码粘贴在此 能看运行效果*****/
/**********/
<script src="demo.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
/*以下是demo.css*/
.box{
border:1px dashed #f0f;
}
.textColor{
color:#f00;
background-color:#eef;
}
.textSize{
font-size:20px;
font-weight:bold;
}
.color1{
color: red;
}
.color2{
color: blue;
}
.parent{
width: 100px;
height: 100px;
background-color: red;
}
.son{
width: 50px;
height: 50px;
background-color: bisque;
}
hello world
<!--html代码
1
hello world
-->
<div id="app">
{{message}}
</div>
//js代码
var app = new Vue({
//绑定id
el: '#app',
//数据
data: {
message: 'helll world! '
}
});
指令带有前缀 v-
<!--
2
指令带有前缀 v-
将这个元素节点的 title 特性和 Vue 实例的 message 属性保持一致
-->
<div id="app-2">
<span v-bind:title="message">
鼠标悬停几秒钟查看此处动态绑定的提示信息!
</span>
</div>
//2
var app2 = new Vue({
el: '#app-2',
data: {
message: '页面加载于 ' + new Date().toLocaleString()
//这个中间的空格不能少一个
}
})
控制切换一个元素是否显示也相当简单:v-if
<!--
3
控制切换一个元素是否显示也相当简单:v-if
在控制台输入 app3.seen = false,你会发现之前显示的消息消失了。
-->
<div id="app-3">
<p v-if="seen">现在你看到我了</p>
</div>
//3
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
v-for 指令可以绑定数组的数据来渲染一个项目列表
<!--
4
v-for 指令可以绑定数组的数据来渲染一个项目列表:
在控制台里,输入 app4.todos.push({ text: '新项目' }),你会发现列表最后添加了一个新项目。
-->
<div id="app-4">
<ol>
<li v-for="x in arrays">
{{ x.text }}
</li>
</ol>
</div>
//4
var app4 = new Vue({
el: '#app-4',
data: {
arrays: [
{ text: '学习 javaScript' },
{ text: '学习Vue' },
{ text: '学习Css' }
]
}
})
v-on 指令添加一个事件监听器
<!--
5
v-on 指令添加一个事件监听器
-->
<div id="app-5">
<p>{{message}}</p>
<button v-on:click="reverseMessage">逆转消息</button>
</div>
//5
/*
* 1:arrayObject.reverse()
* 注意: 该方法会改变原来的数组,而不会创建新的数组。
* 2:arrayObject.join()
* 注意:join() 方法用于把数组中的所有元素放入一个字符串。
* 元素是通过指定的分隔符进行分隔的。
* 指定分隔符方法join("#");其中#可以是任意
* 3:stringObject.split(a,b)这是它的语法
* 方法:用于把一个字符串分割成字符串数组.
* a是必须的决定个从a这分割
* b不是必须的,可选。该参数可指定返回的数组的最大长度 。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
* 注意:返回的数组中不包括a本身;
* 提示和注释:
* 注释:如果把空字符串 ("") 用作 a,那么 stringObject 中的每个字符之间都会被分割。
* 注释:String.split() 执行的操作与 Array.join 执行的操作是相反的。
*/
var app5 = new Vue({
el: '#app-5',
data: {
message: 'hello Vue.js'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。
<!--
6
v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。
-->
<div id="app-6">
<p>{{message}}</p>
<input type="text" name="" id="" value="" v-model="message" />
</div>
//6
var app6 = new Vue({
el: '#app-6',
data: {
message: 'hello Vue'
}
})
注册组件很简单:
<!--
7
一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单:
子单元通过 props 接口与父单元进行了良好的解耦
-->
<div id="app-7">
<ol>
<!--
现在我们为每个 todo-item 提供 todo 对象
todo 对象是变量,即其内容可以是动态的。
我们也需要为每个组件提供一个“key”,稍后再
作详细解释。
相当于通过props接口让 todo = item
-->
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
//7
// 定义名为 todo-item 的新组件
Vue.component('todo-item', {
// todo-item 组件现在接受一个
// "props",类似于一个自定义特性。
// 这个 props 名为 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: '随便其它什么人吃的东西' }
]
}
})
阻止修改现有的属性
<!--
8
数据与方法 使用 Object.freeze()(冻结对象),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。
-->
<div id="app-8">
<p>{{foo}}</p>
<!-- 这里的 `foo` 不会更新!在js中取消冻结就可以更新了 -->
<button v-on:click="foo = 'zyx'">点击不更新</button>
</div>
//8
/******************数据与方法**********************/
//我们的数据对象
data = { a:1}
//将对象加入到一个Vue实例中
var vm = new Vue({
data: data
})
// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3
//当这些数据改变时,视图会进行重渲染。值得注意的是只有当实例被创建时 data 中存在的属性才是响应式的。
//也就是说如果你添加一个新的属性,比如:
vm.c = 'hello'
//那么对 c 的改动将不会触发任何视图的更新。如果你知道你会在晚些时候需要一个属性,但是一开始它为空或不存在,
//那么你仅需要设置一些初始值。比如:
datas = {
newTodoText:"",
visitCount:0,
hideCompletedTodos:false,
todos:[],
error:null
}
var vm1 = new Vue({
data: datas
})
//这里唯一的例外是使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。
//Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属
var obj = {foo: 'wg'}
//冻结操作
Object.freeze(obj);
new Vue({
el: '#app-8',
data: obj
})
一些有用的实例属性与方法(先学习了俩个)
<!--
9
一些有用的实例属性与方法。它们都有前缀 $,以便与用户定义的属性区分开来
有很多 见:https://cn.vuejs.org/v2/api
-->
<!--
(1)vm.$watch观察 Vue 实例变化的一个表达式或计算属性函数
-->
<div id='app-9-1'>
<p>输入firstName后,wacth监听每次修改变化的新值,然后计算输出fullName。</p>
<p>FullName: {{fullName}}</p>
<p>FirstName: <input type="text" v-model="firstName"></p>
<!--验证deep属性-->
<p>boj.a: {{obj.a}}</p>
<p>obj.a改变成 <input type="text" name="" id="" value="" v-model="obj.a"/></p>
</div>
<!--
(2)Vue.extend( options )
-->
<div id="mount-point"></div>
//9
//9-(1)
var vm2 = new Vue({
el: '#app-9-1',
data: {
firstName: 'wg',
lastName: 'zyx',
fullName: '',
obj:{
a:123
}
},
watch: {
firstName:{
handler(newName,oldName){
this.fullName = newName + ' ' + this.lastName;
},
//handler方法和immediate属性
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
immediate: true
},
//这里采用字符串的形式监视 这样Vue.js才会一层一层解析下去,直到遇到属性a,然后才给a设置监听函数。
'obj.a':{
handler(newobj,oldobj){
console.log('obj.a has changed');
},
immediate: true,
//deep: true
}
}
})
//没写在组件中的watch需要手动销毁 vm2.$watch 返回一个取消观察函数,用来停止触发回调:
var unwatch = vm2.$watch('fullName',function(newValue,oldValue){
// 这个回调将在 `vm.fullname` 改变后调用
console.log('fullName改变了');
})
//销毁 你要注销 watch 只要调用unWatch方法就可以了
unwatch();
//9-(2)
//Vue.extend( options )
//参数:
//{Object} options
//用法:
//使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
//data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
//这只是data 3中写法的一种
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
钩子
<!--
10
created 钩子可以用来在一个实例被创建之后执行代码:
mounted 钩子 el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
updated 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
destroyed Vue 实例销毁后调用。
-->
<div id="app-10">
<p>{{message}}</p>
</div>
//10
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
var app10 = new Vue({
el: '#app-10',
data: {
message: 'I love zyx'
},
beforeCreate: function() {
console.group('beforeCreate 创建前状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data);//undefined
console.log("%c%s", "color:red", "message: " + this.message)//undefined
console.groupEnd();
},
created: function() {
console.group('created 创建完毕状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el); //undefined
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 [object Object]
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 I love zyx
console.groupEnd();
},
beforeMount: function() {
console.group('beforeMount 挂载前状态===============》');
console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化 [object HTMLDivElement]
console.log(this.$el);//<div id="app-10"><p>{{message}}</p></div>
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 [object Object]
console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 : I love zyx
console.groupEnd();
},
mounted: function() {
console.group('mounted 挂载结束状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化 [object HTMLDivElement]
console.log(this.$el);//<div id="app-10"><p>{{message}}</p></div>
console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 [object Object]
console.log("%c%s", "color:red", "message: " + this.message);//已被初始化 : I love zyx
console.groupEnd();
},
beforeUpdate: function() { //控制台输入app10.message = 'yes'
console.group('beforeUpdate 更新前状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.groupEnd();
},
updated: function() {
console.group('updated 更新完成状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.groupEnd();
},
beforeDestroy: function() {//输入app10.$destroy(); 再输入app10.message = 'no' 发现并没有更新事件
console.group('beforeDestroy 销毁前状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.groupEnd();
},
destroyed: function() {
console.group('destroyed 销毁完成状态===============》');
console.log("%c%s", "color:red", "el : " + this.$el);
console.log(this.$el);
console.log("%c%s", "color:red", "data : " + this.$data);
console.log("%c%s", "color:red", "message: " + this.message);
console.groupEnd();
}
})
插值
<!--
11
插值 1.{{}} 其中 <span v-once>这个将不会改变: {{ msg }}</span> 加入v-once指令 只渲染元素和组件一次 用于优化更新性能。
2.插入原始html
-->
<div id="app-11">
<p>没用v-html指令{{message}}</p>
<span>用了v-html指令</span><span v-html="message"></span>
</div>
//11
var app11 = new Vue({
el: '#app-11',
data: {
message: '<span style="color:red">red</span>'
}
})
v-bind指令主要用于属性绑定
<!--
12
v-bind指令主要用于属性绑定
-->
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
<!--绑定HTML Class-->
<div id="app-12">
<ul class="box" v-bind:class="{'textColor':isColor, 'textSize':isSize}">
<li>学习Vue</li>
<li>学习Node</li>
<li>学习React</li>
</ul>
</div>
<!--对于多个class : <div v-bind:class="[classA, { classB: isB, classC: isC }]"> -->
//12
//v-bind class属性动态绑定
var app12 = new Vue({
el: '#app-12',
data: {
isColor:true,
isSize: true
}
})
内容与属性中使用javascript表达式的方法
<!--
13
内容与属性中使用javascript表达式的方法
-->
<div id="app-13">
<p>{{n}}</p>
<!--内容直接写{{n+3}}-->
<p>{{n+3}}</p>
<!--三目运算-->
<p>{{ok?'yes':'no'}}</p>
<!--js函数-->
<p>{{ message.split('').reverse().join('') }}</p>
<!--改变class-->
<p :class="'color'+(n+1)">我的颜色</p>
</div>
//13
var app13 = new Vue({
el: '#app-13',
data: {
n:1,
ok:true,
message:'I love zyx'
}
})
动态参数
<!--
14
动态参数 强制转换成小写哦
这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data 属性 attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href
-->
<div id="app-14">
<a v-bind:[attributeName]="url"> 一个链接</a>
</div>
//14
var app14 = new Vue({
el: '#app-14',
data: {
attributename: 'href',
url: '#'
}
})
计算属性
<!--
15
计算属性
computed
-->
<div id="app-15">
<p>{{reverseString}} 时间 : {{now}}</p>
</div>
//15
var app15 = new Vue({
el: '#app-15',
data: {
string: 'I love zyx'
},
computed: {
// 计算属性的 getter
reverseString: function(){
// `this` 指向 vm 实例
return this.string.split('').reverse().join('')
},
//计算属性将不再更新,因为 Date.now() 不是响应式依赖
now: function () {
return Date.now()
}
}
})
console.log(app15.reverseString)//xyz evol I
app15.string = 'Goodbye'
console.log(app15.reverseString)//eybdooG
侦听属性
<!--
16 运行缺少俩个js哦 具体百度把 这里看一下方法就好
侦听属性
watch
-->
<!--
<div id="app-16">
<p>
Ask a yes/no question:
<input v-model="question">
</p>
<p>{{ answer }}</p>
</div>
-->
//16
/*
var app16 = new Vue({
el: '#app-16',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
created: function () {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
// 请参考:https://lodash.com/docs#debounce
this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
},
methods: {
getAnswer: function () {
if (this.question.indexOf('?') === -1) {
this.answer = 'Questions usually contain a question mark. ;-)'
return
}
this.answer = 'Thinking...'
var vm = this
axios.get('https://yesno.wtf/api')
.then(function (response) {
vm.answer = _.capitalize(response.data.answer)
})
.catch(function (error) {
vm.answer = 'Error! Could not reach the API. ' + error
})
}
}
})
*/
声明组件
<!--
17
声明组件
-->
<div id="app-17">
<app></app>
</div>
//17
Vue.component("button-counter", {
data: function() {
return {
count: 0
};
},
template:
'<button v-on:click="count++">You clicked me {{ count }} times.</button>'
});
Vue.component("app", {
data: function() {
return {
count: 0
};
},
template:
'<div> <h1>app新的组件</h1><button @click="insert">点我新成新的组件</button> <div id="appId"> </div></div>',
methods: {
insert() {
const component = Vue.component("button-counter");
const instance = new component();
instance.$mount("#appId");
}
}
});
var app17 = new Vue({
el: "#app-17"
});
v-if 条件渲染
<!--
18
v-if 条件渲染
-->
<div id="app-18">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
</div>
//18
var app18 = new Vue({
el: '#app-18',
data: {
type: 'B'
}
})
//控制台输入 app18.type = 'C'
用 key 管理可复用的元素
<!--
19
用 key 管理可复用的元素
下面不加 key 在输入框输入后 再改变type
<input> 不会被替换掉输入的内容 仅仅是替换了它的 placeholder
template模板
-->
<div id="app-19">
<template v-if="type === 'username'">
<label>UserName</label>
<input type="text" placeholder="输入用户名" key="username-input"/>
</template>
<template v-else="type === 'password'">
<label>PassWord</label>
<input type="text" placeholder="输入密码" key="password-input"/>
</template>
</div>
//19
var app19 = new Vue({
el: '#app-19',
data:{
type: 'username'
}
})
v-for指令
<!--
20
v-for指令
我们用 v-for 指令根据一组数组的选项列表进行渲染。v-for 指令需要使用 item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。
也可以用 of 替代 in 作为分隔符
在 v-for 块中,我们拥有对父作用域属性的完全访问权限。v-for 还支持一个可选的第二个参数为当前项的索引
-->
<div id="app-20">
<ul>
<li v-for="(item,index) in items">
{{parenttext}} - {{index}} - {{item.text}}
</li>
</ul>
<ul>
<!--一个对象的 v-for (1)-->
<li v-for="value of object">
{{value}}
</li>
</ul>
<!--一个对象的 v-for (2)-->
<ul>
<li v-for="(value,key) of object">
{{key}} : {{value}}
</li>
</ul>
<!--一个对象的 v-for (2)-->
<ul>
<li v-for="(value,key,index) of object">
{{index}} - {{key}} : {{value}}
</li>
</ul>
<!--
建议加上key
不要使用对象或数组之类的非原始类型值作为 v-for 的 key。用字符串或数类型的值取而代之。
<div v-for="item in items" :key="item.id">
内容
</div>
-->
</div>
//20
var app20 = new Vue({
el: '#app-20',
data: {
parenttext: 'Parent',
items: [
{text: 'wg'},
{text: 'zyx'}
],
object: {
first: 'Num1',
second: 'Num2',
third: 'Num3'
}
}
})
数组更新和数组的方法
<!--
21
数组更新和数组的方法
变异方法
push()方法可向数组的末尾添加一个或多个元素,并返回新的长度。 app20.items.push({text: 'love'})
pop()方法用于删除并返回数组的最后一个元素。 app20.items.pop()
shift()方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。app20.items.shift()
unshift()方法可向数组的开头添加一个或更多元素,并返回新的长度。app20.items.unshift({text: 'wg'})
splice()方法向/从数组中添加/删除项目,然后返回被删除的项目。app20.items.splice(0,2,{text: 'love'})
splice(index,howmany,item1,.....,itemX)
参数 描述
index 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
howmany 必需。要删除的项目数量。如果设置为 0,则不会删除项目。
item1, ..., itemX 可选。向数组添加的新项目。
sort()方法用于对数组的元素进行排序。
reverse()方法用于颠倒数组中元素的顺序。app20.items.reverse()
替换数组
这些不会改变原始数组,但总是返回一个新数组。
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
example1.items = example1.items.filter(function (item) { return item.message.match(/Foo/) })
concat() 方法用于连接两个或多个数组。
slice() 方法可从已有的数组中返回选定的元素。
其他
split() 方法用于把一个字符串分割成字符串数组。
注意事项
var vm = new Vue({
data: {
items: [
'a',
'b',
'c'
]
}
})
- > 问题一
vm.items[1] = 'x' // 不是响应性的
- > 问题二
vm.items.length = 2 // 不是响应性的
解决第一个问题的俩个方法:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
解决第二个问题的方法
vm.items.splice(newLength)
-->
对象更改检测
<!--
22
对象更改检测
Vue 不能检测对象属性的添加或删除 怎么办呢
需要用到 Vue.set(object, key, value) 例子:
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
你可以添加一个新的 age 属性到嵌套的 userProfile 对象:
Vue.set(vm.userProfile, 'age', 27)
你还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:
vm.$set(vm.userProfile, 'age', 27)
假如你需要添加多个新的响应式属性 就需要用到javascript的Object.assign() 方法
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
-->
想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据
<!--
23
想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据
在这种情况下,可以创建返回过滤或排序数组的计算属性。
在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个 method 方法
-->
<div id="app-23">
<li v-for="x in event1">
{{x}}
<!--自以为的嵌套-->
<li v-for="y in event2(numbers)">
{{y}}
</li>
</li>
</div>
//23
var app23 = new Vue({
el: '#app-23',
data: {
numbers: [1,2,3,4,5,6,7,8,9],
flag: 6
},
computed: {
event1: function() {
return this.numbers.filter(function (num){
return num % 2 === 0
})
}
},
methods: {
//注意这里
event2: function(numbers) {
return numbers.filter(function(number) {
return number % 2 === 1
})
}
}
})
一段取值范围的 v-for
<!--
24
一段取值范围的 v-for
必须还是有绑定的app-24 Vue函数
-->
<div id="app-24">
<span v-for="w in 10">{{w}}</span>
</div>
//24
var app24 = new Vue({
el: '#app-24',
})
利用带有 v-for 的 <template> 渲染多个元素
<!--
25
利用带有 v-for 的 <template> 渲染多个元素
输出v-for 下面的很多个 不像app-23那个自以为的嵌套循环
-->
<div id="app-25">
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li>我每次都会出现哦</li>
</template>
</ul>
</div>
//25
var app25 = new Vue({
el: '#app-25',
data: {
items: [
{msg:1},
{msg:2},
{msg:3}
]
}
})
不推荐同时使用 v-if 和 v-for 但是可以实现效果如下
<!--
26
不推荐同时使用 v-if 和 v-for 但是可以实现效果如下
输出非零数
-->
<div id="app-26">
<span v-for="todo in todos" v-if="todo">
{{ todo }}
</span>
</div>
//26
var app26 = new Vue({
el: '#app-26',
data: {
todos:[1,0,2,0,4]
}
})
Vue 的修饰符(后面应该有介绍)
<!--
27
-->
<div id="app-27">
<!--Vue 的修饰符(后面应该有介绍)这里意思是: 提交事件(即:addNewTodo)不再重载页面 -->
<form v-on:submit.prevent="addNewTodo">
<label>Add a todo</label>
<!--
v-model="newTodoText" input控件或者组件上创建双向绑定
-->
<input v-model="newTodoText" placeholder="请输入创建的文字">
<button>Add</button>
</form>
<ul>
<li is="todo-item" v-for="(todo, index) in todos" v-bind:key="todo.id" v-bind:title="todo.title" v-on:remove="todos.splice(index, 1)"></li>
</ul>
<!--这里的 is="todo-item" 属性。这种做法在使用 DOM 模板时是十分必要的,
因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,
但是可以避开一些潜在的浏览器解析错误。
v-bind:key="todo.id" -> 使用了todo.id作为绑定的key值
v-bind:title="todo.title" title规定元素的额外信息,鼠标移上去可见 这里将todo.title与这个元素节点的 title绑定
v-on:remove="todos.splice(index, 1)" 绑定 remove时间 remove具体事件是什么? 就是- > todos.splice(index, 1)
-->
</div>
//27
//v-on:click="$emit(\'remove\')"
//当点击时$emit()触发当前实例上的事件
//然而当前事件是什么呢?
//传给一个字符串 这里\'remove\'转义表示是字符串
//谁在监听这个字符串 它就会被触发
//父组件可以使用 props 把数据传给子组件。
//子组件可以使用 $emit 触发父组件的自定义事件。
//有props是子组件
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
})
new Vue({
el: '#app-27',
data: {
newTodoText: '',
todos: [
{
id: 1,
title: '我是1',
},
{
id: 2,
title: '我是2',
},
{
id: 3,
title: '我是3'
}
],
nextTodoId: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
})
事件处理方法
<!--
28
事件处理方法 格式如下:
v-on:(触发动作)=(一个需要调用的方法名称)
-->
<div id="app-28">
<button v-on:click.prevent="greet($event)">Click me</button>
</div>
//28
var app28 = new Vue({
el: '#app-28',
methods: {
greet: function(event){
if(event)
alert(event.target.tagName);
else{
alert("javascript调用的");
}
}
}
})
//也可以用 JavaScript 直接调用方法 但是没有DOM事件
//app28.greet();
//event是原生 DOM 事件
//e.target 取得的是事件发生的对象,即事件源,它是 DOM 对象。
//tagName 是 DOM 对象的属性,用于获取 DOM 对象的标签名,取出来是大写的,
//你要取小写的用 nodeName。或者用toLowerCase()把tagName转换成小写之后再进行比较。
事件修饰符 : 由点开头的指令后缀来表示的
<!--
29
事件修饰符 : 由点开头的指令后缀来表示的。
用于DOM的事件处理,常用的事件修饰符有以下几个:
-->
<!--. stop:阻止冒泡(通俗讲就是阻止事件向上级DOM元素传递)下面例子:-->
<div id="app-29">
<div class="parent" v-on:click="parentevent">
点parent
<div class="son" v-on:click="sonevent">
点son
</div>
</div>
<!--点击son控制台出现
我是son的点击事件
我是parent的点击事件
点击parent控制台出现
我是parent的点击事件
说明son的点击事件向上传递了,parent误认为它也被点击了
所以在son的点击事件加上.stop就解决了 =>
v-on:click.stop="sonevent"
-->
<!--
. prevent:阻止默认事件的发生
比如点击超链接的时候会进行页面的跳转,点击表单提交按钮时会重新加载页面主要用在这俩个
-->
<a href="www.baidu.com" @click.prevent>去不了百度</a>
<!--. self:将事件绑定到自身,只有自身才能触发
. once:设置事件只能触发一次,比如按钮的点击等-->
</div>
//29
var app29 = new Vue({
el: '#app-29',
methods: {
parentevent: function(){
console.log("我是parent的点击事件");
},
sonevent: function(){
console.log("我是son的点击事件");
},
}
})
按键修饰符
<!--
30
按键修饰符
在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
-->
<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->
<div id="app-30">
<input v-on:keyup.enter="submit" placeholder="只有按下enter才有对话框">
<!--当然任意有效按键名都可以-->
<input v-on:keyup.y="submity" placeholder="只有按下y才有对话框">
</div>
//30
var app30 = new Vue({
el: '#app-30',
methods: {
submit: function(){
alert("你按下了enter键");
},
submity: function(){
alert("你按下了y键");
}
}
})
用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
<!--
31
用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
.ctrl
.alt
.shift
.meta 对应 command 键 (⌘)Mac系统的
.exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
即使 Alt 或 Shift 被一同按下时也会触发 即click + ctrl + alt/shift
<button @click.ctrl="onClick">A</button>
有且只有 Ctrl 被按下的时候才触发
<button @click.ctrl.exact="onCtrlClick">A</button>
没有任何系统修饰符被按下的时候才触发
<button @click.exact="onClick">A</button>
标按钮修饰符
.left
.right
.middle
-->
<div id="app-31">
<!-- Alt + C 67是按键码 百度一下你知道更多-->
<input v-model="msg" @keyup.alt.67="clear">Alt + C清空
<!-- Ctrl + Click
<div @click.ctrl="doSomething">Do something</div> -->
</div>
//31
var app31 = new Vue({
el: '#app-31',
data: {
msg: "初始值"
},
methods: {
clear: function() {
this.msg = ''
alert("已清空");
}
}
})
表单输入绑定 v-model
<!--
32
表单输入绑定 v-model
<input v-model="message">单行输入框的输入与message双向绑定
<textarea v-model="message"></textarea>多行输入框的输入与message双向绑定
<input type="checkbox" v-model="checked">单个复选框,绑定到布尔值 -> 见(1)
<input type="checkbox" v-model="array">多个复选框,绑定到同一个数组: -> 见(2)
<input type="radio" value="One" v-model="picked">单选按钮和单个复选框差不多 ->(3)
<select v-model="selected"></select>单选选择框 ->(4)
<select v-model="selectarrayed" multiple style="width: 50px;"></select> 多项选择框 绑定到一个数组 -> (5)
用 v-for 渲染的动态选项 -> (6)重点掌握
值绑定 用 v-bind (6)实现值绑定到 Vue 实例的一个动态属性 下面是一些静态字符串绑定
当选中时,`picked` 为字符串 "a"
<input type="radio" v-model="picked" value="a">
toggle` 为 true 或 false
<input type="checkbox" v-model="toggle">
当选中第一个选项时,`selected` 为字符串 "abc"
<select v-model="selected">
<option value="abc">ABC</option>
</select>
复选框的另一种写法: -> (7)
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no">
当选中时 vm.toggle === 'yes'
当没有选中时 vm.toggle === 'no'
-->
<div id="app-32">
<!--(1)-->
<input type="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<!--(2)-->
<br>
<input type="checkbox" value="Jack" v-model="array">
<label for="jack">Jack</label>
<input type="checkbox" value="John" v-model="array">
<label for="john">John</label>
<input type="checkbox" value="Mike" v-model="array">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ array }}</span>
<!--(3)-->
<br>
<input type="radio" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
<!--(4)-->
<br>
<select v-model="selected">
<option disabled value="">请选择</option>
<!--如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。
在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。
因此,更推荐像上面这样提供一个值为空的禁用选项。-->
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{selected}}</span>
<!--(5) multiple属性规定可同时选择多个选项
对于 windows:按住 Ctrl 按钮来选择多个选项
对于 Mac:按住 command 按钮来选择多个选项-->
<br>
<select v-model="selectarrayed" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>按住ctrl/command多选 Selectarrayed: {{ selectarrayed }}</span>
<!--(6)-->
<br>
<select v-model="vForSelected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>vForSelected: {{ vForSelected }}</span>
<!--(7) 在控制台输入console.log(app32.toggle)可以看到-->
<br>
<input type="checkbox" v-model="toggle" true-value="yes" false-value="no">
</div>
//32
var app32 = new Vue({
el: '#app-32',
data: {
checked: false,
array: [],
picked: '',
selected: '',
selectarrayed: [],
vForSelected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
],
toggle: ''
}
})
v-model 的修饰符
<!--
33
v-model 的修饰符
.lazy 在输入框中,v-model 默认是同步数据,使用 .lazy 会转变为在 change 事件中同步 ,也就是在失去焦点 或者 按下回车键时才更新
.number 修饰符可以将 输入的值转化为Number类型 ,否则虽然你输入的是数字 但它的类型其实是String,在数字输入框中比较有用
.trim 修饰符会自动过滤掉输入的首尾空格
-->
<div id="app-33">
<input v-model.lazy="msg1">
<p>数据是:{{msg1}}</p>
<!--限定只能输入Number-->
<input type="number" v-model.number="msg2">
<p>数据类型是:{{typeof(msg2)}}</p>
<input v-model.trim="msg3">
<p>数据长度是:{{msg3.length}}</p>
</div>
//33
var app33 = new Vue({
el: '#app-33',
data: {
msg1: '',
msg2: '',
msg3: ''
}
})
积累的知识点:
1.所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)。
2.指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
3.指令特性的值预期是单个 JavaScript 表达式 (v-for 是例外情况)
4.v-on 缩写 <a v-on:click="doSomething">...</a> <a @click="doSomething">...</a>
5.v-if 和 v-show 不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;
如果在运行时条件很少改变,则使用 v-if 较好。
6.建议尽可能在使用 v-for 时提供 key,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的
7.请不要用带中横线的名字做方法名称
8.v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。
你应该通过 JavaScript 在组件的 data 选项中声明初始值。