重新补一下vue2的基础使用,对之前掌握的使用方法进行下回顾和查漏补缺
数据与方法
- 教程参考
- html:
1
2
3<div id="app">
{{ message }} <!-- 数组插值 -->
</div> - js写法1:
1
2
3
4
5
6var app = new Vue({
el: '#app', // 绑定DOM对象
data: { // 给DOM对象中的数组插值赋值
message: 'Hello Vue!'
}
}) - js写法2:
1
2
3
4
5
6
7
8
9var data = { // 给DOM对象中的数组插值赋值
message: 'Hello Vue!'
}
var app = new Vue({
el: '#app', // 绑定DOM对象
data: data
})
// 修改app.message和data.message都可以改变DOM对象中message值
// 注意:如果想要响应式的变量一开始为空,则需要提前在data中设置空值,new了Vue实例以后才往data中新增的属性是不具备响应式的
Object.freeze()
- Object.freeze()阻止修改现有的 property,也意味着响应系统无法再追踪变化
- 例子
truthy(真值)
- js中将被转换为 true 的值
- MDN
if ({})
和if ([])
都是truthy,即都将被转换为 true
自定义组件上使用 v-for要自己传递prop
- 任何数据都不会被自动传递到自定义组件里
- 列表渲染
自定义组件在js里写
命名规范
自定义事件名用-
- 参考文档
- 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 **v-on 事件监听器在 DOM 模板中会被 自动转换为全小写 (因为 HTML 是大小写不敏感的)**,所以
v-on:myEvent
将会变成v-on:myevent
——导致myEvent
不可能被监听到。 - 因此,我们推荐你始终使用 短横线(kebab-case) 的事件名
子组件命名、引用、使用
- 总结:
- 子组件 命名 与 引用 要么始终以大写字母开头(PascalCase),要么始终用
-
连接(kebab-case) - 无论使用哪种方式命名与引用,组件的 使用方式 都是短横线(类似
<list-item>
- 子组件 命名 与 引用 要么始终以大写字母开头(PascalCase),要么始终用
- 常见使用:
1
2
3components :{ListItem} // 命名 ListItem 大写字母开头/短横线
import ListItem from 'xxx.vue' // 引用 大写字母开头/短横线
<list-item>// 使用组件 短横线
模板语法
- 除了插值(双大括号)直接显示变量值之外的使用方法
- 双大括号还可用于显示js表达式的最终值:例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<div id="app">
{{5+5}}<br> <!-- 10 -->
{{ ok ? 'YES' : 'NO' }}<br> <!-- YES -->
{{ message.split('').reverse().join('') }} <!-- BOONUR -->
<div v-bind:id="'list-' + id">菜鸟教程</div> <!-- 菜鸟教程 -->
</div>
<script>
new Vue({
el: '#app',
data: {
ok: true,
message: 'RUNOOB',
id : 1
}
})
</script> - 属性值可以使用
{js表达式}
: 通过data中是变量判断是否使用class类的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<div id="app">
<label for="r1">修改颜色</label><input type="checkbox" v-model="use" id="r1">
<br><br>
<div v-bind:class="{'class1': use}">
v-bind:class 指令
</div>
</div>
<script>
new Vue({
el: '#app',
data:{
use: false
}
});
</script>
vm.$set
- 文档
vm.$set( target, propertyName/index, value )
设置对象/数组
ref可操作原生DOM
- 文档
this.$refs.refName
1
2<!-- 父组件调用子组件时设置ref -->
<select-form-2 :defaultShopName="defaultShopName" @callback="getCallback" ref="selectForm"/>
父子组件传值
父组件向子组件传值
- 父组件在调用子组件时传值
1
2<!-- 父组件中,select-form-2是子组件 -->
<select-form-2 :defaultShopName="defaultShopName" @callback="getCallback" ref="selectForm"/> - 子组件在data()中通过props取值,注意要以对象的形式,不是数组形式
1
2
3
4
5
6
7// 子组件js中
props: {
defaultShopName: {
type: Number,
required: false,
default: 0,
},
子组件向父组件传值【重点】
- 文档参考
- 子组件位置components/OrderSalesRetrunDetail/select-form-2.vue,父组件pages.index.report-management.test.vue
- 子组件用this.$emit(“自定义事件名”,值)自定义事件向父组件传数据
1
2
3
4
5
6// 子组件js中
methods: {
onSubmit() {
this.$emit('callback', '123')
},
}, - 父组件调用子组件时,通过自定义的事件
@自定义事件名="函数名"
(切记函数名无()否则无法传值到函数中)获取子组件传的值1
2<!-- 父组件中,select-form-2是子组件 -->
<select-form-2 :defaultShopName="defaultShopName" @callback="getCallback" ref="selectForm"/>1
2
3
4
5// 父组件中js
methods: {
getCallback(res){
console.log(res);
},
子组件获取调用父组件函数后的返回值
- 父组件中+子组件中用emit的参数3(一个函数)来接收返回值returnVal:
1
2
3
4
5
6
7
8
9
10
11
12// 父组件中(参数1:子组件传来的参数a;参数2:传给子组件的值b)
DadFn(a, callback){
// ...
callback(b)
}
// 子组件中
// 注意调用父组件函数后的返回值是val,子组件中获取的returnVal需要提前定义
let returnVal = []
// emit的参数1:父组件函数名;参数2:传给父组件函数的参数;参数3:获取父组件函数的返回值
this.$emit('DadFn', a, val => { returnVal = val }) - [(参考文章1)[https://www.cnblogs.com/shenpeng/p/13731274.html]、[参考文章2](https://blog.csdn.net/u013795975/article/details/106335573)]
v-model的妙用(绑定父子组件的值)
- 参考文档
- 目的:直接在子组件中快速修改父组件中的某一个值
- 用途:希望父组件中的值与子组件值绑定的情况
- 父组件中调用子组件时使用v-model给子组件传值
<子组件 v-model = "父组件的值"/>
- 子组件中可通过value拿到v-model传递的值,也可通过
this.$emit('input',传递去改v-model值的值)
修改父组件的值。- 也可以在子组件中使用
model.prop
给value 重命名,model.event
给input 重命名:
- 也可以在子组件中使用
- 注意:子组件里watch是必备的,不能直接在子组件中使用父组件传来的model值,需要改成子组件自己的value。
- 如果没有watch,则子组件内的value不允许修改,只做展示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// ---父组件中---
<子组件名 v-model="confirmValue" />
// ---子组件中---
data() {
return { value: "", }
},
// 【重点】model重命名(和data同级)
model: {
prop: 'modelValue',
event: 'input'
},
props: {
modelValue: { // 父组件的confirmValue,原本是value,但和子组件重名了,故在model.prop里重命名为modelValue
type: String,
default: ''
},
},
// 注意:watch这里是必备的,不能直接在子组件中使用父组件传来的model值,需要改成子组件自己的value
watch: {
modelValue(val) { // 父组件传来的值变化时
this.value = val // 改变子组件的value
},
},
methods:{
change(){ // 某事件函数
...
this.$emit('input',this.value) // 用子组件value改变父组件v-model中定义的confirmValue
},
}
- 如果没有watch,则子组件内的value不允许修改,只做展示
相似的:xx.sync
- 文档
1
2
3
4
5
6
7
8常规用法:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
简写:
<text-document v-bind:title.sync="doc.title"></text-document> :timeEnd.sync
和v-model
用法基本没有区别- 父组件使用
v-model=a
后,子组件使用this.$emit('input',改变父组件v-model中a的值)
- 父组件使用
:a.sync
后,子组件使用this.$emit('update:a',改变父组件中a的值)
- 父组件使用
- 父组件可以同时使用
:timeEnd.sync
和v-model
传递不同的值给子组件
同时设置多个 prop
- 有多个需要绑定值的属性时,可传入一个对象
v-bind.sync="doc"
,这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器(搭配v-on的对象语法使用效果更加)将
v-bind.sync
用在一个字面量的对象上,例如v-bind.sync=”{ title: doc.title }”
,是无法正常工作的,因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑。- 应该就是说,doc对象在conputed或data又或者methods里定义才行,在v-bind里写有可能解析的时候被拆的分崩离析就无法正常工作了
1
2
3
4
5
6
7
8常规用法:(updateDocTitle是方法名,v-on可接收对象)
<text-document
v-bind="doc"
v-on="{ update:doc.title: updateDocTitle, update:doc.footer: updateDocFooter }"
></text-document>
简写:
<text-document v-bind.sync="doc"></text-document>
- 应该就是说,doc对象在conputed或data又或者methods里定义才行,在v-bind里写有可能解析的时候被拆的分崩离析就无法正常工作了
修饰符
事件修饰符
- 事件修饰符
- 修饰符是以半角句号
.
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定 - 例如,
.prevent
修饰符告诉 v-on 指令对于触发的事件调用event.preventDefault()
:1
<form v-on:submit.prevent="onSubmit"></form>
表单输入绑定(v-model)修饰符
- 总结:.trim-过滤首尾空白,.lazy-失去焦点更新,.number-数字类型
.trim
: 去掉输入框内首尾空格,实际绑定的input会禁止输入空格.lazy
: 在默认情况下,v-model 在 input 事件中同步输入框的值与数据 (除了 IME 部分),但你可以添加一个修饰符 lazy ,从而转变为在 change 事件中同步.number
: 可以将输入的数据转换为Number类型,否则虽然你输入的是数字,但它的类型其实是String(比如数字输入框)- 会限制只允许输入数字
- 不允许输入小数点/负号