Vue
1. 常用命令
1.1 v-bind
用于绑定元素属性
1.2 v-if
<div id="app-3">
<p v-if="seen">现在你看到我了</p>
</div>
var app3 = new Vue({
el: '#app-3',
data: {
seen: true
}
})
Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
那么在上面的代码中切换 loginType
将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input>
不会被替换掉——仅仅是替换了它的 placeholder
。
这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key
attribute 即可:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
现在,每次切换时,输入框都将被重新渲染。
注意,<label>
元素仍然会被高效地复用,因为它们没有添加 key
attribute。
v-if一般不与v-for在同一元素上连用
1.3 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: '整个牛项目' }
]
}
})
对于todos的操作如下:
app4.todos.push({text: '添加一个下项目'})
在 v-for
块中,我们可以访问所有父作用域的 property。v-for
还支持一个可选的第二个参数,即当前项的索引。
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
data: {
parentMessage: 'Parent',
items: [
{message: 'Foo'},
{message: 'Bar'}
]
}
结果:
- Foo
- Bar
你也可以用 v-for
来遍历一个对象的 property。
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: A',
author: 'B',
publishedAt: 'C'
}
}
})
结果:
- A
- B
- C
你也可以提供第二个的参数为 property 名称 (也就是键名):
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
结果:
name:A
name:B
name:C
有关key和v-for结合使用的相关描述
2.2.0+ 的版本里,当在组件上使用
v-for
时,key
现在是必须的。
https://cn.vuejs.org/v2/api/#key
为什么要加key
https://www.jianshu.com/p/4bd5e745ce95
1.4 v-once
<span v-once>这个将不会改变: {{ msg }}</span>
通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:
1.5 钩子函数
如 mount/create等函数,可以在vue实例的生命周期中插入相关操作
1.6 箭头函数
实际上和java的λ表达式一样,但是在vue中比较多特殊的是不绑定this
var elements = [
'Hydrogen',
'Helium',
'Lithium',
'Beryllium'
];
elements.map(function(element) {
return element.length;
}); // 返回数组:[8, 6, 7, 9]
// 上面的普通函数可以改写成如下的箭头函数
elements.map((element) => {
return element.length;
}); // [8, 6, 7, 9]
// 当箭头函数只有一个参数时,可以省略参数的圆括号
elements.map(element => {
return element.length;
}); // [8, 6, 7, 9]
// 当箭头函数的函数体只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号
elements.map(element => element.length); // [8, 6, 7, 9]
// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,而 `lengthFooBArX` 则只是个变量名,
// 可以替换成任意合法的变量名
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
1.7 v-html
将文本内容按照html代码解析
<p>例如: {{ rawHtml }}</p>
<p>例如: <span v-html="rawHtml"></span></p>
输出如下
例如:hh
例如:hh //这里的hh是红色的
不推荐使用
1.8 []
从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:
<a v-bind:[attributeName]="url"> ... </a>
这里的 attributeName
会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data
property attributeName
,其值为 "href"
,那么这个绑定将等价于 v-bind:href
。
同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:
<a v-on:[eventName]="doSomething"> ... </a>
在这个示例中,当 eventName
的值为 "focus"
时,v-on:[eventName]
将等价于 v-on:focus
。
1.9 修饰符
修饰符 (modifier) 是以半角句号 .
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent
修饰符告诉 v-on
指令对于触发的事件调用 event.preventDefault()
:
<form v-on:submit.prevent="onSubmit">...</form>
preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交)。
1.10 v-bind:class
用来动态切换clss,text-danger是普通的class attribute
<div
class="classA"
:class="classB: isActive,'text-danger': hasErr"
></div>
data: {
isActive: true,
hasErr: false
}
渲染如下:
<div class="classA classB"></div>
若hasErr发生变化,则:
<div class="classA classB text-danger"></div>
绑定的数据对象不必内联定义在模板里:
<div v-bind:class="classObject"></div>
data: {
classObject: {
classB: true,
'text-danger': false
}
}
渲染的结果和上面一样。
1.11 v-bind:style
v-bind:style
的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:
<div
v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"
></div>
data: {
activeColor: 'red',
fontSize: 30
}
直接绑定到一个样式对象通常更好,这会让模板更清晰:
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
同样的,对象语法常常结合返回对象的计算属性使用。
v-bind:style
的数组语法可以将多个样式对象应用到同一个元素上:
<div v-bind:style="[baseStyles, overridingStyles]"></div>
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
1.12 数组的相关操作
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
以上这些方法会改变调用他们的数组,还有一些方法,例如:filter(),concat(),**slice()**等方法会直接返回一个新的数组
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
而且,你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。
例如:
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
在计算属性不适用的情况下 (例如,在嵌套 v-for
循环中) 你可以使用一个方法:
1.13 v-on
事件修饰符
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 v-on
提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的
.stop
.prevent
.capture
.self
.once
.passive
.once
<!-- 阻止单击事件继续传播 -->
<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>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
1.14 v-model
一些修饰符
- .lazy
在默认情况下,v-model
在每次 input
事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy
修饰符,从而转为在 change
事件_之后_进行同步:
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">
-
.number
如果想自动将用户的输入值转为数值类型,可以给
v-model
添加number
修饰符:<input v-model.number="age" type="number">
-
.trim
如果要自动过滤用户输入的首尾空白字符,可以给
v-model
添加trim
修饰符:<input v-model.trim="msg">
v-model与自定义事件的一些用法
<custom-input v-model="searchText"></custom-input>
等价于
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
所以,为了让它正常工作,这个组件内的 <input>
必须:
- 将其
value
attribute 绑定到一个名叫value
的 prop 上 - 在其
input
事件被触发时,将新的值通过自定义的input
事件抛出
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
2. 计算属性
在vue实例中队vue中的data中的属性进行绑定操作,这种操作可以当作data中的另一种属性,例如:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
结果:
Original message: “Hello”
Computed reversed message: “olleH”
这里我们声明了一个计算属性 reversedMessage
。我们提供的函数将用作 property vm.reversedMessage
的 getter 函数:
console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
一般计算属性不与v-for连用
一些其他用法
-
可以替代侦听属性
当你有一些数据需要随着其它数据变动而变动时,你很容易滥用
watch
:<div id="demo">{{ fullName }}</div>
侦听:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } })
计算属性
var vm = new Vue({
el: '#demo',
data{
firstName: 'Foo',
lastName: 'Bar'
}
computer: {
fullName: function(){
return this.firstName + '' + this.lastName;
}
}
})
-
设置set方法
一般计算属性默认都是setter方法,但可以设置一个setter方法
var vm = new Vue({ el: '#demo', data{ firstName: 'Foo', lastName: 'Bar' } computer: { fullName:{ get: function(){ return this.firstName + '' + this.lastName; } set: functiong(newValue){ var names = newValue.split(''); this.firstName = names[0]; this.lastName = names[names.length - 1]; } } } })
现在再运行
vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和vm.lastName
也会相应地被更新。
计算属性的好处
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
将reverseMessage定义成一个方法同样可以达到反转的效果,但计算属性属于响应式依赖,也就是说,如果使用计算属性来实现反转效果,如果message不发生改变,则reverseMessage不会再次运行,直接返回之前缓存中的值,而定义成方法则每次都会重新执行reverseMessage()方法,会消耗资源,因此,推荐使用计算属性。
computed: {
now: function () {
return Date.now()
}
}
因为是计算属性,所以只要Date.now()不会每次都刷新
3. 非常有用的示例
3.1 动态添加一个含有函数的按钮
<div id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="new-todo"
placeholder="E.g. Feed the cat"
>
<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>
</div>
注意这里的
is="todo-item"
attribute。这种做法在使用 DOM 模板时是十分必要的,因为在<ul>
元素内只有<li>
元素会被看作有效内容。这样做实现的效果与<todo-item>
相同,但是可以避开一些潜在的浏览器解析错误。查看 DOM 模板解析说明 来了解更多信息。
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
})
new Vue({
el: '#todo-list-example',
data: {
newTodoText: '',
todos: [
{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Mow the lawn'
}
],
nextTodoId: 4
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
})
demo1.vue
<template>
<div id="todo-list-example">
<form v-on:submit.prevent="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="new-todo"
placeholder="E.g. Feed the cat"
>
<button>Add</button>
</form>
<ul>
<li
is="todoItem"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
@remove="todos.splice(index,1)"
></li>
</ul>
</div>
</template>
<script>
import base from '@/baseMix/listMix'
import todoItem from './demo2'
export default {
name: 'todo-list-example',
components: {todoItem},
data() {
return {
newTodoText: '',
mixins: [base],
todos: [
{
id: 1,
title: 'Do the dishes',
},
{
id: 2,
title: 'Take out the trash',
},
{
id: 3,
title: 'Mow the lawn'
}
],
nextTodoId: 4
}
},
methods: {
addNewTodo: function () {
this.todos.push({
id: this.nextTodoId++,
title: this.newTodoText
})
this.newTodoText = ''
}
}
}
</script>
<style scoped>
</style>
demo2.vue
<template>
<li>
{{title}}
<button v-on:click="$emit('remove')">Remove</button>
</li>
</template>
<script>
export default {
name: "todo-item",
props: {
title: '',
}
}
</script>
<style scoped>
</style>
3.2 父组件调用子组件的方法
https://www.cnblogs.com/jin-zhe/p/9523029.html
3.3 子组件调用父组件的方法
https://www.cnblogs.com/jin-zhe/p/9523782.html
3.4 父组件向子组件传值
https://www.cnblogs.com/padding1015/p/7878710.html
3.4 props中属性值类型的设置
https://www.cnblogs.com/yddzyy/p/13269839.html
4. 组件深入
4.1 组件注册
– 全局注册
Vue.component('my-component',{...})
使用这种方式,为全局注册
例如:
<!--demo3的代码如下-->
<template>
<div>
<h1>测试一下全局注册</h1>
</div>
</template>
<script>
export default {
name: 'test-demo3',
}
</script>
<style scoped>
</style>
将demo3在main.js中全局注册
import testDemo1 from '@/views/dateList/dateListVue/demo3'
Vue.component('test-demo1',testDemo1)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1BvCef25-1629538897942)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210820144636596.png)]
在demo4中自动显示test-demo3
– 局部注册
通过普通的js对象来定义组件
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在 component
中定义想要使用的组件
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
对于 components
对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。
或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
在 ES2015+ 中,在对象中放一个类似 ComponentA
的变量名其实是 ComponentA: ComponentA
的缩写,即这个变量名同时是:
- 用在模板中的自定义元素的名称
- 包含了这个组件选项的变量名
.注意
1.大小写问题
-
在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:
<!-- 在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。 除非在实例中有一个名为“someattr”的 property,否则代码不会工作。 --> <a v-bind:[someAttr]="value"> ... </a>
那么,我们一般在props中定义attribute,最好不要用驼峰命名法,用小短横 - 来命名,如data-list
2.props和data的区别
https://www.jb51.net/article/181697.htm
3.v-if
v-if接收的值不是简单的true而是truthy
Truthy(真值)的解释
https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy
4.命名
4.1 组件名
在注册组件名的时候强烈推荐:
字母全小写且必须包含一个连字符
Vue.component('my-component-name', { /* ... */ })
4.2 事件名
推荐始终使用kebab-case 的事件名,因为:
v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以v-on:myEvent
将会变成v-on:myevent
——导致myEvent
不可能被监听到。- 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了
总结
https://www.cnblogs.com/zhanglw456/p/12761008.html
5. 关于v-bind的一些问题
因为以前的学习中,双引号""
中的内容,我们通常看作字符串,也因此通常不考虑""
中的内容如何执行。
但是在v-bind中,经过v-bind绑定后,属性后的""中的内容将被看作js表达式
<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="42"></blog-post>
6. is
is
attribute。在ul,table等元素中可能严格要求了其中的标签,所以我们直接使用组件可能并不能被接受,eg:
<ul>
<my-row></my-row>
</ul>
并不能被识别,所以:
<ul>
<row
is="my-row"
></row>
</ul>
名
4.1 组件名
在注册组件名的时候强烈推荐:
字母全小写且必须包含一个连字符
Vue.component('my-component-name', { /* ... */ })
4.2 事件名
推荐始终使用kebab-case 的事件名,因为:
v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以v-on:myEvent
将会变成v-on:myevent
——导致myEvent
不可能被监听到。- 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了
总结
https://www.cnblogs.com/zhanglw456/p/12761008.html
5. 关于v-bind的一些问题
因为以前的学习中,双引号""
中的内容,我们通常看作字符串,也因此通常不考虑""
中的内容如何执行。
但是在v-bind中,经过v-bind绑定后,属性后的""中的内容将被看作js表达式
<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="42"></blog-post>
6. is
is
attribute。在ul,table等元素中可能严格要求了其中的标签,所以我们直接使用组件可能并不能被接受,eg:
<ul>
<my-row></my-row>
</ul>
并不能被识别,所以:
<ul>
<row
is="my-row"
></row>
</ul>