常用选项
1. data
(1)对象格式
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
new Vue({
data: {
message1: 'Hello Vue!【1】',
message2: 'Hello Vue!【2】',
message3: '<h1>Hello Vue!【3】</h1>',
}
}).$mount('#app')
</script>
(2)方法格式
推荐,且组件开发中常用
<template>
<div>
<h1>{{ message1 }}</h1>
<h1>{{ message2 }}</h1>
<h1>{{ message3 }}</h1>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message1: 'Hello Vue!【1】',
message2: 'Hello Vue!【2】',
message3: '<h1>Hello Vue!【3】</h1>',
}
}
}
</script>
2. methods
不推荐使用箭头函数,因为箭头函数没有 this,会向外面找,此时 this 就从 vue 实例对象变成了 window 对象,就无法方便的获取源数据
<template>
<div>
<button @click="popMsg">点击</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
methods: {
popMsg() {
alert('哈哈哈')
},
}
}
</script>
3. computed
(1)对象格式
<template>
<div>
<p>{{ reversedMessage }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message: 'Hello,World!'
}
},
computed: {
reversedMessage: {
// - 读取计算属性的值,就是读取 get() 方法的返回值
// - 该 get() 方法的返回值有一个缓存机制,依赖于数据源是否发生改变
get() {
return this.message.split('').reverse().join('')
},
// - 当这个计算属性被修改时调用 set() 方法
// - 但是,计算属性一般是不会被修改的,仅仅用来展示数据
set(newValue) {
console.log(newValue);
},
}
}
}
</script>
(2)方法格式
计算属性一般是不会被修改的,也即 set() 方法一般无需书写,此时只有一个 get() 方法是必须的,所以可以简写计算属性为方法格式
<template>
<div>
<p>{{ reversedMessage }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message: 'Hello,World!'
}
},
computed: {
reversedMessage() {
return this.message.split('').reverse().join('')
}
}
}
</script>
(3)计算属性和方法的比较
计算属性有缓存机制,不管有多少个地方调用了计算属性的方法,只要计算属性所依赖的属性源没有发生变化,就会有缓存机制使得计算属性的方法只被调用一次
<template>
<div>
<p>{{ reversedMessage }}</p>
<p>{{ reversedMessage }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message: 'Hello,World!'
}
},
computed: {
reversedMessage() {
console.log('调用计算属性');
return this.message.split('').reverse().join('')
}
}
}
</script>
在表达式中调用方法也可以来达到与计算属性同样的效果,但是 vue 没有给方法提供像计算属性那样的缓存机制,方法被调用多少三次,方法就会执行多少次
<template>
<div>
<p>{{ reversedMessage() }}</p>
<p>{{ reversedMessage() }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message: 'Hello,World!'
}
},
methods: {
reversedMessage() {
console.log('调用方法');
return this.message.split('').reverse().join('')
},
}
}
</script>
4. watch
可以侦听 data、computed 的变化
(1)对象格式
<template>
<div>
<p>{{ user.username }}</p>
<p>{{ user.age }}</p>
<p>{{ phone }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
user: {
username: 'zhangsan',
age: 26
},
phone: '13711112222',
}
},
watch: {
// 1. 监听对象的某个属性
'user.age': {
handler(newAge, oldAge) {
console.log('旧的age为:' + oldAge + '新的age为:' + newAge + '————【user.age】');
}
},
// 2. 监听对象【深度监听】
user: {
handler(newValue, oldValue) {
console.log('旧的user为:' + oldValue + '新的user为:' + newValue + '————【user】');
},
// 开启 deep 选项,默认是 false,表示是否监听复杂数据类型的属性的变化
deep: true,
// 开启 immediate 选项,默认是 false,表示是否页面一加载就进行一次侦听
immediate: true,
},
// 3. 监听某个值
phone: {
handler(newValue, oldValue) {
console.log(newValue, oldValue);
},
// 开启 immediate 选项,默认是 false,表示是否页面一加载就进行一次侦听
immediate: true,
},
}
}
</script>
(2)方法格式
<template>
<div>
<p>{{ msg1 }}</p>
<p>{{ msg2 }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
msg1: 1,
msg2: 2,
}
},
// 侦听器: 侦听器的本质就是一个方法,用来监视数据的变化
watch: {
// 一个参数时,仅表示新值
msg1(newValue) {
console.log('【msg1】新值是: ' + newValue);
},
// 两个参数时,按照顺序,分别是新值、旧值
msg2(newValue, oldValue) {
console.log('【msg2】新值是: ' + newValue + ' 旧值是: ' + oldValue);
},
}
}
</script>
5. filters
在 vue3 已经移除,并不是必须要用的功能,一般可以使用计算属性、侦听器来替换该功能
(1)私有过滤器
<template>
<div>
<!-- 1. 使用管道符传递数据给下一个过滤器使用 -->
<!-- 2. 过滤器的本质就是一个方法,可以传递参数 -->
<p>{{ message | f1(1) | f2(1, 2) | f3(1, 2, 3) }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message: '这是 message 数据'
}
},
filters: {
// 3. 过滤器接收参数时,第一个参数永远是前面使用管道符传递过来的数据
f1(data) {
// 使用 return 将新的数据返回
return data + '--f1';
},
// 过滤器接收参数时,第二个参数往后,是过滤器形参里面传递的数据
f2(data, arg1, arg2) {
return data + '--f2' + arg1 + arg2;
},
f3(data, arg1, arg2, arg3) {
return data + '--f3' + arg1 + arg2 + arg3;
},
}
}
</script>
(2)全局过滤器
main.js
:定义全局过滤器
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
Vue.filter('f1', (data) => {
return data + '【全局过滤器】';
})
new Vue({
render: h => h(App),
}).$mount('#app')
组件中:使用全局过滤器
<template>
<div>
<p>{{ message | f1(1) }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
message: '这是 message 数据'
}
}
}
</script>
6. ref
使用 id 获取组件元素:这种情况获取的是组件 template 标签里面的全部元素,真实的 dom 结构
使用 ref 获取组件元素:获取的是组件对应的 vc,组件的实例对象【便于组件之间进行通信】
<template>
<div>
<h2 ref="tit">你好</h2>
<button @click="show" ref="btn">点我输出</button>
<MyCom ref="sch"/>
</div>
</template>
<script>
import MyCom from "@/components/MyCom.vue";
export default {
name: "HelloWorld",
components: {MyCom},
methods: {
show() {
console.log(this.$refs) // 获取组件实例的 refs 属性
console.log(this.$refs.tit) // 获取真实的dom元素
console.log(this.$refs.btn) // 获取真实的dom元素
console.log(this.$refs.sch) // 获取子组件的实例对象
},
}
}
</script>
7. props
- 如果在 props 里面声明了未传递的参数,该参数会成为 undefined
- data里面的属性 和 props 接收的属性尽量不要重名,如果冲突了,报错如:
error Duplicated key 'name'
- 使用
v-bind:
指令传递一个变量、数字、、、- 如果 props 里面声明了已经存在与 data 里面的数据,则会报错
- props 不可以接收特殊的参数,比如:‘ref’、‘key’、、、、、
- 可以传递
- 数据
- 方法
(1)简单使用
父组件:通过表达式传递数据、方法
<template>
<div>
<MyCom name="张三" :age="16" :show="show"/>
<hr>
<MyCom name="李四" :age="26" :show="show"/>
</div>
</template>
<script>
import MyCom from "@/components/MyCom.vue";
export default {
name: "HelloWorld",
components: {MyCom},
methods: {
show(data) {
console.log('我是', data, '【来自父组件的消息】')
}
}
}
</script>
子组件:接收数据、方法
<template>
<div class="demo">
<h3>姓名:{{ name }}</h3>
<h3>年龄:{{ age + 1 }}</h3>
<button @click="show">点我</button>
</div>
</template>
<script>
export default {
name: "MyCom",
props: ['name', 'age', 'show'],
}
</script>
(2)接收参数时对类型进行限制
<template>
<div class="demo">
<h3>姓名:{{ name }}</h3>
<h3>年龄:{{ age + 1 }}</h3>
<button @click="show">点我</button>
</div>
</template>
<script>
export default {
name: "MyCom",
// 1. 简单
// props: ['name', 'age', 'show'],
// 2. 升级
// props: {
// name: String,
// age: Number,
// show: Function
// },
// 3. 完整
props: {
name: {
type: String,
required: true,
},
age: {
type: Number,
default: 29,
},
// 可以设置参数不是必须传入,但是要保证该参数没有被使用过
show :{
type: Function,
required: true
}
},
}
</script>
(3)接收的参数是不可以修改的
如果一定要修改则可以参考如下,将 props 的数据赋值到 data 数据源里面,然后修改 data 数据源的数据
原理:在 data 里面可以访问到 props 接收到的参数
助解:儿子接收父亲传来的东西,必须先有父,才有子,并且儿子不可以改变父亲的东西
不可修改,所以,不要将 v-model 的值使用 props 接收的值
- 普通类型:不可修改值
- 对象类型:不可修改地址,可以仅修改对象的某一个属性
<template>
<div class="demo">
<h3>姓名:{{ name }}</h3>
<!-- 将 props 的数据赋值到 data 数据源,然后使用 data 数据源里面的数据 -->
<h3>年龄:{{ myAge + 1 }}</h3>
<button @click="updateAge">点我</button>
</div>
</template>
<script>
export default {
name: "MyCom",
props: ['name', 'age', 'show'],
data() {
return {
myAge: this.age,
}
},
methods: {
updateAge() {
this.myAge += 5
}
},
}
</script>
8. mixin 配置
多个组件共享一个配置
把共同的配置抽取出来到一个 js 文件里面,进行模块化
公共方法里面的 this
- 局部:某个组件的实例对象
- 全局:Vue 实例
(1)提供公共配置
bugu.js
export const bugu1 = {
data() {
return {
time: '2023-03-03'
}
}
}
export const bugu2 = {
methods: {
showMsg() {
// 局部:某个组件的实例对象
// 全局:Vue 实例对象
console.log(this);
// 可以访问实例对象的 msg 属性
console.log(this.msg);
}
}
}
(2)局部混入公共配置
HelloWorld.vue
:先局部混入公共配置,再使用配置
- 混合文件和组件里面都有相同的属性时,最终使用组件自己定义的属性
- 但是,如果是生命周期函数,会先使用混合的函数再使用自己的函数,而不是覆盖的效果导致只执行一个
<template>
<div>
<button @click="showMsg">点我</button>
<h2>时间:{{ time }}</h2>
<h2>姓名:{{ name }}</h2>
</div>
</template>
<script>
import { bugu1, bugu2 } from "../common/bugu.js";
export default {
name: "HelloWorld",
data() {
return {
msg: "这是 HelloWorld 组件!!!",
name: "张三",
};
},
mixins: [bugu1, bugu2],
}
</script>
(3)全局混入公共配置
测试 Vue 实例对象的公共配置
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 引入配置
import {bugu1, bugu2} from "./common/bugu";
// 混入公共的配置
Vue.mixin(bugu1)
Vue.mixin(bugu2)
new Vue({
render: h => h(App),
// 测试 Vue 实例对象是否有公共配置
mounted() {
this.showMsg()
}
}).$mount('#app')
在组件中测试公共配置
<template>
<div>
<button @click="showMsg">点我</button>
<h2>时间:{{ time }}</h2>
<h2>姓名:{{ name }}</h2>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
msg: "这是 HelloWorld 组件!!!",
name: "张三",
};
},
}
</script>