网站建设 图片压缩,计算机网络技术是学什么,注册安全工程师好考吗,网站设计权限1. 脚手架创建项目的区别#xff1a;
vue2: vue init webpack “项目名称”vue3: vue create “项目名称” 或者vue3一般与vite结合使用:
npm create vitelatest
yarn create vite2. template中结构
vue2: template下只有一个元素节点
templatedivdiv…1. 脚手架创建项目的区别
vue2: vue init webpack “项目名称”vue3: vue create “项目名称” 或者vue3一般与vite结合使用:
npm create vitelatest
yarn create vite2. template中结构
vue2: template下只有一个元素节点
templatedivdiv/divdiv/div/div
/templatevue3:template下可以有多个元素节点
templatediv/divdiv/divdiv/div
/template3. main.js入口文件挂载App.vue文件
vue2:
new Vue({app: #app,router,...
})vue3:使用createApp
import App from ./App.vue
import router from ../src/router/index.jscreateApp(App).use(router).mount(#app)
// const app createApp(App)
// app.use(router) // 挂载路由
// app.mount(#app)4. router的区别
vue2:
在这里插入代码片vue3: 使用createRouter使用createRouter必须要写history
import { createRouter, createWebHistory } from vue-routerconst router createRouter({history: createWebHistory(),// history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: /,component: () import(/App.vue),},{path: /props_pre,component: () import(/components/props_test/PropsTest.vue),},]
})export default router5. setup的使用
vue2: 引入子组件需要使用compontents{}挂载
import xx from ..子组件...
scriptexport default {components: { xx }}
/scriptvue3: 引入子组件
templatexx /
/templatescript setupimport xx from ..子组件...; // 引入子组件不需要再compontents{}挂载在template中直接使用即可// 使用setup就不能使用export default{}导出了
/script如果需要使用export default则
scriptexport default {setup() {...},}
/script 6. props的使用
vue2
子组件中:export default{props: {xx: {type: String/Number/Object/Array,default: /0/(){}/()(){}}},// props:[xx1, xx2]}vue3: 如果报错 ‘defineProps’ is not defined则在package.json文件eslintConfig{env: {‘vue/setup-compiler-macros’: true }}中添加’vue/setup-compiler-macros’: true
defineProps([xx1, xx2])不需要引入直接使用,返回一个对象,数组或者对象写法都可子组件中使用 let props defineProps([xx1, xx2]), // 在template中props可以省略{{props.xx1}} {{xx1}}props名字可以随便取templatespan{{props.name}}/span // 可以省略props,直接使用name span{{name}}/span
/template
script setuplet props defineProps([name, age]);
/script7. ref的使用
vue2:
templateChild refchild1 /
/template
// 使用
scriptexport default {mouted() {console.log(this.$refs.child1); // 获取child1的ref有关数据}}
/scriptvue3: 需要先从vue中引入 ref, vue3中不可使用this
templateChild :money money / // 子组件也是用defineProps([money])接收
/templatescript setupimport { ref } from vuelet money ref(10000)
/script8. 自定义事件
下面这个Event1组件上的click
在vue2框架当中这种写法是自定义事件可以通过.native修饰符变为原生DOM事件在vue3框架当中这种写法就是原生DOM事件绑定自定义事件为Event1 xxx“handlexxx” /
templateEvent1 click /
/template自定义事件父子组件传值 Event2 updateList“handlexxx” /
vue2中子组件用this.$emit(‘updateList’, 参数1, 参数2)调用vue3使用setup组合式APIZ没有实例不能用this.$emit,vue3中使用defineEmits方法返回函数触发自定义事件
script setup// 利用defineEmits方法返回函数触发自定义事件// defineEmits方法不需要引入直接使用let $emit defineEmits([updateList]);const handleUpdateList () {$emit(updateList, 参数1, 参数2);}
/script注意
templateEvent2 updateListhandle1 clickhandle2 /
/templatescript setupconst handle1 (参数1, 参数2) {...}// click原生dom事件点击就会执行const handle2 (参数1, 参数2) { // 子组件调用了父组件的click类型的方法需要接收参数, 没调用传参时不用接收参数// alert(123) // 这是之前DOM事件时点击就会执行...}
/scriptEvent2子组件中
templatebutton click$emit(click, 参数1, 参数2)子组件调用父组件click自定义事件/button
templatescript setuplet $emit defineEmits([updateList]); // 此时在父组件点击子组件会执行alert(123)let $emit defineEmits([updateList, click]); // 此时在父组件点击子组件不会执行alert(123)这里把click类型的DOM事件变成了自定义事件...$emit(updateList, 参数1, 参数2)
script9. 组件通信方式之全局事件总线
vue2:兄弟组件通信 b u s ( bus( bus(on, $emit)vue3:没有实例,没有this所以不能使用$bus,使用插件mitt
1.安装mitt
npm i --save mitt
2.新建bus/index.js文件
mitt是一个方法(),方法执行会返回bus对象
import mitt from mitt; // 引入mitt插件
const $bus mitt(); // 名字随意取
export default $bus;
3.使用
在父组件中使用两个子组件
eventBus.vue中
templatediv classboxh1全局事件总线$bus/h1div classdis-flexChildBus1 /ChildBus2 //div/div
/templatescript setup
import ChildBus1 from ./ChildBus1.vue;
import ChildBus2 from ./ChildBus2.vue;
/script在ChildBus1子组件中监听接收
templatediv classchild1h3我是子组件1 曹植/h3/div
/templatescript setup
import $bus from ../../bus/index.ts;
// 组合式API函数
import { onMounted } from vue;
// 当组件挂载完毕时当前组件绑定一个事件接收将来兄弟组件传递的数据
onMounted(() {// 第一个参数:即为事件类型第二个参数即为事件回调$bus.on(car, (car) {console.log(car, 在回调函数内可以做这个组件相应的操作);})
})
/script在ChildBus2子组件中发送
templatediv classchild2h2我是子组件2曹丕/h2button clickhandleClick点击我给我的兄弟送火箭/button/div
/templatescript setup// 引入$bus对象import $bus from ../../bus/index.ts; // 点击按钮回调const handleClick () {$bus.emit(car, {car: 火箭});}
/script10. 组件通信方式之v-model
vue2: vue3: 使用v-model, v-model不仅可以用来收集表单数据实现数据双向绑定还可以用来父子组件之间通信
templateinput typetext v-modelname /
/templatescript setup
// v-model指令收集表单数据数据双向绑定
// v-model也可以实现组件之间的通信实现父子组件数据同步的业务
import { ref } from vue;
let name ref();
/script在vue的3.3版本中新加了defineModel但是跟ref一样需要引入
import { defineModel } from vue;
let xx defineModel();v-model组件身上使用
Child :modelValuemoney update:moneyModelhandleMoney / 等价与
/**v-model组件身上使用第一相当于给子组件传递props[modelValue], 名字一定要叫modelValue第二相当于给子组件绑定自定义事件update:modelValue
*/
Child v-modelmoney /
// 如果是v-model:moneymoney这样的话子组件传递props[money], 名字不一定要叫modelValue了
Child v-model:moneymoney / // 跟多个v-model一样的然后这样的不用再绑定自定义事件$emit那边就能更改父组件
template!-- ChildModel1 :modelValuemoney update:modelValuehandleUpdate / --ChildModel1 v-modelmoney / // 这句就相当于上面那行代码用了这行代码可能会有报错handleUpdate声明了却没使用页面上叉掉报错是能正常增加的
/templatescript setupimport ChildModel1 from ./ChildModel1.vue;
let money ref(100);const handleUpdate (num) {money.value num;
}
/script子组件
templatediv父组件的钱:{{modelValue}}/divbutton clickhandleClick点击更改父组件钱/button
/templatescript setup
const props defineProps([modelValue]);
const $emit defineEmits([update:modelValue]);
const handleClick () {$emit(update:modelValue, props.modelValue 1);
}
/script设置多个v-model
templateChild v-model:pageNopageNo v-model:pageSizepageSize /
/templatescript setupimport { ref } from vue;let pageNo ref(1);let pageSize ref(10);
/script11. 组件通信方式之useAttrs方法
vue3框架提供一个方法useAttrs方法它可以获取组件身上的属性与事件
父组件中调用子组件并传参
templateHintButton typeprimy :sizesmall :iconedit /
/templatescript setupimport HintButton from ./HintButton.vue;
/script在HintButton子组件中
template// 使用$attrsel-button :type$attrs.type/el-button// 还可以使用语法el-button :$attrs/el-button // 这种写法相当于h1 v-bind{a: 1,b: 2} / 可以简写为h1 :{a: 1,b: 2} /
/templatescript setup// 1.这样可以获取子组件上的参数let props defineProps([type, size, icon]);// 2.引入useAttrs方法获取组件标签身上的属性与事件, 此方法执行会返回一个对象import { useAttrs } from vue;let $attrs useAttrs();
/script注意使用defineProps接收过的参数useAttrs()就接收不到了defineProps([xxx])的优先级更高useAttrs方法不仅能接收到父组件传过来的参数还能接收事件(DOM原生click事件和自定义事件),比如HintButton typeprimy :sizesmall :iconedit clickhandle1 handleUpdatehandle2 /
12. 组件通信方式之ref与$parent
ref: 可以获取真实的DOM节点可以获取到子组件实例VC $parent:可以在子组件内部获取到父组件的实例 获取子组件的实例ref需要与组件名称同名: 比如
Son refson / // ref的名称需要与ref获取的名字一样 比如Son refaccount / 下面获取时需要名字相同 let account ref();import { ref } from vue;
import Son from ./refSon.vue;
let son ref();
console.log(son.value);这样能拿到子组件实例但拿不到子组件内部的数据因为 组件内部数据对外关闭的别人不能访问如果想让外部访问需要通过defineExpose方法对外暴露这个方法不仅能暴露属性还能暴露方法 $parent,子组件必须使用这个名称可以拿到父组件的实例父组件的属性也需要暴露出去
父组件代码
templatediv classbox父组件的钱:{{money}}button clickhandler父组件加10/buttonSon refson /Daughter //div
/templatescript setup
import Son from ./refSon.vue;
import Daughter from ./refDaughter.vue;
import { ref } from vue;
let money ref(10000);
let son ref();
const handler () {money.value 10;// 儿子减10son.value.money - 10;son.value.flyFun();
}
defineExpose({money // 暴露出去给daughter.vue组件使用
})
/scriptson组件代码
templatediv classson儿子组件钱:{{money}}/div
/templatescript setup
import { ref } from vue;
let money ref(666);// 组件内部数据对外关闭的别人不能访问
// 如果想让外部访问需要通过defineExpose方法对外暴露,这个方法不仅能暴露属性还能暴露方法
const flyFun () {console.log(想飞咯);
}
defineExpose({money,flyFun
})
/scriptdaughter组件代码
templatediv女孩的钱{{money}}button clickhandler($parent)点击100/button // 把父组件$parent实例作为参数传入函数中/div
/templatescript setup
import { ref } from vue;
let money ref(999);
const handler ($parent) {money.value 100;$parent.money - 100;
}
/script13.组件通信方式之Provide与Inject
vue3提供provide(提供)与inject(注入)可以实现隔辈组件传递数据 在爷爷组件使用provide(传递),在孙子组件inject(获取)
爷爷组件
templatediv classboxprovide: {{car}}ChildPage //div
/templatescript setup
import ChildPage from ./childPage.vue;
import { ref, provide } from vue;
let car ref(豪车);
// vue3提供provide(提供)与infect(注入),可以实现隔辈组件传递数据
// 祖先组件给后代组件提供数据
// 两个参数第一个参数就是提供的数据key
// 第二个参数祖先组件提供数据
provide(TOKEN, car)
/scriptstyle scoped
.box {height: 500px;background: skyblue;
}
/style父亲组件ChildPage.vue中间组件只需要导入孙子组件就行了
templatediv classchild子组件GrandChildPage //div
/templatescript setup
import GrandChildPage from ./grandChildPage.vue;
/scriptstyle scoped
.child {height: 300px;background: pink;
}
/style孙子组件GrandChildPage.vue中使用inject(来获取如果需要更改爷爷组件传递过来的属性值直接修改 xx.value ‘’即可。
templatediv classbox孙子组件:{{car}}button clickupdateCar更新数据/button/div
/templatescript setup
import { inject } from vue;
// 注入祖先组件提供数据
// 需要参数即为祖先提供数据的key
let car inject(TOKEN);
console.log(car);const updateCar () {car.value 自行车; // 更改爷爷组件的car属性值
}
/scriptstyle scoped
.box {height: 100px;background: salmon;
}
/style13.组件通信之pinia组合式API
使用pinia需要先安装piaia: npm i pinia -D; 在src目录下新建store目录创建index.js文件作为大仓库需要在main.js入口文件中引入index.js文件并用使用use挂载
/**
vuex:集中式管理状态容器可以实现任意组件之间的通信核心概念state, mutations, actions, getters, modules */
/**
pinia:集中式管理状态容器可以实现任意组件之间通信核心概念state, actions, getterspinia写法选择器API,组合式API */选择器API
main.js入口文件...........
import { createApp } from vue
import App from ./App.vue
import router from ../src/router/index.js
import store from ./store/index.ts;
createApp(App).use(router).use(store).mount(#app)在store目录下创建modules目录用来装小仓库 src ----store文件夹 -------modules文件夹用来存放小仓库 ---------------info.js小仓库使用defineStoreimport { defineStore } from “pinia”; -------index.js文件用来存放大仓库, 大仓库使用createPiniaimport { createPinia } from “pinia”;
修改store数据
直接修改
import useInfoStore from ../store/modules/info.js;
let info useInfoStore();
info.count ; // 会改变store.count的值使用$patch修改
infoStore.$patch({count: 1111})直接调用仓库内的方法来修改值可以传参
infoStore.updateNum();
infoStore.updateNum(66);在info小仓库内
// 创建小仓库
import { defineStore } from pinia;// 第一个参数 小仓库名字 第二个参数小仓库配置对象
// defineStore方法会返回一个函数函数作用就是让组件可以获取到仓库数据
let useInfoStore defineStore(info, {// 存储数据: statestate: () {return {count: 99,arr: [1,2,3,4,5,6,7,8,9]}},actions: {// 注意函数没有context上下文对象但是有thisthis指向的是这个小仓库updateNum() {this.count;}},getters: {total() { // 有点像computer,需要return返回值let result this.arr.reduce((pre, next) {return pre next;}, 0)return result;}}
});// 对外暴露方法
export default useInfoStore;在组件中使用info小仓库
templatediv classchild1子组件1: {{infoStore.count}}------{{infoStore.total}}button clickupdateCount点击我修改store数据/button/div
/templatescript setup
import useInfoStore from ../../store/modules/info.ts;
// 获取小仓库对象
let infoStore useInfoStore();
const updateCount () {// infoStore.count ; // 这样是可以修改的// infoStore.$patch({// count: 1111// }) // 这个方法也是可以修改的// 仓库调用自身的方法去修改仓库数据infoStore.updateNum();
}
/script组合式API todo.js代码
// 定义组合式API仓库
import { defineStore } from pinia;
import { ref, computed } from vue;// 创建小仓库
let useTodoStore defineStore(todo, () {let todos ref([{id: 1,title: 吃饭},{id: 2,title: 睡觉}]);// let arr [1,2, 3, 4, 5];let arr ref([1, 2, 3, 4, 5]);const total computed(() {return arr.value.reduce((pre, next) pre next, 0);})// 务必要返回一个对象属性与方法可以提供给组件使用return {todos,arr,total,updateTodo(){todos.value.push({id: 3,title: 打豆豆})}}
});export default useTodoStore;在组件中使用
template
p clickupdateTodo{{todoStore.todos}}------{{todoStore.total}}/p
/templatescript setup
import useTodoStore from ../../store/modules/todo.js;
let todoStore useTodoStore();
// 点击p段落去修改仓库的数据
const updateTodo () {todoStore.updateTodo();
}
/script14. 组件通信方式之插槽
默认插槽具名插槽作用域插槽
默认插槽传递组件内容接收组件
父组件内
template
Childdivpre想要在子组件slot插槽展现的内容/pre/div
/Child
/templatescript setup
import Child from ./Child.vue;
/script子组件内
templateslot/slot
/template具名插槽:传递组件使用或者template #xxx#号可以代替v-slot指令简写。接收方使用
父组件内
template
Childtemplate v-slot:contextdiv具名插槽内容/div/template// v-slot指令可以简写为#template #contextdiv具名插槽内容/div/template
/Child
/templatescript setup
import Child from ./Child.vue;
/script子组件内
templateslot namecontext/slot
/template作用域插槽:就是可以传递数据的插槽子组件可以将数据回传给父组件父组件可以决定这些回传的数据是以何种结构或者外观在子组件内部去展示
父组件
templatedivTestPage1 :todostodostemplate v-slot{$row, $index}span :style{color: $row.done ? green : red}{{$row.title}}---{{$index}}/span/template/TestPage1/div
/templatescript setup
import TestPage1 from ./testPage1.vue;
/*** 插槽默认插槽具名插槽作用域插槽*/
import { ref } from vue;
// todos数据
let todos ref([{id: 1, title: 吃饭, done: true},{id: 2, title: 睡觉, done: false},
])
/script
templatedivh1作用域插槽/h1ulli v-for(item, index) in todos :keyitem.id!-- 作用域插槽可以将数据回传给父组件 --slot :$rowitem :$indexindex/slot/li/ul/div
/templatescript setup
// 通过props接收父组件传递数据
defineProps([todos])
/script