this.$data.content=this.content
**生命周期:**creat mount update unmount
Vue.creatApp({
data(){},
template:``
}).mount(’#root’)
v-on:@
v-model:双向绑定
v-bind:属性绑定
app.component(‘todo’,{})
app.mount(’#root’)
**局部组件:**需要做映射,首字母大写,驼峰命名
const Count={}
const app=Vue.creaApp({
components:{conuter:Counter},
template:``
})
全局组件:app.component() 横线间隔
props:{
required:
default:
type:
validator(){}
}
属性传值传的时候,使用content-abc,接的时候,使用contentAbc
单项数据流,不能修改父组件传过的数据,但是可以使用
父组件往子组件传值的时候,子组件不用props接收:Non-props属性
**// **Non- -props属性****
const app = Vue. createApp({
template:`
<div>
<counter msg="hello" msg1="hello1" />
</div>
`
});
app. component('counter', {
. // inheritAttrs: false,
mounted() {
console. log (this . $attrs.msg);
},
I
template:
<div :msg="$att rs. msg">Counter</div>
<div v-bind="$attrs">Counter</div>
<div :msg1=" $attrs. msg1">Counter</div>
}) ;
emit
props:[]
emits:[’’]
不通过emit方法:
父组件:
子组件:
props:[‘data’]
handleClick(){
this.$emit(‘update:data’,this.modelValue+3);
}
props:{
‘modelValue’:String,
‘modelModefiers’:{
default:()=>({})
}
},
handleClick(){
let newValue=this.modelValue+‘b’
if(this.modelModifiers.uppercase){
newValue=newValue.toUpperCase();
}
}
slot
具名插槽
<template v-slot:“header”>
<template v-slot:“footer”>
app.component('layout,{
template:`
作用域插槽
属性传递
const app=Vue.createApp({
template:`
<list v-slot="{item}">
<div>{{item}}</div>
</list>
`
});
app.component('list',{
date(){
return {list:[1,2,3]}
},
template:`
<div>
<slot v-for="item in list" :item="item"/>
</div>
`
})
const vm=app.mount('#root');
动态组件和异步组件
动态组件:
handleClick(){
if(this.currentItem ===‘input-item’){
this.current=‘common-item’;
}else{
this.currentItem=‘input-item’
}
父组件:
<button @click=“handleClick”>切换
再定义两个子组件
过渡动画
// 动画
@keyframes leftToRight{
0%{
transfrom:translateX(-100px);
}
50%{
transform:translateX(-50px);
}
0%{
transform:translateX(0px);
}
}
.animation{
animation :leftToRight 3s;
// 过度
transition{
transition:3s background-color escape;
}
}
.blue{
background:blue;
}
.green{
background:green
}
data (){
return{
transition:true,
blue:true,
green:false,
}
}
handleClick(){
this.Animate.blue=!this.Animate.blue;
this.animate.green=!this.animate.green;
}
// 单元素组件的入场和出场效果 多元素多组件也可以
动画效果网站:animate.style
@keyframes shake{
0%{
transfrom:translateX(-100px)
}
50%{
transfrom:translateX(-50px)
}
100%{
transform:translateX(50px)
}
}
.bye{
animation:shake 3s;
}
.hello{
animation:shake 3s;
}
<div>
//:duration 时间 :css=false关闭动画 @before-enter @enter-active @after-enter @before-leave钩子 appear刚进入也有效果
<transition enter-active-class="hello" leave-active-class="bye">
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
列表动画
状态动画
mixin
// 组件的data,methods优先级比mixin优先级更高
// 生命周期函数,先执行mixin里面的
// 自定义属性,组件中的属性优先级高于mixin属性的优先级
const myMixins={
data(){
return{
number:1
}
}
}
data(){}
mixins:[myMixins]
自定义指令
//第一种
<div v-pos="100" class="header">
<input/>
</div>
app.directive('focus',(el,binding)=>{
el.style.top=(binding.value+'px');
}
// {
// mounted(el,banding){
// el.style.top=(bainding.value+'px');
// }
// }
)
//第二种
const app=vue.createApp({
data(){
return{
distance:110
}
},
template:`
<div>
<div v-pos:right="distance" class="header">
<input/>
</div>
</div>
`
})
app.directive('pos',(el,binding)=>{
el.style[binding.arg]=(binding.value+'px')
})
const vm=app.mount('#root')
// 局部指令
const directives={
focus:{
mounted(el){
el.focus();
}
}
}
const app=Vue.createApp({
directives:directives,
template:`
<div>
<input v-focus/>
</div>
`
})
teleport传送门
<div class="area">
<button @click='handleBtnClick'>按钮</button>
<teleport to="#hello">
<div class="mask" v-show="show">{{message}}</div>
</teleport>
</div>
render函数
template -> render -> h ->虚拟DOM (JS对象) ->真实DOM ->展示到页面上
插件的定义和使用
const myPlugins={
install(app,options){
app.provide('name','Dell Lee');
app.directive('focus',{
mounted(el){
el.focus();
}
})
app.mixin({
mounted(){
console.log('mixins')
}
})
app.config.globalProperties.$sayHello='hello world';
}
}
const app=Vue.createApp({
template:`<my-title/>`
});
app.component('my-title',{
inject:['name'],
mounted(){
console.log(this.$sayHello);
},
template:`<div>{{name}}<input v-focus/></div>`
})
校验插件
const app=Vue.createApp({
data(){},
rules:{
ages:{
validate:age=>age>25,
message:'too young'
}
}
})
const validatorPlugin=(app,options)=>{
app.mixins({
created(){
for(let key in this.$options.rules){
const item=this.$options.rules[key];
this.$watch(key,(value)=>{
const result=item.validate(value);
if(!result) console.log(item.message);
})
}
}
})
}
conposition Api- setup函数
// Setup函数,在create实例被完全初始化之前,不能使用this,return的东西可以被模板使用
// 是composition的东西
setup(props,context){
return {
name:'dell',
handleClick:()=>{
alert(123)
}
}
}
ref,reactive,toRefs,readonly响应式
// ref,reative响应式
// proxy对数据封装ref('dell')->proxy({value:'dell'})
setup (props,context){
// res
// const {ref}=Vue;
// let name=ref('dell');
// setTimeout(()=>{
// name.value='lee'
// },2000)
// return {name}
//reactive,readonly不可修改
const {reactive,readonly}=Vue;
const nameObj=reactive([123]);
const copyNameObj=readonly(nameObj)
setTimeout(()=>{
nameObj[0]=456
copyNameObj[0]=456 //是不被允许的
},2000)
return{nameObj}
}
// toRefs用于解构,解构后还是响应式:{name:'dell'}变成proxy({name:'dell'})
// toRefs proxy({name:'dell',age:21}),->{name:proxy({value:'dell}),age:proxy({value:21})}
const {reactive,toRefs} =Vue;
const Obj=reactive({name:'dell',age:21});
setTimeout(()=>{
nameObj.name='lee'
},2000)
const {name,age}=toRefs(nameObj);
return{name}
setUp封装
// todolist封装
<script>
{/* 关于list操作的内容封装 */}
const listRelativeEffect=() => {
const {reactive}=Vue;
const list=reactive([]);
const addItemToList=(item) => {
list.push(item);
}
return {list,addItemToList}
}
{/* 关于inputValue操作的内容进型封装 */}
const inputRelativeEffect = () =>{
const {ref}=Vue;
const inputValue=ref('');
const handleValueChange=(e)=>{
inputValue.value=e.target.value
}
return{inputValue,handleValueChange}
}
const app=Vue.createApp({
setup (){
// 流程调度中转
const {list,addItemToList}=listRelativeEffect();
const {inputValue,handleValueChange}=inputRelativeEffect();
return{
list,addItemToList,
inputValue,hanleInputChange
}
},
template:`
<div>
<div>
<input :value="inputValue" @input="handleValueChange"/>
<button @click="()=>addItemToList(inputValue)">提交</button>
</div>
<ul>
<li v-for="(item,index) in list" :key="index">{{item}}</li>
</ul>
</div>
`
})
</script>
computed计算属性
const app=Vue.createApp({
setup(){
const {reactive,computed}=Vue;
const countObj=reactive({count:0});
const handleClick=()=>{
countObj.count+=1;
}
let countAddFive=computed({
get:()=>{
return countObj.count+5;
},
set:(param)=>{
countObj.count=param-5;
}
})
setTimeout(()=>{
countAddFive.value=100;
},3000)
return {count,countAddFive,handleClick}
}
template:`
<div>
<span @click="handleClick">{{count}}</span>--{{countAddFive}}
</div>
`
})
watch,watchEffect监听器
// watch具有惰性,能拿到原始和当前值,可以一个监听器承载多个数据的变化
// watchEffect是立即执行,会自动监测内部代码,不需要传进监听的内容,只要一个回调参数,没办法获取之前的值,根据数据依赖决定是否执行
setup (){
const{reactive,watch,watchEffect,toRefs}=Vue;
const nameObj=reactive({
name:'dell',englishName:'lee'
})
watch([()=>nameObj.name,()=>nameObj.englishName],([curName,curEng],[prevName,preEng])=>{
console.log(curName,precName,'---',curEng,preEng);
},{
immediate:true //让监听器立即执行
})
// watchEffect(()=>{console.log(nameObj.name)});
// 取消监听器
const stop=watchEffect(()=>{
console.log(nameObj.name);
setTimeout(()=>{
stop();
},5000)
})
const {name,englishName}=toRefs(nameObj);
return {name,englishName}
template:`
<div>
<div>
name:<input v-model="name"></input>
</div>
</div>
`
}
生命周期
const app=Vue.createApp({
// beforeMount =>onBeforeMount
// mounted =>onMounted
// beforeUpdate =>onBeforeUpdate
// beforeUnmount=>onBeforeUnmount
// unmount=>onUnmounted
// onRenderTracked页面渲染触发,onRenderTrriger页面重新渲染触发
setup(){
const{
ref,onBeforeMount,onMounted,onBeforeUpdate,unUpdates,onRenderTracked
}=Vue;
const name=ref('dell')
onBeforeMount(()=>{
console.log('onBeforeMounted')
})
}
})
provide,inject
const app=Vue.createApp({
setup(){
const {provide,ref,readonly} = Vue;
const name=res('dell');
provide('name',readonly(name)); //让接收的不能直接通过name.value修改值
provide('changeName',(value)=>{
name.value=value;
})
},
template:`
<div>
<child/>
</div>
`
})
app.component('child',{
setup(){
const {inject}=Vue;
const name=inject('name');
const changeName=inject('changeName');
const handleClick=()=>{
changeName('lee');
}
return {name,handleClick}
},
template:'<dvi @click="hadleClick">{{name}}</dvi>'
})
ref获取DOM节点
// Composition API语法下,获取真实的DOM元素节点
const app=Vue.createApp({
setup(){
const {res, onMounted}=Vue;
const hello=ref(null);
onMounted(()=>{
console.log(hello.value)
})
return {hello}
},
template:`
<div>
<div ref="hello">hello world</div>
</div>
`
})
const vm=app.mount('#root')
路由
异步加载:首次加载页面不会加载没展示的路由的页面,跳转的时候才会加载
component:()=>{}
vuex
通过this.
s
t
o
r
e
.
s
t
a
t
e
.
n
a
m
e
获
取
v
u
e
x
定
义
的
n
a
m
e
通
过
t
h
i
s
.
store.state.name获取vuex定义的name 通过this.
store.state.name获取vuex定义的name通过this.store.dispatch(‘change’)派发change的action ,执行change
action中的change --this.commit(‘change’) 提交一个commit 触发一个mutation,执行mutation
mutation写同步,action写异步
通过CompositionAPI使用Vuex
// 通过aompositionAPI使用VueX
export default {
name:'Home',
setup(){
const store=useStore(); //关键
const {name}=toRefs(store.state);
const handleClick=()=>{
store.dispatch('getData')
}
return {name,handleClick}
}
}
杂记
为了让所有的浏览器显示同样的样式:nomalize (npm install normalize.css --save)(import ‘nomalize.css’)