Qustion One:why learning vue3.0?
Vue is the most popular front-end framework at present,Official update,we also want to update.more steps.
Qustion Two:vue3.0 new change ?
- number one :performance;
- number two :support typescript;
- number three : provide new ways of coding;
Question three:Update of destructive syntax?
- number one : Remove $on event;(the xisting eventBus mode is no longer supported and can be reolaced with a third-party plug-in)
- number two:Remove filter option;(Instead of using filter in the interpolation expression,use methods instead)
- number three:Remove .sync grammar;(v-bind can no longer use the .sync modifier,which is now merged with v-model syntax)
Vue3 development environment construction:
number one :create project
command line:
vue create "project name "
This may appear in creating vue3.0 projects (Cannot find module ‘vue-loader-v16/package.json)
solution
- number one : npm install npm@latest -g (update npm )
- number tow:npm i vue-loader-v16
package.json shows in the dependencies configuration that we are currently using version 3.1.4
Vue2.0 and Vue3.0 happen to change
number one :main.js
//Vue2.0
import Vue from 'vue'
new Vue({
render:h => h(App),
}).$mount('#app')
//vue3.0
import {createApp} from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
//thought:
core code:createApp(App).mount('#app') =
createApp(root component).mount(' div container in public/index.html ')
//number one: in vue2.0 ,a vue instance is created directly
//number two :vue3.0 export a createApp on demand (what createApp does)
app single files in vue3 are no longer mandatory to have a root element
this means that in vue2.0 there must be a root element,and in vue3.0 there is no such requirement.
<template>
<image src="../../../static/logo.png" mode=""></image>
<view>Take pride in knowing that your happiness is infectious and you can make so many days brighter just by flashing your grin.</view>
</template>
Composition API and Option API
The vue3 Composition API was created to distinguish it from the vue2 options API.
Here is the differential code to distinguish vue2 from vue3
Requirement: Implement box display and hiding
difference:
Option API (vue2.0)
advantage:
easy to understand,clear logic(data in data,method in methods)
disadvantages: code jumping,not easy to reuse.
Composition API(vue3.0)
advantage:
Strong maintenance,data,methods together.
disadvantages:
large amount of code can be logically split.
Composition API
number one:setup
-
number one :A component option that is executed before the component is created,once props are resolved,and serves as an entry point to the composite API.
-
number two :undefined cannot be used in setup. Undefined cannot be executed with this and this
-
number three :The setup function is executed before the beforecreated hook function
-
number four :The setup function is executed only once during initialization
Life cycle hook
Option API:
beforeCreate
create
beforeMount
mounted
beforeUpdate
updated
beforeUnmount
unmounted
errorCaptured
renderTracked
renderTriggered
activated
deactivated
Composition API:
Not needed*
Not needed*
onBeforeMount
onMounted
onBeforeUpdate
onUnmounted
onErrorCaptured
onRenderTracked
onRenderTracked
onRenderTriggered
onActivated
onDeactivated
These lifecycle hook registration functions can only be used synchronously during setup() because they rely on internal global state to locate the currently active instance (the component instance whose setup() is being called at this time). Calling them when there is no currently active instance results in an error.
The component instance context is also set during synchronous execution of the lifecycle hook, so listeners and compute properties created synchronously within the lifecycle hook are also automatically removed when the component is uninstalled.
Because setup runs around the beforeCreate and created lifecycle hooks, there is no need to define them explicitly. In other words, any code written in these hooks should be written directly in the setup function.
You can access a component's lifecycle hook by prefixing it with "on." Prerequisite needs to be introduced
export default{
setup(){
onMounted(()=>{
console.log('Component is mounted!)
})
}
}
Reactive ref function
- number one :the ref function is not used
<template>
<div>{{ num }}</div>
<button @click="addNum">add one</button>
</template>
<script>
export default {
setup(){
let num = 1,
addNum=()=>{
num++
console.log(num)
}
return {num,addNum}
}
}
</script>
- number two : the ref function is used
<script>
import {ref} from "vue"
export default {
setup(){
let num = ref(1),
addNum=()=>{
num.value++
console.log(num)
}
return {num,addNum}
}
}
</script>
- complex data type
<template>
<div>
{{ly.a}}
<button @click="addNum">add one</button>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
setup(){
const ly = ref({a:1})
const addNum = ()=>obj.value.a++
return {obj,addNum}
}
}
</script>
Procedure of use
-
number one :Import the ref function from the vue framework
-
number tow :Use the ref function and pass in data (simple data type or complex data type)
-
number three : In the setup funcition,the return value of the ref function is returned as object
The ref returns a mutable reactive object that maintains its internal value as a reactive reference, which is where the ref name comes from. This object contains only one property named value. Note that.value is required in the setup function, not in the template template
ref reference
Get references to DOM elements and subcomponents in vue2 Directly bind ref Get references through the $refs.ref bind attribute name
Binding ref directly in vue3 is not available
<template>
<div ref="wind"></div>
</template>
<script>
import { ref, onMounted } from "vue";
export default {
setup() {
const wind = ref(null);
onMounted(() => {
console.log(wind.value);
});
return { wind };
},
};
</script>
Note that the dom is obtained in the onMounted hook function, or by adding a click event
reactive function
The ref function is used to define reactive data where.value is added every time it is used, reactive is used to omit.value, but it can only define data of complex data types
toRefs function
After defining the reactive data, we pass the object in the template each time. However, if in order to solve this problem, it can be deconstructed by the toRefs function, the template can directly use a toRefs and reactive.
<template>
<div>
{{ a }}
<button @click="addNum">add one</button>
</div>
</template>
<script>
import {reactive, toRefs} from 'vue'
export default {
setup() {
const obj = reactive({a:1})
let {a} = toRefs(obj)
const addNum = ()=>obj.a++
return {a,addNum}
},
};
</script>
From above, it's deconstructing "a," but why not just... obj cloth
setup() {
const obj = reactive({a:1})
// let {a} = toRefs(obj)
const addNum = ()=>{obj.a++, console.log(obj.a);}
return {...obj,addNum}
},
The answer is no and the reason is to use... The data after a does not retain the characteristics of responsiveness
toRefs are useful when returning a reactive object from a composable function, so that the consumer component can decompose/diffuse the returned object without losing responsiveness
How to choose between ref and reactive
We now have two ways of defining reactive data which one should we use
number one : The ref function is preferred because it can handle both simple and complex data types and is often used to define reactive data for simple data types
ref features: When obtaining or modifying a value in the code, it needs to be supplemented with.value, but not in the template template
number two : reactive is commonly used and defines complex data types as reactive data
reactive features Getting or modifying values in code does not require a.value. reactive is used if you know exactly what properties are in the object
Computed computation attribute
Basic usage
grammar
import { computed } from 'vue'
const 计算属性名 = computed(() => {
return 响应式数据相关计算
})
<template>
<div>name:{{name}} age:{{age}} gender:{{gender}}</div>
</template>
<script>
import { computed, ref } from "vue";
export default {
setup() {
const name = ref("ly");
let salary = ref(18)
const gender = ref("female")
return { name,age,gender };
},
};
</script>
Advanced usage
<template>
<div>
name:{{ name }} start:{{ start }} all:{{ all }}
<input type="text" v-model="total" />
</div>
<button @click="double"> all double</button>
</template>
<script>
import { computed, ref } from "vue";
export default {
setup() {
const name = ref("ly");
let start = ref(10000);
const total = computed({
set(val){
return start.value=val/12
},
get(){
return start.value * 12
}
});
const double = () => start.value *= 2;
return { name, start, all, double };
},
};
</script>
Computation properties can also be bound to the v-model
watch monitor
Single data monitoring
<template>
<div>{{ num }}</div>
<button @click="addNum">加1</button>
</template>
<script>
import { ref, watch } from "vue";
export default {
setup() {
let num = ref(1),
addNum = () => {
num.value++;
};
watch(num, (newValue) => {
console.log(newValue);
});
return { num, addNum };
},
};
</script>
Multiple data monitoring
<template>
<div>{{ num }}||| {{num2}} </div>
<button @click="addNum">add one</button>
<button @click="addNum2">add one</button>
</template>
<script>
import {ref,watch} from 'vue'
export default {
setup() {
let num=ref(1)
let num2=ref(2)
const addNum=()=>num.value++
const addNum2=()=>num2.value++
watch([num,num2],(newValue)=>{
console.log(newValue);
})
return {num,num2,addNum,addNum2}
},
};
</script>
Complex data type listening
<template>
name:{{ stu.name }},age:{{ stu.age }}
star{{ stu.all.star }}
<button @click="stu.age ='ly'">ly</button>
</template>
<script>
import { reactive, watch } from 'vue'
export default {
setup() {
const stu = reactive({
name: 'ly',
age:18,
all: {
star: 1800
}
})
watch(stu, () => {
console.log('1')
})
return { stu }
}
}
</script>
Listen for properties in complex data types
When writing watch, avoid using deep to cause performance problems. The first parameter can be used as a callback
<template>
name:{{ stu.name }}
girl {{ stu.all.girl }}
<button @click="stu.all.girl =18000"></button>
</template>
<script>
import { reactive, watch } from 'vue'
export default {
setup() {
const stu = reactive({
name: 'yuanyuan',
all: {
girl: 1800
}
})
watch(()=>{
return stu.all.girl
}, () => {
console.log('~')
})
return { stu }
}
}
</script>
Enable deep listening
The first monitoring is immediate deep monitoring
<template>
name:{{ stu.name }}
star:{{ stu.all.star }}
<button @click="stu.all.star*=2">double</button>
</template>
<script>
import { reactive, watch } from 'vue'
export default {
setup() {
const stu = reactive({
name: 'ly',
all: {
star: 18000
}
})
watch(() => {
return stu.all
}, () => {
console.log('stu.all发生了变化')
}, {
deep: true // 只有为true,才能监听star下所有属性的变化
})
return {
stu
}
}
}
</script>
Parent-child communication
From father to son
The setup function takes two arguments the first is props and the second is context
props is an object. After receiving props, it contains all prop data passed to it. context contains attrs, slots and emit attributes
father
<template>
<div>
<Son :msg="msg"></Son>
</div>
</template>
<script>
import { ref } from 'vue';
import Son from "./son.vue";
export default {
components: {
Son,
},
setup() {
const msg = ref('ly')
return {msg}
},
};
</script>
<style scoped>
</style>
son
<template>
<div>son{{msg}} </div>
</template>
<script>
export default {
props:{
msg:{
type:String,
default:''
}
},
setup(props,context){
console.log(props,context);
}
};
</script>
<style scoped>
</style>
From son to father
Note that this.$emit in vue2 does not take effect in the setup function without this, but in the setup second argument there is the emit method
son
setup(props,context){
context.emit('name','ly')
}
father
setup() {
const name = (name)=>console.log(name);
return {name}
},
Parent to child: Using props data in setup setup(props){props is parent component data}
emit comes from setup(props,{emit}){emit is the trigger event function}