Vue3、Vite、Pinia基础学习

2024-08-28 09:52

本文主要是介绍Vue3、Vite、Pinia基础学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Vue3

1、创建一个Vue3应用

<script src="vue.global.js"></script>
<body><div id="app">{{msg}}<h2>{{person.title}}</h2><h2>{{person.name}}</h2></div><script>// 采用解构的方式可以省略Vue.createApp和Vue.reactive前的Vueconst{createApp,reactive}=Vue;Vue.createApp({// setup选项用于设置响应式数据和方法setup(){const person=Vue.reactive({title:"Vue学习",name:"sss",})return{msg:"success",person}}}).mount("#app")    //mount用于挂载到id为app的标签上</script>
</body>

2、Vue3模块化开发

<body><div id="app">{{msg}}<h2>{{person.title}}</h2><h2>{{person.name}}</h2></div><!-- 模块化开发 --><script type="module">// 采用解构的方式可以省略Vue.createApp和Vue.reactive前的Vueimport {createApp,reactive} from './vue.esm-browser.js'createApp({// setup选项用于设置响应式数据和方法setup(){const person=reactive({title:"Vue学习",name:"sss",})return{msg:"success",person}}}).mount("#app")    //mount用于挂载到id为app的标签上</script>
</body>

3、ref和reactive的区别

<body><div id="app">{{msg}}<h2>{{person.title}}</h2><h2>{{person.name}}</h2></div><script type="module">import {createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const number=ref(10);//ref用于存储单个基本类型的数据,如:数字、字符串、数组等const arr=ref([1,2,3,4]);number.value=200;//使用ref创建的响应式对象,需要通过.value属性来访问和修改其值// reactive用于存储复杂数据类型,如对象或数组等const person=reactive({title:"Vue学习",name:"sss",})person.name="scu";//使用reactive创建的响应式对象,可以直接通过属性名来访问和修改值return{msg:"success",person}}}).mount("#app")    </script>
</body>

4、绑定事件v-on

<body><div id="app">{{msg}}<h2>{{person.title}}</h2><h2>{{person.name}}</h2><!-- 绑定事件 --><button v-on:click="edit">修改</button><br><!-- v-on简写形式 --><button @click="edit">修改(简写形式)</button></div><script type="module">import {createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const person=reactive({title:"Vue学习",name:"sss",})//构建函数const edit=()=>{person.name="hjklakhs";}return{msg:"success",person,edit}}}).mount("#app")    </script>
</body>

5、按键修饰符

按键修饰符:

  • enter回车
  • space空格
  • tab键
  • keyup是在用户松开按键时才触发
  • keydown是在用户按下按键时立即触发
<body><div id="app">{{msg}}<h2>{{person.title}}</h2><h2>{{person.name}}</h2><h2>{{person.user}}</h2><!-- 按键修饰符 -->回车<input type="text" @keyup.enter="add(40,60)"><br>空格<input type="text" @keyup.space="add(20,30)"><br>Tab <input type="text" @keydown.tab="add(30,40)"><br>w   <input type="text" @keyup.w="add(32,43)"><br><!-- 组合快捷键 -->ctrl + Enter <input type="text" @keyup.ctrl.enter="add(34,58)"><br>ctrl + A     <input type="text" @keyup.ctrl.a="add(22,30)"><br></div><script type="module">import {createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const person=reactive({title:"Vue学习",name:"sss",user:0})const add=(x,y)=>{person.user+=x+y;}return{msg:"success",person,add}}}).mount("#app")    </script>
</body>

6、显示和隐藏v-show

  • v-show通过css display属性来控制元素的显示或隐藏
  • v-show适用于频繁切换元素的显示状态,因为只改变display属性,不需要重新渲染整个组件
<body><div id="app">{{web.show}}<hr><!-- 显示和隐藏v-show --><p v-show="web.show">西游记 黑神话悟空</p><button @click="toggle()">切换状态</button></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const web=reactive({show:true})const toggle=()=>{web.show=!web.show;}return{web,toggle}}}).mount("#app")</script>
</body>

7、条件渲染v-if

  • v-if用于对元素进行条件渲染,当条件为true时,渲染该元素,为false时,则不渲染
  • v-if适用于较少改变的场景,因为频繁从dom中删除或添加元素,会导致性能下降
<body><div id="app">{{web.show}}<hr><!-- v-if条件渲染 --><p v-if="web.show">西游记 黑神话悟空</p><button @click="toggle()">切换状态</button><!-- v-if-else --><p v-if="web.user<1000">新网站</p><p v-else-if="web.user>=1000&&web.user<=10000">优秀网站</p><p v-else="web.user">资深网站</p></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const web=reactive({show:true,user:10005})const toggle=()=>{web.show=!web.show;}return{web,toggle}}}).mount("#app")</script>
</body>

8、动态属性绑定v-bind

  • 单向数据绑定:当数据发生改变时,视图会自动更新,但用户手动更改input的值,数据不会自动更新。
  • 单向数据绑定<input type="text"  :value="data.txt">
    <style>.textColor{color: rebeccapurple;}</style><body><div id="app"><!-- 动态属性绑定v-bind --><!-- :value --><h3>value="www.baidu.com"</h3><!-- <input type="text" value="www.baidu.com"> --><input type="text" v-bind:value="web.url"><!-- 简写 --><input type="text" :value="web.url"><!-- :src --><h3>src="dhimg1.png"</h3><!-- <img src="../resource/image/dhimg1.png" alt=""> --><img :src="web.img" alt=""><!-- :class --><h3>class="textColor"</h3><!-- <b class="textColor">西游记</b> --><b :class="{textColor:web.Status}">西游记</b></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const web=reactive({url:"www.baidu.com",img:"../resource/image/dhimg1.png",Status:true})return{web}}}).mount("#app")</script>
</body>

9、遍历数组或对象v-for

<body><div id="app"><!-- 遍历数组或对象v-for --><ul><li v-for="(value,index) in web.number">{{index}}:{{value}}</li></ul><ul><li v-for="(value,key,index) in web.user">{{index}}:{{key}}:{{value}}</li></ul><ul><template v-for="(value,key,index) in web.user"><li v-if="index==1">{{index}}:{{key}}:{{value}}</li></template></ul><ul><li v-for="(value,index) in web.teacher" :title="value.name" :key="value.id">{{index}}:{{value.id}}:{{value.name}}:{{value.web}}</li></ul></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const web=reactive({number:["十","十一","十二"],//数组user:{name:"sss",age:20},//对象teacher:[{id:100,name:"lucy",web:"baidu.com"},{id:101,name:"jucy",web:"bai.com"}]//包含两个对象的数组})return{web}}}).mount("#app")</script>
</body>

10、双向数据绑定v-model

  • 双向数据绑定:当数据发生改变时,视图会自动更新,用户手动更改input的值,数据也会自动更新。对于<input type="text">,v-model绑定的是input元素的value属性。
  • 双向数据绑定<input type="text"  v-model=“data.txt">
<body><div id="app"><!-- 双向数据绑定v-model --><h3>文本框{{data.text}}</h3><h3>单选框{{data.radio}}</h3><h3>复选框{{data.checkbox}}</h3><h3>记住密码{{data.remember}}</h3><h3>下拉框{{data.select}}</h3><!-- 单向数据绑定 --><input type="text" :value="data.text"><br><!-- 双向数据绑定 --><input type="text" v-model="data.text"><br><!-- 单选框 --><input type="radio" v-model="data.radio" value="1">写作<input type="radio" v-model="data.radio" value="2">画画<br><!-- 复选框 --><input type="checkbox" v-model="data.checkbox" value="a">写作<input type="checkbox" v-model="data.checkbox" value="b">画画<input type="checkbox" v-model="data.checkbox" value="c">运动<br><!-- 单个复选框 --><input type="checkbox" v-model="data.remember">记住密码<br><!-- 下拉框 --><select v-model="data.select"><option value="">请选择</option><option value="A">写作</option><option value="B">画画</option><option value="C">运动</option></select></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const data=reactive({text:"baidu.com",//文本框radio:"",//单选框checkbox:[],//复选框remember:false,//单个复选框 记住密码select:""//下拉框})return{data}}}).mount("#app")</script>
</body>

11、v-model修饰符

  • 在失去焦点或按下回车键之后渲染用 v-model.lazy
  • 输入框的值转换为数字类型用 v-model.number
  • 去除首尾空格 v-model.trim

<body><div id="app"><h3>{{web.url}}</h3><h3>{{web.user}}</h3>实时渲染<input type="text" v-model="web.url"><br>在失去焦点或按下回车键之后渲染<input type="text" v-model.lazy="web.url"><br>输入框的值转换为数字类型<input type="text" v-model.number="web.user"><br>去除首尾空格<input type="text" v-model.trim="web.url"></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const web=reactive({url:"baidu.com",user:10})return{web}}}).mount("#app")</script>
</body>

12、渲染数据v-text和v-html

  • v-text将数据解析为纯文本格式
  • v-html将数据解析为html格式
<body><div id="app"><h3>{{web.title}}</h3><h3 v-text="web.title"></h3><h3 v-html="web.url"></h3><h3 v-text="web.url"></h3></div><script type="module">import{createApp,reactive} from './vue.esm-browser.js'createApp({setup(){const web=reactive({url:"<i style='color:blue;'>baidu.com</i>",title:"javascript"})return{web}}}).mount("#app")</script>
</body>

13、计算属性computed

<body><div id="app"><h3>{{add()}}</h3><h3>{{add()}}</h3><!-- sub是属性不是方法 --><h3>{{sub}}</h3><h3>{{sub}}</h3>x <input type="text" v-model.number="data.x"><br>y <input type="text" v-model.number="data.y"></div><script type="module">// 导入computedimport{createApp,reactive,computed} from './vue.esm-browser.js'createApp({setup(){const data=reactive({x:10,y:20})// 方法:无缓存const add=()=>{console.log("add");//打印流程return data.x+data.y;}// 计算属性-有缓存(计算属性根据其依赖的响应式数据变化而重新计算)const sub=computed(()=>{console.log("sub");return data.x-data.y;})return{data,add,sub}}}).mount("#app")</script>
</body>

14、侦听器watch

<body><div id="app">爱好<select v-model="hobby"><option value="">请选择</option><option value="1">写作</option><option value="2">画画</option><option value="3">运动</option></select><hr>年<select v-model="data.year"><option value="">请选择</option><option value="2023">2023</option><option value="2024">2024</option><option value="2025">2025</option></select>月<select v-model="data.month"><option value="">请选择</option><option value="10">10</option><option value="11">11</option><option value="12">12</option></select></div><script type="module">// 导入watchimport{createApp,reactive,ref,watch} from './vue.esm-browser.js'createApp({setup(){const hobby=ref("");//爱好const data=reactive({year:"2023",month:"10"})// 侦听对象hobbywatch(hobby,(newValue,oldValue)=>{console.log(newValue,oldValue);if(newValue=="2"){console.log("画画");}})// 监听datewatch(data,(oldValue,newValue)=>{/*JS中对象和数组是通过引用传递的,而不是通过值传递当修改对象或数组的值时,实际上修改的是对对象或数组的引用,而不是创建一个新的对象或数组所以,如果修改了对象或数组的值,那么打印出来的结果则是修改后的值*/console.log(oldValue,newValue);if(newValue.year=="2025"){console.log("2025");}})// 监听date中的某个属性yearwatch(()=>data.year,(newValue,oldValue)=>{console.log(oldValue,newValue);if(data.year=="2024"){console.log("2024");}})return{hobby,data}}}).mount("#app")</script>
</body>

15、自动侦听器watchEffect

<body><div id="app">爱好<select v-model="hobby"><option value="">请选择</option><option value="1">写作</option><option value="2">画画</option><option value="3">运动</option></select><hr>年<select v-model="data.year"><option value="">请选择</option><option value="2023">2023</option><option value="2024">2024</option><option value="2025">2025</option></select>月<select v-model="data.month"><option value="">请选择</option><option value="10">10</option><option value="11">11</option><option value="12">12</option></select></div><script type="module">// 导入watchEffectimport{createApp,reactive,ref,watchEffect} from './vue.esm-browser.js'createApp({setup(){const hobby=ref("");//爱好const data=reactive({year:"2023",month:"10"})// 自动监听watchEffect(()=>{console.log("监听开始");if(hobby.value=="2"){console.log("画画");}if(data.year=="2025"){console.log("2025");}if(data.month=="10"){console.log("10");}console.log("监听结束");})return{hobby,data}}}).mount("#app")</script>
</body>

16、图片轮播案例

<body><div id="app"><h3>{{number}}</h3><img :src=`../resource/image/dhimg${number}.png`  style="width: 300px;"><br><button @click="next">下一张</button><button @click="prev">上一张</button><hr><ul><li v-for="value in 4"><a href="#" @click="jump(value)">{{value}}</a></li></ul></div><script type="module">import{createApp,reactive,ref} from './vue.esm-browser.js'createApp({setup(){const number=ref(2)const next=()=>{number.value++;if(number.value=="5"){number.value=1;}}const prev=()=>{number.value--;if(number.value=="0"){number.value=5;}}const jump=(value)=>{number.value=value;}return{number,next,prev,jump}}}).mount("#app")</script>
</body>

17、记事本案例

<body><div id="app"><input type="text" v-model="data.content"><button @click="add">添加</button><ul><li v-for="(value,index) in data.list">{{value}}<button @click="del(index)">删除</button></li></ul>{{data.list.length}}<button @click="clear">清空</button></div><script type="module">import{createApp,reactive,ref} from './vue.esm-browser.js'createApp({setup(){const data=reactive({content:"baidu.com",list:["sss","yyy"]})const add=()=>{data.list.push(data.content);console.log(data.list)}const del=(index)=>{data.list.pop(index);}const clear=()=>{data.list=[];}return{data,add,del,clear}}}).mount("#app")</script>
</body>

18、购物车案例

<body><div id="app"><table><thead><tr><td><input type="checkbox" v-model="data.selected" @change="selectAll"></td><td>商品</td><td>单价</td><td>库存</td><td colspan="2">操作</td></tr></thead><tbody><tr v-for="(value,index) in data.list"><td><input type="checkbox" :value="value" v-model="data.checkboxList" @change="changeSelect"></td><td>{{value.name}}</td><td>{{value.price}}</td><td>{{value.stock}}</td><td><button @click="sub(value)">-</button>{{value.number}}<button @click="add(value)">+</button></td><td><button @click="del(index,value.id)">删除</button></td></tr></tbody><tfoot><tr><td>总价{{totalPrice()}}</td></tr></tfoot></table></div><script type="module">import{createApp,reactive,ref} from './vue.esm-browser.js'createApp({setup(){const data=reactive({selected:false,checkboxList:[],list:[{id:1,name:"铅笔",price:10,number:1,stock:3},{id:2,name:"鼠标",price:20,number:2,stock:5},{id:3,name:"键盘",price:30,number:1,stock:6}],})const selectAll=()=>{console.log(data.selected);if(data.selected){data.checkboxList=data.list;}else{data.checkboxList=[];}}const changeSelect=()=>{if(data.checkboxList.length==data.list.length&&data.list.length!=0){data.selected=true;}else{data.selected=false;}}const totalPrice=()=>{let total=0;for(let i=0;i<data.checkboxList.length;i++){total+=data.checkboxList[i].price*data.checkboxList[i].number;}return total;}const add=(value)=>{value.number++;if(value.number>=value.stock){value.number=value.stock;}}const sub=(value)=>{value.number--;if(value.number<=1){value.number=1;}}const del=(index,id)=>{data.list.splice(index,1);let newArr=data.checkboxList.filter((value,index)=>{return value.id!=id;})data.checkboxList=newArr;changeSelect();}return{data,selectAll,changeSelect,totalPrice,add,sub,del}}}).mount("#app")</script>
</body>

19、购物车案例优化

<body><div id="app"><table><thead><tr><td><input type="checkbox" v-model="data.selected" ></td><td>商品</td><td>单价</td><td>库存</td><td colspan="2">操作</td></tr></thead><tbody><tr v-for="(value,index) in data.list"><td><input type="checkbox" :value="value" v-model="data.checkboxList" @change="changeSelect"></td><td>{{value.name}}</td><td>{{value.price}}</td><td>{{value.stock}}</td><td><button @click="sub(value)">-</button>{{value.number}}<button @click="add(value)">+</button></td><td><button @click="del(index,value.id)">删除</button></td></tr></tbody><tfoot><tr><td>总价{{totalPrice}}</td></tr></tfoot></table></div><script type="module">import{createApp,reactive,watch,computed} from './vue.esm-browser.js'createApp({setup(){const data=reactive({selected:false,checkboxList:[],list:[{id:1,name:"铅笔",price:10,number:1,stock:3},{id:2,name:"鼠标",price:20,number:2,stock:5},{id:3,name:"键盘",price:30,number:1,stock:6}],})let flag=true;watch(()=>data.selected,(newValue,oldValue)=>{if(newValue){data.checkboxList=data.list;}else{if(flag){data.checkboxList=[];}}})watch(()=>data.checkboxList,(newValue,oldValue)=>{if(newValue.length==data.list.length&&data.list.length!=0){data.selected=true;}else{data.selected=false;flag=false;}})const totalPrice=computed(()=>{/*reduce定义:用于对数组中所有元素进行迭代操作,并将每次操作的结果累加到一个初始值上reduce接收两个参数:一个是累加器函数,另一个是初始值reduce:将data.checkboxList数组中的每个checkbox对象的price和number属性进行相乘,并将结果累加到初始值0上,最后返回累加的结果total(累加器)用于存储每次计算的结果,初始值为0item(当前元素)在每次迭代过程中,当前元素的值会被传递给回调函数*/return data.checkboxList.reduce((total,item)=>total+item.price*item.number,0)})const add=(value)=>{value.number++;if(value.number>=value.stock){value.number=value.stock;}}const sub=(value)=>{value.number--;if(value.number<=1){value.number=1;}}const del=(index,id)=>{data.list.splice(index,1);let newArr=data.checkboxList.filter((value,index)=>{return value.id!=id;})data.checkboxList=newArr;}return{data,totalPrice,add,sub,del}}}).mount("#app")</script>
</body>

Vite

1、基于Vite创建Vue3项目

  • 在指定目录下打开cmd执行命令 npm create vite@latest

  • 打开src文件夹删除style.css文件和HelloWorld.vue文件
  • 打开main.js文件删除  import './style.css'
  • 打开App.vue文件删除 import HelloWorld from './components/HelloWorld.vue' 和 默认样式

2、导入组件

<script setup>//导入子组件//App.vue是父组件,因为它包含了header.vue和footer.vue两个子组件import Header from "./components/header.vue"import Footer from "./components/footer.vue"
</script><template><Header/><Footer/>
</template><style scoped></style>

3、父传子defineProps

/*App.vue文件*/
<script setup>import { reactive } from 'vue';//导入子组件//App.vue是父组件,因为它包含了header.vue和footer.vue两个子组件import Header from './components/header.vue';import Footer from './components/footer.vue';// const propsweb = {//   user:10,//   url:"ww.baidu.com"// }const propsweb = reactive({user:10,url:"www.baidu.com"})const userAdd=()=>{propsweb.user++;console.log(propsweb.user);}
</script><template><!-- 父传子 - 方式1 --><Header propsname="孙悟空" propsurl="baidu.com" /><button @click="userAdd">添加用户</button><!-- 父传子 - 方式2 --><!-- <Footer v-bind="propsweb"/> --><!-- v-bind简写 --><Footer :="propsweb"/>
</template><style scoped></style>/*header.vue文件*/
<script setup>//接收方式:数组const props = defineProps(["propsname","propsurl"])console.log(props);
</script><template><h3>header</h3>
</template><style scoped></style>/*footer.vue文件*/
<script setup>//接收方式:对象const props=defineProps({user:Number,url:{type:String,required:false,//true表示必传属性,若未传则会提示警告信息default:"baidu.com"//未传默认值}})console.log(props)
</script><template><h3>footer</h3> {{ props.user }}
</template><style scoped></style>

4、子传父defineEmits

/*App.vue文件*/
<script setup>import{reactive,ref} from 'vue'import Header from './components/header.vue'// 响应式数据const web = reactive({name:"孙悟空",url:"baidu.com"})const user = ref(0)const emitsGetWeb=(data)=>{console.log(data)web.url=data.url;}const emitsUserAdd=(data)=>{console.log(data);user.value+=data;}
</script><template><Header @getweb="emitsGetWeb" @userAdd="emitsUserAdd"/>{{ web.url }} - {{ user }}
</template><style scoped></style>
/*header.vue文件*/
<script setup>const emits = defineEmits(["getweb","userAdd"])emits("getweb",{name:"黑神话",url:"www.baidu.com"})const add=()=>{emits("userAdd",10)}
</script><template><h3>header</h3><button @click="add">添加用户</button>
</template><style scoped></style>

5、跨组件通信-依赖注入

/*App.vue文件*/
<script setup>import{ref,provide,reactive} from 'vue'// 导入子组件import Header from './components/header.vue'// 响应式数据const web = reactive({name:"孙悟空",url:"baidu.com"})//provide用于父组件将数据提供给所有子组件/*若使用了provide和inject来进行数据传递,则一般不需要再使用defineProps*/provide("provideWeb",web)const user = ref(0)provide("provideUser",user)const userAdd=()=>{user.value++;}//用于父组件将函数提供给所有子组件provide("provideFuncUserAdd",userAdd)
</script><template><h3>App.vue-Top组件</h3>user:{{ user }}<!-- 子组件 --><Header/>
</template><style scoped></style>/*header.vue文件*/
<script setup>// 导入子组件import Footer from "./footer.vue"import {inject} from 'vue'//子组件通过inject注入父组件提供的响应式数据const user = inject("provideUser")console.log("provideUser",user)
</script><template><h3>header.vue-Middle组件</h3><!-- 子组件 --><Footer/>
</template><style scoped></style>/*footer.vue文件*/
<script setup>import { inject } from 'vue';//子组件通过inject注入父组件提供的响应式数据const web=inject("provideWeb");console.log("provideWeb",web);//子组件通过inject注入父组件提供的响应式数据const FuncUserAdd = inject("provideFuncUserAdd")console.log(FuncUserAdd)
</script><template><h3>footer.vue-Bottom组件</h3> <button @click="FuncUserAdd">添加用户</button>
</template><style scoped></style>

6、匿名插槽和具体插槽v-slot

  • 插槽是指可以在父组件内自定义模板片段,在子组件中可以将定义的模板片段插入到子组件的特定位置。

/*App.vue文件*/
<script setup>// 导入子组件import Header from './components/header.vue';import Footer from './components/footer.vue';
</script><template><h3>App.vue</h3><Header><a href="baidu.com">百度</a></Header><Footer><!-- <template v-slot:url> --><!-- v-slot简写形式 --><template #url><a href="www.baidu.com">网址</a></template></Footer>
</template><style scoped></style>/*header.vue文件*/
<script setup></script><template><h3>header.vue子组件</h3><!-- 匿名插槽 --><slot/>
</template><style scoped></style>/*footer.vue文件*/
<script setup></script><template><h3>footer.vue子组件</h3> <!-- 具名插槽 --><slot name="url"/>
</template><style scoped></style>

7、作用域插槽

  • 作用域插槽:子组件向父组件传递数据,并在父组件定义的模板中渲染

/*App.vue文件*/
<script setup>// 导入子组件import Header from './components/header.vue';import Footer from './components/footer.vue';
</script><template><h3>App.vue</h3><Header><a href="baidu.com">百度</a></Header><Footer><!-- <template v-slot:url> --><!-- 作用域插槽 --><template #url="data"><!-- 解构形式 --><!-- <template #url="{title,user}"> --><!-- data用于接收数据 -->{{ data.title }}{{ data.user }}<a href="www.baidu.com">网址</a></template></Footer>
</template><style scoped></style>/*footer.vue文件*/
<script setup></script><template><h3>footer.vue子组件</h3> <!-- 具名插槽 --><slot name="url" title="摆渡" user="1000"/>
</template><style scoped></style>

8、生命周期函数

生命周期函数是组件实例从创建到销毁过程中不同时间点自动调用的函数。

1、挂载阶段:

  •  onBeforeMount:在组件实例即将被挂载到DOM之前调用,此时模板还未编译或渲染到DOM,通常用于执行初始化操作,如:获取异步数据、设置初始属性值等。
  • onMounted:在组件成功挂载到DOM并完成首次渲染后调用,此时可以访问和操作DOM元素,并执行与页面交互相关的逻辑。

2、更新阶段:

  • onBeforeUpdate (由于响应式数据变化):在组件更新之前在重新渲染时之前调用,可以根据新的参数判断是否需要进行特殊处理,甚至可以选择阻止此次更新过程。
  • onUpdated:在组件完成更新并重新渲染后调用,可以基于新的渲染结果处理更新后的数据。

3、卸载阶段:

  • onBeforeUnmount:在组件从DOM中销毁之前调用,用于释放资源,如:清理计时器、解绑事件监听器等。
  • onUnmounted:在组件已经从DOM中移除并销毁后调用,确保组件所占用的所有资源都被正确释放。

4、错误处理:

  • onErrorCaptured:在捕获到组件中的错误时调用,用于处理错误,如:记录错误日志等。
<script setup>import { onMounted,onUpdated,ref} from 'vue';// 在组件成功挂载到DOM并完成首次渲染后调用onMounted(()=>{console.log("onMounted")})// 组件更新后调用onUpdated(()=>{console.log("onUpdated")})const user = ref(0)console.log(user.value)
</script><template>{{ user }}<button @click="user++">添加用户</button>
</template><style scoped></style>

9、toRef和toRefs

  • toRefs将一个响应式对象的所有属性转换为ref对象
  • toRef将一个响应式对象的某个属性转换为ref变量
<script setup>import {reactive,toRefs,toRef} from 'vue';let web=reactive({name:"黑神话",url:"baidu.com"})// let{name,url}=toRefs(web);let url=toRef(web,"url")console.log(url)
</script><template>{{ url }}
</template><style scoped></style>

Pinia

1、Pinia简介

  • Pinia是一个轻量级的状态管理库,状态管理库是用于管理应用程序全局状态的工具。
  • Pinia可以处理大型项目中复杂的状态管理需求,而父传子、子传父以及跨组件通信,可以解决一些简单的状态传递问题,更适合小型项目。
  • 对于复杂的状态管理需求,使用Pinia是更好的选择,而对于简单的状态管理需求,使用localStorage是更简单的解决方案。

  • 以登录为例:使用Pinia创建一个userStore来集中管理用户的登录状态和过期时间。
    • 当用户登录成功时:设置userStore中用户的登录状态为已登录,并设置过期时间。
    • 当用户退出登录时:修改userStore中用户的登录状态为未登录,并删除过期时间。

2、安装Pinia以及定义和使用Store

  • 在终端中输入命令安装npm install pinia
//main.js文件import { createApp } from 'vue'
//导入Pinia的createPinia方法,用于创建Pinia实例(状态管理库)
import {createPinia} from 'pinia'
import App from './App.vue'
//创建一个Pinia实例,用于在应用中集中管理状态(store)
const pinia = createPinia()
// createApp(App).mount('#app')
const app = createApp(App)
app.use(pinia)//将Pinia实例注册到Vue应用中
app.mount("#app")//web.js文件// 定义仓库
import { defineStore } from "pinia";
import { reactive,ref } from "vue";
//定义一个基于Pinia的Storeexport const useWebStore = defineStore('web',()=>{const web=reactive({title:"仓库管理",url:"baidu.com"})const users=ref(1000)const userAdd=()=>{users.value++;}return{web,users,userAdd}
})//App.vue文件
<script setup>import {useWebStore} from './stores/web.js'const webStore =useWebStore()console.log(webStore.web)console.log(webStore.users)
</script><template>{{ webStore.web.url }}{{ webStore.users }}<button @click="webStore.userAdd">添加用户</button>
</template><style scoped></style>

3、Pinia持久化存储插件

1、安装npm i pinia-plugin-persistedstate

2、将插件添加到 pinia 实例上

import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

3、创建 Store 时,将 persist 选项设置为 true

//组合式语法
import { defineStore } from 'pinia'
import { ref } from 'vue'export const useStore = defineStore('main',() => {const someState = ref('你好 pinia')return { someState }},{persist: true,},
)

这篇关于Vue3、Vite、Pinia基础学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114428

相关文章

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

python解析HTML并提取span标签中的文本

《python解析HTML并提取span标签中的文本》在网页开发和数据抓取过程中,我们经常需要从HTML页面中提取信息,尤其是span元素中的文本,span标签是一个行内元素,通常用于包装一小段文本或... 目录一、安装相关依赖二、html 页面结构三、使用 BeautifulSoup javascript

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06