原理:通过 proxy 对数据进行封装,当数据变化时,触发模板等内容的更新; 作用:使非响应式的数据变成响应式;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 我们想象中 2s 后 这里使用的 name 的值也会变成“大哥刘备”
template: `
<div>name: {{name}}</div>
`,
setup(props, context){
// 定义一个变量 name
let name = "zibo";
// 2s 后改变其内容
setTimeout(() => {
name = "大哥刘备";
}, 2000);
return{
name
}
}
});
const vm = app.mount('#root');
</script>
</html>
ref底层得本质还是reactive,系统会根据我们给ref传入得值将它转换成ref(xx)–>reactive({value: xx})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 我们想象中 2s 后 这里使用的 name 的值也会变成“大哥刘备”
// 时间:2021年06月15日 18时18分16秒
// 理论上讲这里要使用name.value,但 vue 默认帮你做了,直接使用 name 就等于使用了 name.value
template: `
<div>name: {{name}}</div>
`,
setup(props, context){
// 从 vue 引入 ref
const { ref } = Vue;
// 定义一个变量 name
// proxy, ref 会将 "zibo" 变成 proxy({value: 'zibo'}) 这样的一个响应式引用
let name = ref("zibo");
// 2s 后改变其内容
setTimeout(() => {
name.value = "大哥刘备";
}, 2000);
return{
name
}
}
});
const vm = app.mount('#root');
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// vue 会自动将 person 替换成 person.value
// 明白了原理,就不难有一些骚操作,不过既然有了 reactive ,一般还是使用 reactive
template: `
<div>name: {{person.name}} age: {{person.age}}</div>
`,
setup(props, context){
// 从 vue 引入 ref
const { ref } = Vue;
// 定义一个变量 name
// proxy, ref 会将 "{name: 'zibo', age: 25}" 变成 proxy({value: {name: 'zibo', age: 25}}) 这样的一个响应式引用
let person = ref({name: 'zibo', age: 25});
// 2s 后改变其内容
setTimeout(() => {
person.value.name = "大哥刘备";
person.value.age = 42;
}, 2000);
return{
person
}
}
});
const vm = app.mount('#root');
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 我们想象中 2s 后 这里使用的 name 的值也会变成“大哥刘备”
template: `
<div>name: {{nameObj.name}}</div>
`,
setup(props, context){
// 从 vue 引入 reactive
const { reactive } = Vue;
// 定义一个变量 nameObj 对象
let nameObj = reactive({name: 'zibo'});
// 2s 后改变其内容
setTimeout(() => {
nameObj.name = "大哥刘备";
}, 2000);
return{
nameObj
}
}
});
const vm = app.mount('#root');
</script>
</html>
使用 ref 和reactive 取代原来的data;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 我们想象中 2s 后 这里使用的 name 的值也会变成“大哥刘备”
template: `
<div>name: {{nameObj.name}}</div>
`,
setup(props, context){
// 从 vue 引入 reactive
const { reactive, readonly } = Vue;
// 定义一个变量 nameObj 对象
let nameObj = reactive({name: 'zibo'});
let nameObjReadOnly = readonly(nameObj);
// 2s 后改变其内容
setTimeout(() => {
nameObj.name = "大哥刘备";
nameObjReadOnly.name = "大哥刘备";
}, 2000);
return{
nameObj
}
}
});
const vm = app.mount('#root');
</script>
</html>
对象是响应式的,但是从对象中解构的属性不是响应式的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 我们想象中 2s 后 这里使用的 name 的值也会变成“大哥刘备”
template: `
<div>name: {{name}}</div>
`,
setup(props, context){
// 从 vue 引入 reactive
const { reactive } = Vue;
// 定义一个变量 nameObj 对象
let nameObj = reactive({name: 'zibo'});
// 2s 后改变其内容
setTimeout(() => {
nameObj.name = "大哥刘备";
}, 2000);
const { name } = nameObj;
return{
name
}
}
});
const vm = app.mount('#root');
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
// 我们想象中 2s 后 这里使用的 name 的值也会变成“大哥刘备”
template: `
<div>name: {{name}}</div>
`,
setup(props, context){
// 从 vue 引入 reactive
const { reactive, toRefs } = Vue;
// 定义一个变量 nameObj 对象
let nameObj = reactive({name: 'zibo'});
// 2s 后改变其内容
setTimeout(() => {
nameObj.name = "大哥刘备";
}, 2000);
// 单个属性
// toRefs 使得 proxy({name: 'zibo'}) 变成 proxy(name: proxy({value: 'zibo'}))
// 多个属性
// toRefs 使得 proxy({name: 'zibo', age: 25}) 变成
// {
// proxy(name: proxy({value: 'zibo'})),
// proxy(age: proxy({value: 25})),
// }
const { name } = toRefs(nameObj);
return{
name
}
}
});
const vm = app.mount('#root');
</script>
</html>