一、组件通信方式
- props 父子通信
- $emit 子父通信(四步)
- $refs 直接获取组件对象
- provide/inject 依赖注入
- 透传 Attribute
- $root 获取根对象
- $parent 获取父级对象
- vuex 状态管理器
二、TransitionGroup的使用
<body>
<div id="app">
<button @click="handleAdd">按钮</button>
<transition-group
enter-active-class="animate__animated animate__rotateInDownLeft"
>
<div class="box" v-for="item in arr" :key="item">{{ item }}</div>
</transition-group>
</div>
</body>
<script>
Vue.createApp({
//创建vue应用
data() {
//数据包
return {
arr: [1, 2, 3, 4],
};
},
methods: {
handleAdd() {
let n = this.arr.length + 1;
this.arr.push(n);
},
},
}).mount("#app");
</script>
三、动态组件与KeepAlive
<div id="app">
<!-- 静态调用组件 -->
<!-- <my-comp1></my-comp1>
<my-comp2></my-comp2>
<my-comp3></my-comp3> -->
<!-- 动态组件 -->
<button v-for="item in 3" @click="handleTab(item)">菜单{{item}}</button>
<keep-alive>
<component :is="compName"></component>
</keep-alive>
</div>
<script>
let app = Vue.createApp({
//创建vue应用
data() {
//数据包
return {
compName: "my-comp1",
};
},
methods: {
handleTab(i) {
this.compName = `my-comp${i}`;
},
},
});
app.component("my-comp1", {
data() {
return {
bool: false,
};
},
template: `<div :class="bool?'active':''" @click="bool=!bool">组件1</div>`,
});
app.component("my-comp2", {
data() {
return {
bool: false,
};
},
template: `<div :class="bool?'active':''" @click="bool=!bool">组件2</div>`,
});
app.component("my-comp3", {
data() {
return {
bool: false,
};
},
template: `<div :class="bool?'active':''" @click="bool=!bool">组件3</div>`,
});
app.mount("#app");
</script>
四、Teleport传送门
- 传送门 Teleport 可以将组件 DOM 节点传送并渲染到 to 所指定的标签内
- 应用场景:封装的遮罩弹窗效果,需要在最外层覆盖所有其他元素的时候,可以使用 Teleport
<div id="app">
<div>
第一层容器
<div>
第二层容器
<my-comp></my-comp>
</div>
</div>
</div>
<script>
let app = Vue.createApp({
//创建vue应用
data() {
//数据包
return {
msg: "Hello Vue",
};
},
});
app.component("my-comp", {
template: `<Teleport to="body">
<div class="modal">这是一个组件</div>
</Teleport>`,
});
app.mount("#app");
</script>
五、组合式API
<div id="app">
<h1 @click="handleNum">{{num}}---{{count}}</h1>
</div>
<script>
Vue.createApp({
setup() {
// 逻辑关注点1
let num = 100; //非响应式数据
let count = Vue.ref(233); //响应式数据
const handleNum = () => {
num++;
count.value++;
console.log(num);
};
// 此处return的内容才能在标签区域使用
return {
num,
handleNum,
count,
};
},
}).mount("#app");
</script>
5.1 reactive实现响应式数据
<div id="app">
<h1 @click="handleNum">{{state.num}}</h1>
<button @click="handleAdd">新增学员</button>
<div v-for="(item,index) in stu" :key="index">
姓名:{{ item.name }} , 分数:{{item.score}}
</div>
</div>
Vue.createApp({
setup() {
// 逻辑关注点1
let state = Vue.reactive({ num: 100 });
const handleNum = () => {
state.num++;
console.log(state.num);
};
// 逻辑关注点2
let stu = Vue.ref([
{ name: "张三丰", score: 100 },
{ name: "三丰", score: 90 },
]);
const handleAdd = () => {
stu.value.push({
name: "无忌",
score: 80,
});
};
return {
state,
handleNum,
stu,
handleAdd,
};
},
}).mount("#app");
</script>
5.2 其他组合式API
<div id="app">
<h1 @click="msg='你走'">{{msg}}</h1>
<h2>{{reMsg}}</h2>
<h2>{{reMsg}}</h2>
<h2>{{reMsg}}</h2>
<input type="text" ref="myInput" />
<h1 ref="myH1">这是h1</h1>
</div>
<script>
Vue.createApp({
setup() {
//setup内部无法使用this,也没必要使用this
// 逻辑关注点1
const msg = Vue.ref("Hello");
// 使用computed,计算属性
const reMsg = Vue.computed(() => {
return msg.value.split("").reverse().join("");
});
console.log(msg, reMsg);
// 生命周期,没有create系列钩子,多了一个会优先与所有其他生命周期执行的setup
const myInput = Vue.ref(); //定义一个ref对象
const myH1 = Vue.ref();
Vue.onMounted(() => {
myInput.value.focus();
});
// watch监听
Vue.watch(msg, () => {
console.log("检测到了msg的变化");
});
return {
msg,
reMsg,
myInput,
myH1,
};
},
}).mount("#app");
</script>
六、选项式 API 对应的组合式 API
- 所有的组合式 API 需要写在 setup 区域
- data(){} 对标的 Vue.ref() Vue.reactive()
- computed:{} 对标的 Vue.computed()
- methods:{} 对标的 const handleXXX = ()=>{}
- mounted(){} 对标的 onMounted(()=>{}) 取消了create系列生命周期
- watch:{} 对标的组合式 watch('被检测的数据',()=>{回调函数})
- directives:{'focus':{}} 挂载局部指令 const vFocus = {mounted(){}}
- components:{} 对标的组合式 直接引入使用,免注册
七、ref() 与 reactive() 实现响应式
- ref 处理响应式
- ref() 可以将基本类型处理为响应式 let num = Vue.ref(100)
- ref() 可以将对象类型处理为响应式
- reactive
- reactive() 只能将对象处理为响应式 let state = Vue.reactive({num:100})
- 实现原理
- ref() 是通过数据劫持(Object.defineProperty)实现响应式能力
- reactive() 是通过数据代理(Proxy)实现的响应式能力
- 操作手段的不同
- ref() 的操作需要 xxx.value
- reactive() 是直接操作
八、@vue/cli 脚手架
文档 Nodejs 版本 v16.18.1
8.1 安装
npm i @vue/cli -g 全局安装
vue -V 查看脚手架版本号
8.2 使用脚手架提供的命令创建 vue 项目
vue create 项目名称
8.3 按需选择项目依赖
8.4 启动项目进行预览开发
cd my-app 进入项目目录终端
npm run serve 启动项目
九、认识 Vue 工程化目录
- node_modules 项目依赖文件夹
- public 项目启动后所浏览的 html 页面,是以内部 index.html 为模板生成的
- src 项目业务代码
- assets 静态资源文件夹(img、css)
- components 公共组件
- App.vue 根组件
- main.js 项目入口文件
- .gitignore 可以让 git 忽略某些文件、文件夹
- package.json 项目相关信息的记录文件(基本信息、命令、依赖)