安装
1.yarn global add @vue/cli
2.vue --version
查看是否安装成功
3. vue create .
安装此文件夹下
vue2的methods方法转换:reactive
什么是reactive?
- reactive是vue3中提供的实现响应式数据的方法
- 在vue2中响应式数据是通过defineproperty来实现的 在vue3中响应式数据是ES6Proxy来实现的
reactive注意点:
- reactive参数必须是对象(json/arr)
- 如果reactive传递其他对象(例如 new Date() )
· 默认情况下修改对象,界面不对发生更新
· 如果想更新就得重新赋值
setup 只能是同步函数不可用于异步函数
<button @click='add()'>按钮</button>
setup() {
// 在API组合方法中 定义方法不用在methods'里面定义 在setup直接定义就行
// const add = (()=>{
// console.log(111)
// });
function add() {
console.log(2222)
}
return {add}
vue2的data转换成:ref
什么是ref?
- ref和reactive一样,也是用来响应式数据的方法
- 由于reactive必须传递一个对象,所以导致在企业开发中
· 如果我们直系那个要某个变量实现响应式的时候会非常麻烦
· 所以Vue3就给我们提供了ref方法,实现对简单值的监听
ref的本质:
- ref底层的本质其实还是reactive
· 系统会自动根据我们给fef传入的值将他转换成ref(xx)-> reactive({value: xx})
ref的注意点:
- 在vue中使用ref的值不用通过value获取
- 在js中使用ref的值必须通过value获取
vue2 {{ num }}
data() {
return {
num: 10
}
}
vue3 {{ num }} // 页面输出不用加value 通过ref创建的数据 在template中使用的时候不用通过.value来获取 因为vue会自动给我们添加 .value
setup() {
let num = ref(10)
return {num}
// 修改值 必须得加value
比如( 时间函数 {
num.value = 11
})
}
小案例增删功能(点击li删除):
<template>
<div>
<ul>
<input type="text" name="" id="" v-model="state2.arr.id">
<input type="text" name="" id="" v-model="state2.arr.name">
<input type="text" name="" id="" v-model="state2.arr.age">
<button @click="add()">添加</button>
<li v-for="v in state.arr" :key="v.id" @click="del(v.id)">
{{ v.name }}-{{ v.age }}
</li>
</ul>
</div>
</template>
<script>
import { reactive } from "vue";
export default {
setup() {
let { state, del } = useReomveStudent(); // 解构赋值 { state, del }= {state,del}
let { state2, add } = useAddStudent(state);
return { state, del, state2, add};
},
};
// 增
let useAddStudent = (state) => {
let state2 = reactive({
arr: {
id: '',
name: '',
age: ''
}
})
let add = (()=> {
const arr = Object.assign({},state2.arr)
state.arr.push(arr)
state2.arr.id = ''
state2.arr.name = ''
state2.arr.age = ''
})
return {state2,add}
}
// 删
let useReomveStudent = () => {
let state = reactive({
arr: [
{ id: 1, name: "lili", age: 10 },
{ id: 2, name: "Tom", age: 20 },
{ id: 3, name: "lisa", age: 30 },
],
});
let del = (index) => {
state.arr = state.arr.filter((v, i) => v.id !== index);
console.log(state);
};
return { state, del };
};
toRaw
- 从Reactive 或 ret中得到原市数据
- toRaw 可以坐一些不想监听事情(提升性能)
注意:当toRaw方法接收的参数是ref对象时,需要加上.value才能获取到原始数据对象
<div class="home">
{{obj}}
{{objOne}}
<button @click="myFn"> 点击修改数据 </button>
</div>
<script>
import {reactive, toRaw,ref} from 'vue'
export default {
setup() {
//reactive
let obj = reactive({name: 'lili', age: '18'})
let obj2 = toRaw(obj)
//ref
let objOne = ref({name: 'lili', age: '18'})
//当toRaw方法接收的参数是ref对象时,需要加上.value才能获取到原始数据对象
let ObjTwo = toRaw(objOne.value)
function myFn() {
//reactive
// 如果直接修改obj 那么就无法出发界面更新的
// 只有通过包装之后的对象来修改,才会出发界面的根性
obj2.name = 'Tom'
console.log(obj)
console.log(obj2)
//ref
ObjTwo.name = 'lisa'
console.log(objOne)
console.log(ObjTwo)
}
return{obj,objOne,myFn}
}
}
makeRaw let obj2 = makeRaw(obj)
表示 永远不会被追踪
toRef, toRefs
<template>
<div class="home">
{{ name }} -- {{ age }}
<p>{{obj3}}</p>
<button @click="myFn"> 点击修改数据 </button>
</div>
</template>
<script>
import {toRef, toRefs} from 'vue'
export default {
setup() {
let obj = {name: 'lisa', age: 18}
let obj2 = {name: 'lisa', age: 18}
//toRef 只可以获取单个数据
let name = toRef(obj,'name')
let age = toRef(obj,'age')
// toRefs 可以获取多个数据
let obj3 = toRefs(obj)
function myFn() {
name = 'Tom'
age = '100'
console.log(name + '----' + age)
obj3.name.value = 'jack'
obj3.age.value = '99'
console.log(obj3)
}
return{name,age,myFn,obj3}
}
}
</script>
customRef
· 创建具有自定义引用的显式控件,以对其依赖项跟踪进行显式控制并更新触发。它需要一个工厂函数,该函数接收track和trigger作为参数使用,并应返回带有get和的对象set。
点击按钮触发track和trigger
<template>
<div class="home">
{{num}}
<button @click="myFn"> 点击修改数据 </button>
</div>
</template>
<script>
import {ref, customRef} from 'vue'
function myRef(value) {
return customRef ((track, trigger) => { // track 追踪, trigger 触发
return {
get() {
track() // 告诉Vue这个数据是需要追踪变化的
console.log('get', value);
return value
},
set(newValue) { // 当用set 的时候就开始发生变化
console.log('set', newValue);
value = newValue
trigger() // 告诉vue 触发界面更新否则不会更新
console.log('-------------');
return newValue
}
}
})
}
export default {
setup() {
let num = myRef(0)
function myFn() {
num.value += 1
}
return {myFn,num}
}
}
</script>
网络请求触发track和trigger
<template>
<div class="home">
{{state}}
</div>
</template>
<script>
import { customRef } from 'vue'
function myRef(value) {
return customRef ((track, trigger) => { // track 追踪, trigger 触发
fetch('jsonone.json')
.then((res) => {
console.log(res)
return res.json()
})
.then((data) => {
console.log(data)
value = data
trigger()
})
.then((err) => {
console.log(err)
})
return {
get() {
track() // 告诉Vue这个数据是需要追踪变化的
console.log('get', value);
// 不要在get方法里面发送网络请求 否则会一直循环 渲染界面 -> 发送网络请求 -> 保存数据 -> 更新界面 -> 条用get
return value
},
set(newValue) { // 当用set 的时候就开始发生变化
console.log('set', newValue);
value = newValue
trigger() // 告诉vue 触发界面更新否则不会更新
console.log('-------------');
return newValue
}
}
})
}
export default {
setup() {
let state = myRef('jsonone.json')
return {state}
}
}
</script>
ref 获取元素
<template>
<div class="home">
<div ref='box'>
box
</div>
</div>
</template>
<script>
import {ref, customRef, onMounted} from 'vue'
export default {
setup() {
let box = ref(null)
onMounted(()=> {
console.log(box.value)
})
console.log(box.value);
return {box}
}
}
</script>
readonly, shallowReadonly,isReadonly
- readonly 用于创建一个只读的数据。并且是递归只读(数据也不会变,视图不变)
- shallowReadonly 用于一个只读的数据,但是 不是递归只读(数据会变,视图不变)
- isReadonly 检查对象是否是由readonly创建的只读代理
<template>
<div class="home">
<div>{{obj}}</div>
<div>{{obj1}}</div>
<button @click="muFn">点击</button>
</div>
</template>
<script>
import { readonly, shallowReadonly, isReactive, isReadonly } from "vue";
export default {
setup() {
//readonly 用于创建一个只读的数据。并且是递归只读
let obj = readonly({ name: "lili", attr: { name: "Tom", age: "18" } });
// shallowReadonly 用于一个只读的数据,但是 不是递归只读
let obj1 = shallowReadonly({
name: "jack",
attr: { name: "tony", age: "18" },
});
function muFn() {
obj.name = "hello";
obj.attr.name = "lisa";
obj.attr.age = "999";
console.log(obj);
console.log(isReadonly(obj));
console.log('----------------------------');
obj1.name = "hello";
obj1.attr.name = "lisa";
obj1.attr.age = "999";
console.log(obj1);
console.log(isReadonly(obj1));
}
return { obj, muFn, obj1, obj1 };
},
};
</script>
proxy
// vue3响应式数据本质
// 在vue2种是通过defineProperty 来实现响应式数据的
// 在vue3.x种事通过proxy来实现响应式数据的
let obj = [1,3,5]
// proxy 两个参数 把谁变成proxy 第二个变完之后 如何去监听和赋值...
let state = new Proxy (obj,{
get(obj,key) { // 获取值调用get // obj 是赋值的对象 key是obj的属性
console.log(obj+'------'+key); // [1,3,5] 1
return obj[key]
},
set(obj,key,value) { // 监听 条用set // obj 是赋值的对象 key是obj的属性 value 是新给他赋值的值
// [1,3,5] 3 7
// [1,3,5,7]length 4
console.log(obj,key,value);
// obj[key] = value
console.log("更新UI界面");
return true // 告诉这个操作是成功的
}
})
obj.push(7)
console.log(state);