项目结构(新的)
components
用来装子组件的
assets
用来装css图片等资源
router
有一个index.js用来装不同的url路径对应的处理函数以及所对应的挂载的组件
store
里面装的是一个用来存储不同网页的共同使用的资源的文件
views
里面装的是组件的视窗部分,就是给路由用的
reactive和ref函数
| ref | reactive | |
|---|---|---|
| 数据类型 | 原始数据、对象 | 对象 |
| 操作 | js中需要添加.value,tamplate中则不用 |
都不用添加.value |
watch监听
1 | watch(count, (newCount, oldCount) =>{ |
立即执行
1 | watch( |
深度监听
当你监听的是一个对象而且没有进行深度监听的时候,当对象的某个属性值改变的时候是不会触发监听事件的。这个时候就要加上一个{deep:true,}
1 | watch( |
多重监听
主要是把单个名字改成一个数组形式,
1 | watch( |
监听单个属性
1 | watch( |
使用箭头函数作为watch的回调函数可以让我们再函数内部访问到变化前后的属性值
templateRef
- 需要在你想要调用的元素的标签名里面加上
ref = index(这是一个别名) - 在
<script setup>里面写上const index = ref(null)这里写上null并没关系。 - 调用templateRef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<div ref="index">
<h1>templateRef模板引用</h1>
<p>打开控制台查看</p>
</div>
//以下是script
import {ref} from 'vue'
const index = ref(null)
function handleClick() {
console.log(index.value)
}
//以下是在控制台的输出结果
<div ref="index">
<h1>templateRef模板引用</h1>
<p>打开控制台查看</p>
</div> - 实现dom树的修改
1 | function changeColor() { |
父子组件通信
子组件向父组件传输数据
defineEmits
1 | const emit = defineEmits(['pass-msg-to-father']) |
注意:这里emit不可以随便修改,两个都是!
在父组件中子组件的标签内用@pass-msg-to-father = "getMagFromSon"自己定义的一个方法名
在<script setup>中添加
1 | const msg2 = ref('') |
来实现子组件向父组件的通信
当然,这里的data也是一个别名
defineExpose(学长甄选,更加符合直觉,我也是这么觉得滴)
1 | defineExpose({ |
这里的sonMsg和changeSonMsg等就是已经在子组件已经定义的变量和函数
然后再在父组件的script里面加上这几句,其实就是你平时怎么用就怎么用就好了
1 | const getMsgFromSon2 = () => { |
父组件向子组件的通信
defineProps
在子组件当中创建一个props对象
1 | const props = defineProps({ |
这里的defineProps就相当于给子组件添加了新的属性
然后再在父组件当中的子组件标签当中用v-bind实现双向绑定,然后再再父组件中添加const msg = ref(0)等语句就可以实现父组件给子组件传值。
祖孙组件传值
provide and inject
1 | import { provide, ref } from 'vue'; |
只要在祖组件当中使用过一次provide子组件和孙组件等只需要inject就可以共享使用变量和方法了
1 | <script setup> |
1 | <script setup> |
然后只要按照平时使用变量和函数的方法正常使用就没有问题了
pinia
是vue专属的最新的状态管理库,允许跨组件或页面来共享数据的状态
添加pinia项目
- 命令行添加依赖
npm install pinia - 在入口文件
main.js中引入Pinia1
2
3import { createPinia } from 'pinia'
//别的乱七八糟
app.use(createPinia())
使用pinia项目
要在专门的store文件夹里面添加不同的文件
1 | import { ref, computed } from 'vue' |
注意:
useCounterStore位置是实际引用的时候会使用到的名称- 在
const前要记得加上export,导入之前自然要先导出,没有疑问的 - 回调函数的最后记得将需要导出的变量和方法名
return出来。
在组件中使用
1 | <script setup> |
然后正常使用就可以了,比如需要用count直接写counterStore.count想要使用,想要使用increment方法就可以直接写counterStore.increment
实践
在实际使用的时候只要在创建vue项目的时候选择添加pinia就可以了
router
添加router项目
创建一个router文件夹,这个文件夹和组件store等在同一层
然后在router文件夹里面创建一个index.js文件
index.js
在index.js的开头记得加上import { createRouter, createWebHistory } from 'vue-router'
1 | const router = createRouter({ |
这是路由的模板,有两种挂载组件的方法,可以在一开始导包import refAndReactive from '../views/refAndReactive.vue'然后在路由当中用component: refAndReactive直接挂载,但是如果每次都一次性导包,效率未免有些低,所以可以用component: () => import('../views/computedAndWatch.vue')让其在实际使用的时候才挂载起来
组件中使用
1 | import { RouterLink, RouterView } from 'vue-router' |
从vue-router导入RouterLink和RouterView等,然后创建一个数组,存储url和name
然后使用
1 | <router-link :to="item.url">{{ item.name }}</router-link> |
来创建链接实现跳转,item.url就是要跳转的url不过是在App.vue的基础上跳转的,item.name就是相对的名字等
1 | <router-view></router-view> |
这个就是用来展示views的视窗
v-on绑定
1 | <button @click="$router.push('/refAndReactive')">点击返回refAndReactive</button> |
使用v-on绑定事件$router.push('url')就可以直接跳转到对应的页面
useRouter
1 | <script setup> |
1 | <button @click="toPage('/computedAndWatch')">点击返回computedAndWatch</button> |
'/computedAndWatch'处也是填入对应的url