赞
踩
vue3中,直接导入组件就能用
不再要求唯一根元素
//createApp(App)是创建实例,.mount('#app')是在将实例往id为app的盒子上挂载 createApp(App).mount('#app') //挂载就是让实例接管一片区域
assets是存放图片或样式的目录
执行时机在beforeCreate之前
测试代码:
- <script>
- export default {
- setup(){
- console.log("setup函数")
- },
- beforeCreate() {
- console.log('beforeCreate函数')
- }
- }
- </script>
控制台输出:
可以看出setup函数的执行时机在beforeCreate之前
vue3基本不用this
2.setup函数里面定义的数据或者函数要想在界面中使用,需要return
- setup(){
- //数据
- const message ='hello'
-
- //函数
- const logMessage =()=>{
- console.log(message)
- }
- return{
- message,
- logMessage
- }
-
-
- },
只要return了就能直接在界面中使用
-
- <template>
- <div>{{message}}</div>
- <button @click="logMessage"></button>
- </template>
语法糖:这样就简化了代码,不再需要return,只要在<script setup>标签里面添加数据和函数就能直接在界面中使用
- <script setup>
- //数据
- const message ='hello'
- //函数
- const logMessage =()=>{
- console.log(message)
- }
- // console.log("setup函数")
- </script>
3.reactive:接收一个对象类型的数据,返回一个响应式的对象
响应式的对象指的是当数据改变时,前端界面上显示的数据也随之改变
- <script setup>
- //reactive:接收一个对象类型的数据,返回一个响应式的对象
- import {reactive} from "vue";
-
- const user = reactive({
- count:100
- })
- const setCount = ()=>{
- user.count++;
- }
- </script>
-
- <template>
- <div>
- <div>{{user.count}}</div>
- <button @click="setCount">加一</button>
- </div>
- </template>
4.ref,接收简单类型或者复杂类型,返回一个响应式的对象
- <script setup>
- import {ref} from "vue";
- const count = ref(0)
-
- const setCount =()=>{
- count.value++
- }
-
- //这里使用ref得到响应式对象后,要打印count的话要用.value才能得到count的值
- console.log(count.value)
- //但是在标签里面不用.value,直接count即可
-
- //ref的原理就是将普通对象包装成复杂对象,并使用了reactive使其能响应式更新
-
- </script>
-
- <template>
- <div>
- <div>{{count}}</div>
- <button @click="setCount">加一</button>
- </div>
-
- </template>
推荐以后都使用ref,因为他既能接受简单类型又能接受复杂类型
- <script setup>
- //const 计算属性
- import {computed,ref} from "vue";
- //声明数据
- const list = ref([1,2,3,4,5])
-
- //基于list派生出一个计算属性,从list中过滤出大于2的所有数
-
- const computedList = computed(()=>{
- return list.value.filter(item=>item>2)
- })
-
- const add=()=>{
- list.value.push(666);
- }
- </script>
- <template>
- <div>
- <div>{{list}}</div>
- <div>{{computedList}}</div>
- <button @click="add">加666</button>
- </div>
- </template>
计算属性的优点是它们可以缓存计算结果,并且只在依赖数据发生变化时才重新计算。这有助于提高性能,并避免不必要的重复计算。
在使用computedList
时,你可以像使用普通属性一样访问它,在模板中进行绑定或在JavaScript代码中读取它。每当list
的值发生变化时,computedList
会自动更新并提供最新的计算结果。
语法:
// 1.监听单个数据的变化 // watch(ref对象,newValue,oldValue)=>{ //})
//2.监听多个数据的变化 //watch([ref对象1,ref对象2],(newArr,oldArr)=>{ // })
//3.immediate 立即执行 // watch(count,(newValue,oldValue)=>{ // console.log(newValue,oldValue); // },{ //immediate:true, //}) //4.deep深度监视 //默认watch进行的是浅层监视 //const ref = ref(简单类型) 可以直接监视 //但是如果是复杂类型,就要使用deep属性进行升读监视 // watch(count,(newValue,oldValue)=>{ // console.log(newValue,oldValue); // },{ //immediate:true, //deep:true //})
5.不开启deep,直接监视复杂类型的某个属性,语法: watch(()=>user.value.age,(newValue,oldValue)=>{ console.log(newValue,oldValue) })
代码示例
- <script setup>
- import {ref,watch} from "vue";
- const count = ref(0);
- const name = ref("宁是");
- const add=()=>{
- count.value++;
- }
- const setName =()=>{
- name.value="李四"
- }
-
- // 1.监听单个数据的变化
- // watch(ref对象,newValue,oldValue)
- // watch(count,(newValue,oldValue)=>{
- // console.log(newValue,oldValue);
- // })
-
- //2.监听多个数据的变化
- //watch([ref对象1,ref对象2],(newArr,oldArr)=>{
- // })
-
- watch([count,name],(newArr,oldArr)=>{
- console.log(newArr,oldArr)
- })
- </script>
-
- <template>
- <div>数量:{{count}}</div>
- <button @click="add">加一</button>
- <div>姓名:{{name}}</div>
- <button @click="setName">修改</button>
- </template>
父组件数据传到子组件:
1.在父组件中给子组件自定义属性并赋值
2.在子组件中使用defineProps来接受
3.此时就能使用父组件传过来的数据了,不过要注意:
//对于props得到的数据,在script里面要用props.car获取数据
//而模块中直接用car即可
子组件:
const props = defineProps({ car:String, money:Number })
console.log(props.car) console.log(props.money)
子组件改变父组件数据
1.父组件给子组件绑定事件,如果触发此事件就执行某方法
<SonCom //此处就是绑定了changeMoney方法,会执行changeFn方法 @changeMoney = "changeFn" car="保安吗" :money="money"> </SonCom>
2.在子组件中用defineEmits注册事件
const emit = defineEmits('changeMoney')
注册完事件后就能在方法里面使用emit通知父组件更新数据了
const buy=()=>{ //需要emit触发事件 emit('changeMoney',5) }
事件名是changeMoney,参数是5
父子通信完整代码演示
父组件:
- <script setup>
-
- import SonCom from '@/components/son-com.vue'
- import {ref} from "vue";
-
- const money = ref(100)
- const addMoney =()=>{
- money.value+=10;
- }
-
- const changeFn =(newMoney)=>{
- money.value = money.value-newMoney
- }
- </script>
-
- <template>
- <div>
- <h3>父组件</h3>
- <!-- 给子组件以添加属性的方式传值-->
- <SonCom
- @changeMoney = "changeFn"
- car="保安吗" :money="money"></SonCom>
- <button @click="addMoney">挣钱</button>
- </div>
- </template>
子组件:
- <script setup>
- const props = defineProps({
- car:String,
- money:Number
- })
- //对于props得到的数据,在script里面要用props.car获取数据
- //而组件中直接用car即可
-
- console.log(props.car)
- console.log(props.money)
- //defineEmits里面的数组填写的是需要触发的事件,事件定义好了才能触发
-
- const emit = defineEmits('changeMoney')
-
- const buy=()=>{
- //需要emit触发事件
- emit('changeMoney',5)
- }
- </script>
- <template>
- <div> 我是子组件-{{car}}--{{money}}
- <button @click="buy">花钱</button>
- </div>
- </template>
-
-
- <style scoped>
-
- </style>
引用dom元素:
1.使用ref生成一个ref对象
const inp = ref(null);
2.在模板中给元素添加属性
<input ref="inp" type="text">
此时就绑定成功了
通过inp.value.focus()能让输入框聚焦
代码示例
父组件:
- <script setup>
-
- import TestCom from "@/components/test-com.vue";
- import {ref} from "vue";
-
- //1.调用ref函数,生成一个ref对象
- //2.通过ref标识,进行绑定
- //3.通过ref对象,value即可访问到绑定的元素
- const inp = ref(null);
-
- const clickFn =()=>{
- inp.value.focus()
- }
- </script>
-
- <template>
- <div>
- <input ref="inp" type="text">
- <button @click="clickFn">点击使输入框聚焦</button>
- </div>
- <TestCom></TestCom>
- </template>
子组件:
-
-
- <script setup>
- const count =999;
- const sayHi=()=>{
- console.log("打招呼")
- }
-
- defineExpose({
- count,
- sayHi
- })
- </script>
-
- <template>
-
- </template>
注意:孙子或者更低的组件得到高级组件传递的数据后,不能直接更改它的值
要想更改它的值,可以让高级组件将修改它的值的方法也传递过来
顶级组件:
- <script setup>
- import {inject} from "vue";
- const themeColor = inject('theme-color')
- const count = inject('count')
- const setCount =inject('setCount')
- const clickFn=()=>{
- setCount(666);
- }
- </script>
-
- <template>
- <div>
- <h3>我是底层组件-{{themeColor}}--{{count}}</h3>
- <button @click="clickFn">修改Count</button>
- </div>
- </template>
中级组件:
- <script setup>
- import BottonCom from "@/components/botton-com.vue";
- </script>
-
- <template>
- <div>
- <h2>我是中间组件</h2>
- <botton-com></botton-com>
- </div>
- </template>
底层组件:
- <script setup>
- import {inject} from "vue";
- const themeColor = inject('theme-color')
- const count = inject('count')
- const setCount =inject('setCount')
- const clickFn=()=>{
- setCount(666);
- }
- </script>
-
- <template>
- <div>
- <h3>我是底层组件-{{themeColor}}--{{count}}</h3>
- <button @click="clickFn">修改Count</button>
- </div>
- </template>
使用Pinia
1.npm install pinia
2.在自己创建的js文件(如counter.js)里面导入Pinia
import {defineStore} from "pinia";
3.创建并导出一个状态管理函数(函数名以use开头),这个函数里面就是仓库内容,(可以声明数据,声明操作数据的方法,声明基于数据派生的计算属性)
记得一定要return
- export const useCounterStore=defineStore('counter',()=>{
- //声明数据
- //第一个数据
- const count = ref(0)
-
- //声明操作数据的方法
- const addCount=()=>count.value++
- const subCount=()=>count.value--
- //声明基于数据派生的计算属性
- const getDoubleCount = computed(()=>count.value*2)
-
-
- //第二个数据
- const msg = ref('hello')
-
-
- //只有return出去后,才能被页面使用
- return{
- count,
- msg,
- addCount,
- subCount,
- getDoubleCount
- }
- })
export导出后就能在其他组件中使用了
4.其他组件中使用:
- import {useCounterStore}from'@/store/counter'
- const counterStore = useCounterStore()
将这个状态管理函数导入即可,使用就直接用' . '来调用变量或者方法
如:
- <template>
- <h3>子组件1 {{counterStore.count}} - {{counterStore.getDoubleCount}}</h3>
- <button @click="counterStore.addCount()">+</button>
- </template>
counterStore.count 和counterStore.getDoubleCount都是从状态管理函数的返回值得到的
156.Pinia的异步方法
- export const useChannelStore =defineStore('channel',()=>{
- //声明数据
- const channelList = ref([])
- const getList = async ()=>{
- const {data:{data}} =await axios.get('https://geek.itheima.net/v1_0/channels')
- channelList.value = data.channels
- }
- return{
- channelList,
- getList
-
- }
- })
res默认会包装一层
1.安装pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate
2.在main.js里面导入
import persist from 'pinia-plugin-persistedstate'
app.use(createPinia().use(persist))
3.在store仓库中(就是一个用来保存数据的js文件)加一条属性
persist : true
- import {defineStore} from "pinia";
- import {computed, ref} from "vue";
- import persist from "pinia-plugin-persistedstate";
-
- //定义store
- //defineStore(仓库的唯一标识(填名字就行),()=>{...})
-
- export const useCounterStore=defineStore('counter',()=>{
- //声明数据
- //第一个数据
- const count = ref(0)
-
- //声明操作数据的方法
- const addCount=()=>count.value++
- const subCount=()=>count.value--
- //声明基于数据派生的计算属性
- const getDoubleCount = computed(()=>count.value*2)
-
- //第二个数据
- const msg = ref('hello')
- //只有return出去后,才能被页面使用
- return{
- count,
- msg,
- addCount,
- subCount,
- getDoubleCount
- }
- },{
- persist:true
- })
这样,该counter里面的数据就会被自动存入本地存储
其中,这一句
export const useCounterStore=defineStore('counter',()=>{
里面的counter就是存本地存储的键名
拓展:
1.修改key
persist:{ key:'nsy-counter' }
2.更改storage
persist:{ key:'nsy-counter', storage:sessionStorage }
3.指定需要进行持久化的数据
(默认是stage里面的所有数据都持久化)
persist:{ key:'nsy-counter', storage:sessionStorage, paths:['count'] }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。