vue2 脚手架

安装

文档:https://cli.vuejs.org/zh/
第一步:全局安装(仅第一次执行)
npm install -g @vue/cli

yarn global add @vue/cli
备注:如果出现下载缓慢:请配置npm 淘宝镜像:
npm config set registry https://registry.npm.taobao.org
安装的时候如果报错证书过期:
一:
清除npm缓存
npm cache clean --force
取消ssl验证:
npm config set strict-ssl false
之后再npm install

二:
npm config set registry http://registry.cnpmjs.org
npm config set registry http://registry.npm.taobao.org

第二步:切换到你要创建项目的目录,然后使用命令创建项目
名称不能再包含大写字母
vue create domeapp
第三步:启动项目
npm run serve

public/index.html 的代码理解

<!DOCTYPE html>
<html lang=""><head><meta charset="utf-8"><!-- 针对IE浏览器的一个特殊配置,含义是让IE浏览器以最高的渲染级别渲染页面 --><meta http-equiv="X-UA-Compatible" content="IE=edge"><!-- 开启移动端的理想视口 --><meta name="viewport" content="width=device-width,initial-scale=1.0"><!-- 配置页签图标 --><link rel="icon" href="<%= BASE_URL %>favicon.ico"><!-- 配置网页标题 --><title>哈哈系统</title></head><body><!-- 当浏览器不支持JS时noscript中的元素就会被渲染 --><noscript><strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><!-- 容器 --><div id="app"></div></body>
</html>

main.js render说明

/*该文件是整个项目的入口文件
*/
//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false/*关于不同版本的vue:1.vue.js与vue.runtime.xxx.js的区别:(1). vue.js是完整版的Vue,包含:核心功能+模板解析器。(2). vue.runtime.xxx.js是运动版的Vue.只包含:核心功能:没有模板解析器。2.因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容
*///创建vue实例对象---vm
new Vue({// el:'#app',   相当于.$mount('#app')  二者存一//下面这行代码,完成了这个功能,将APP组件放入容器中render: h => h(App),  //相当于 render: createElement => createElement(App)   createElement => createElement('h1','你好')
}).$mount('#app')

https://cli.vuejs.org/zh/config/#vue-config-js 文档 vue.config.js 是一个可选的配置文件 可以对脚手架进行个性化定制 可以修改webpack默认配置属性

单个单词组件名报错: error Component name “School” should always be multi-word vue/multi-word-component-names
这个错误是由 Vue.js 的 ESLint 插件生成的,插件名为 vue/multi-word-component-names。这个规则要求 Vue 组件的名称应该由多个单词组成,以避免与现有的或未来的 HTML 元素冲突。
解决方案一:在根目录下找到vue.config.js文件(如果没有则新建一个),添加下面的代码

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,lintOnSave:false,  //关闭eslint校验
})

但是官方并不建议直接关闭校验,因为此方法只是编译时不报错,如果使用vscode+eslint会在文件头标红提示,所以推荐下一种方式。

解决方案二:在ESlint的配置文件eslintrc.js中(如果没有在根目录下新建一个名为**.eslintrc.js**的文件,注意!最前面有个点)将以下代码复制进去,此方案是根据文件进行关闭规则,更适用。

module.exports = {root: true,env: {node: true},'extends': ['plugin:vue/essential','eslint:recommended'],parserOptions: {parser: '@babel/eslint-parser'},rules: {'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off','no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',},overrides: [//这里是添加的代码{files: ['src/components/**','src/pages/**'],   // 匹配views和二级目录中的index.vuerules: {'vue/multi-word-component-names':"off",} //给上面匹配的文件指定规则},{//这就是匹配目录下的所有vue文件files: ['**/__tests__/*.{j,t}s?(x)','**/tests/unit/**/*.spec.{j,t}s?(x)'],env: {jest: true}}]
}

ref属性

1.被用来给元素或子组件注册引用信息(id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方式

<template><div><!-- 打标识ref='xxx' --><h1 ref="doen">{{ title }}</h1><button ref="btn" @click="showDom">点我输出上方的DOM元素</button><School ref="sch" msg="你好"/></div>
</template><script>
//引入组件
import School from './components/School.vue'
export default {name: 'App', //组件名components: {  //注册组件School},data(){return {title:'你好打工'}},methods:{showDom(){//获取this.$refs.xxxconsole.log(this.$refs.doen) //真实DOM元素console.log(this.$refs.btn)//真实DOM元素console.log(this.$refs.sch) //School组件的实例对象(vc)}}
}
</script>

props配置

props是只读的,vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,
那么请复制props的内容到data中一份,然后去修改data中的数据。

父组件

<template><div><School name="李四" sex="女" :age="18" /></div>
</template><script>
//引入组件
import School from './components/School.vue'
export default {name: 'App', //组件名components: {  //注册组件School},
}
</script>

子组件

<template><div><h1>学生姓名:{{ name }}</h1><h1>学生性别:{{ sex }}</h1><h1>学生年龄:{{ myAge+1 }}</h1><button @click="updateAge">尝试修改收到的年龄</button></div>
</template><script>
export default {name: 'School',data(){return{myAge:this.age  //props优先级更高}},//三种写法 1.简单声明接收 接收数据// props:['name','sex','age']//三种写法 2.接收的同时对数据进行类型限制// props:{//   name:String,//   sex:String,//   age:Number// }//三种写法 3.接收的同时对数据进行类型限制+默认值的指定+必要性的限制props:{name:{type:String,//name的类型是字符串required:true,//name是必须的},sex:{type:String,//类型是字符串required:true,//必须的},age:{type:Number,//name的类型是字符串default:99   //默认值},},methods:{updateAge(){this.myAge++}}
}
</script>

mixin 混入

功能:可以把多个组件共用的配置提取成一个混入对象
第一步:定义混合
mixintest.js

 export const mixin1= {//vue里面可以写的这里都可以写methods:{showName(){alert(this.name)}},mounted(){console.log('你好啊')}
}export const hunhe= {//vue里面可以写的这里都可以写data(){return{x:100,y:200}}
}

第二步:使用混入
全局混入 所有的vc以及vm都会得到这个东西 (不推荐)
main.js

/*该文件是整个项目的入口文件
*/
//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false
//全局混合//引入一个混合
import {mixin1,hunhe} from './mixintest.js'
Vue.mixin(mixin1) //挂载全局
Vue.mixin(hunhe)  //挂载全局
//创建vue实例对象---vm
new Vue({render: h => h(App),  
}).$mount('#app')

组件使用

<template><div><h1 @click="showName">学校:{{ name }}</h1><h1>学校地址:{{ address }}</h1></div>
</template><script>
//引入一个混合
//import {mixin1,hunhe} from '../mixintest.js'
export default {name: 'School',data(){return{name:'清华',address:'北京'}},//配置混合 值是接收一个数组 和原有的数据或者方法 组合在一起可以用//mixins:[mixin1,hunhe],mounted(){console.log('你好啊!!!!!!')}
}
</script>

局部组件混入(推荐)

<template><div><h1 @click="showName">学生姓名:{{ name }}</h1><h1>学生性别:{{ sex }}</h1><h3>{{ x }}</h3></div></template><script>//引入一个混合
import {mixin1,hunhe} from '../mixintest.js'export default {name: 'Student',//如果和混合的数据发生冲突的时候 以自身的为主data(){return{name:'张三',sex:'男',x:666}},//配置混合 值是接收一个数组 和原有的数据或者方法 组合在一起可以用mixins:[mixin1,hunhe]}</script>

插件

功能:用于增强vue
本质:包含install方法的一个对象,install的第一个参数是vue,第二个以后的参数是插件使用者传递的数据。
定义插件:plugins.js

export default {install(Vue,x,y,z){console.log(x,y,z)//全局过滤器Vue.filter('mySlice',function(value){return value.slice(0,4)})//自定义全局指令Vue.directive('fbind',{//指令与元素成功绑定时(一上来)bind(element,binding){element.value=binding.value},//指令所在元素被插入页面时inserted(element){element.focus()},//指令所在的模板被重新解析时update(element,binding){element.value=binding.value}})//定义混入Vue.mixin({data(){return{x:100,y:200}}})//给vue原型上添加一个方法(vm和vc就都能用了)Vue.prototype.hello=()=>{alert('你好啊')}}
}

使用插件Vue.use()
main.js

//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false//引入插件
import plugins from './plugins'
//应用(使用)插件
Vue.use(plugins,1,2,3)//创建vue实例对象---vm
new Vue({render: h => h(App),  
}).$mount('#app')

组件使用

<template><div><h1 >学校:{{ name | mySlice }}</h1><h1>学校地址:{{ address }}</h1><input type="text" v-fbind:value="address">{{ y }}<button @click="hello">点我测试一下hello方法</button></div>
</template><script>export default {name: 'School',data(){return{name:'清华宝盛道吉',address:'北京'}},
}
</script>

webStorage

1.存储内容大小一般支持5MB左右(不同浏览器可能还不一样)
2.浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制
3.相关API:
1.xxxxStorage.setItem(‘key’,‘value’);
该方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值。
2.xxxxStorage.getItem(‘key’);
该方法接收一个键名作为参数,返回键名对应的值。
3.xxxxStorage.removeItem(‘key’);
该方法接收一个键名作为参数,并把该键名从存储中删除
4.xxxxStorage.clear();
该方法会清空存储中的所有数据
4.备注:
1.SessionStorage存储的内容会随时浏览器窗口关闭而消失
2.LocalStorage存储的内容,需要手动清除才消失
3.xxxxStorage.getItem(xxx) 如果xxx对应的value获取不到,那么getItem的返回值是null
4.JSON.parse(null)的结果依然是null

组件自定义事件

1.一种组件通信的方式,适用于:子组件===》父组件
2.适用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
3.注意:通过this.$refs.xxx.$on('hahah',回调)绑定自定义事件,回到要么配置在methods中,要么用箭头函数,否则this指向会出问题
绑定自定义事件
解绑自定义事件
子组件1

<template><div><h3 >学校:{{ name  }}</h3><h3>学校地址:{{ address }}</h3><!-- 两种写法都可以 --><button @click="sendSchoolName">把学校名给APP1</button><button @click="getSchoolName(name)">把学校名给APP2</button></div>
</template><script>
export default {name: 'School',  data(){return{name:'清华',address:'北京'}},//声明接收props:['getSchoolName'],methods:{sendSchoolName(){this.getSchoolName(this.name)}}}
</script>

子组件2

<template><div><h3 >学生姓名:{{ name }}</h3><h3>学生性别:{{ sex }}</h3><h4>当前求和为:{{number}}</h4><button @click="add">点我number++</button><button @click="sendStudentName">把学生名给APP</button><button @click="unbind">解绑haha事件</button><button @click="death">销毁当前Student组件的实例(vc)</button></div></template><script>export default {name: 'Student',//如果和混合的数据发生冲突的时候 以自身的为主data(){return{name:'张三',sex:'男',number:0}},methods:{sendStudentName(){//触发Student组件实例身上的haha事件    $emit是一个函数this.$emit('haha',this.name,666,888,900)//this.$emit('hehe')},unbind(){//解绑this.$off('haha')  //解绑一个自定义事件//this.$off(['haha','hehe'])  //解绑多个自定义事件 接收的是一个数组//this.$off()   //解绑所有的自定义事件},death(){this.$destroy()  //销毁了当前Student组件的实例(vc)  销毁后所有Student实例的自定义事件全都不凑效},add(){this.number++}}}</script>

父组件

<template><div><h1>学生的姓名:{{ studentName }}</h1><!-- 通过父组件给子组件传递函数类型的props实现,子给父传递数据 --><School :getSchoolName="getSchoolName" /><!-- 自定义事件 二种方式 --><!-- 通过父组件给子组件绑定一个自定义事件实现,子给父传递数据(第一种写法,使用@或v-on) --><!-- <Student  @haha="demo"  @hehe="m1" /> --><!--.once 只触发一次  --><!-- <Student  @haha.once="demo" /> --><!-- 通过父组件给子组件绑定一个自定义事件实现,子给父传递数据(第二种写法,使用ref) --><!-- 想要添加原生的dom 点击事件 需要加修饰符@click.native   不然组件会认为是自定义事件--><Student ref="student" @click.native="show" />  </div>
</template><script>
//引入组件
import School from './components/School.vue'
import Student from './components/Student.vue'
export default {name: 'App', //组件名components: {  //注册组件School,Student},data(){return{studentName:''}},methods:{getSchoolName(name){console.log('App收到了学校名',name)},// demo(name,x,y,z){//   console.log('App收到了学生名',name,x,y,z)// },//两种方式接收参数demo(name,...a){console.log('App收到了学生名',name,...a)this.studentName=name},m1(){console.log('hehe事件被触发了')},show(){alert('ddd')}},mounted(){//注意:通过this.$refs.xxx.$on('hahah',回调)绑定自定义事件,回到要么配置在methods中,要么用箭头函数,否则this指向会出问题// this.$refs.student.$on('haha',this.demo)  //绑定自定义事件this.$refs.student.$on('haha',function(name,...a){console.log('App收到了学生名',name,...a)//这里的this 是Student组件的实例对象console.log(this)this.studentName=name  //普通函数 这里的this.studentName赋值不生效 因为这里的this是Student组件的实例对象  写成箭头函数就可以})  //绑定自定义事件//只触发一次 后面就不触发了// this.$refs.student.$once('haha',this.demo)  //绑定自定义事件(一次性)}
}
</script>

全局事件总线(GlobalEventBus)(推荐)

1,一种组件间通信的方式,适用于任意组件间通信
2.安装全局事件总线 main.js

//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//关闭vue的生产提示
Vue.config.productionTip = false//创建vue实例对象---vmnew Vue({render: h => h(App),beforeCreate(){//全局事件总线//把x当作一个傀儡 一般x叫 $bus x是便于理解Vue.prototype.x=this  //安装全局事件总线//Vue.prototype.$bus=this  //安装全局事件总线}  
}).$mount('#app')

3.使用事件总线
4.最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件
组件1

<template><div><h3 >学校:{{ name  }}</h3><h3>学校地址:{{ address }}</h3></div>
</template><script>
export default {name: 'School',  data(){return{name:'清华',address:'北京'}},mounted(){//绑定事件this.x.$on('hello',(data)=>{console.log('我是School组件,收到了数据',data)})},beforeDestroy(){//解绑this.x.$off('hello')}}
</script>

组件2

<template><div><h3 >学生姓名:{{ name }}</h3><h3>学生性别:{{ sex }}</h3><button @click="sendStudentName">把学生名给school组件</button></div></template><script>export default {name: 'Student',//如果和混合的数据发生冲突的时候 以自身的为主data(){return{name:'张三',sex:'男',}},methods:{sendStudentName(){//触发事件this.x.$emit('hello',this.name)}}}</script>

消息订阅与发布 pubsub-js

1.一种组件间通信的方式,适用于任意组件通信
安装 npm i pubsub-js
引入 import pubsub from ‘pubsub-js’;
组件1

<template><div><h3 >学校:{{ name  }}</h3><h3>学校地址:{{ address }}</h3></div>
</template><script>
import pubsub from 'pubsub-js';
export default {name: 'School',  data(){return{name:'清华',address:'北京'}},mounted(){//订阅消息   (绑定)             函数有2个参数  第一个是消息名,第二个才是参数this.pubId= pubsub.subscribe('hello',(a,b)=>{console.log(this)console.log('有人发布了hello消息,hello消息的回调执行了',a,b)})},beforeDestroy(){//解绑 取消订阅  需要id才能取消 和定时器一样pubsub.unsubscribe(this.pubId)}}
</script>

组件2

<template><div><h3 >学生姓名:{{ name }}</h3><h3>学生性别:{{ sex }}</h3><button @click="sendStudentName">把学生名给school组件</button></div></template><script>import pubsub from 'pubsub-js';export default {name: 'Student',//如果和混合的数据发生冲突的时候 以自身的为主data(){return{name:'张三',sex:'男',}},methods:{sendStudentName(){//发布消息 (触发)pubsub.publish('hello',this.name)}}}</script>

nextTick

1.语法:this.$nextTick(回调函数)
2.作用:在下一次DOM更新结束后执行其指定的回调
3.什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行

this.$nextTick(function(){console.log(111)})

动画transition

<template><div><button @click="isShow=!isShow">显示/隐藏</button><!-- 自己写的动画 --><!-- <h3 style="background-color: rebeccapurple;" v-show="isShow" class="come">你好</h3> --><!-- vue的动画组件 如果起name 了 就不能使用v了 就是hello开头  appear第一次就生效动画 --><transition name="hello"  appear><h3 style="background-color: rebeccapurple;" v-show="isShow" >你好</h3></transition></div>
</template><script>
export default {name: 'School',  data(){return{isShow:true}},
}
</script>
<style scoped>
/* vue的动画名称有规范 不能随便命名 进入的时候v-enter-active 如果起name 了 就不能使用v了 */
.hello-enter-active{animation: haha 0.5s linear;
}
/* vue的动画名称有规范 不能随便命名 离开的时候v-leave-active 如果起name 了 就不能使用v了 */
.hello-leave-active{animation: haha 0.5s linear reverse;
}/* vue的动画名称有规范 不能随便命名 进入的时候v-enter-active */
.v-enter-active{animation: haha 0.5s linear;
}
/* vue的动画名称有规范 不能随便命名 离开的时候v-leave-active */
.v-leave-active{animation: haha 0.5s linear reverse;
}
.come{animation: haha 1s;
}
/* reverse反转动画 */
.go{animation: haha 1s reverse;
}
/* 动画写一个就可以了  可以反转动画 */
@keyframes haha {from{transform: translateX(-100%);}to{transform: translateX(0px);}
}
</style>

过渡

<template><div><button @click="isShow=!isShow">显示/隐藏</button><!-- 自己写的动画 --><!-- <h3 style="background-color: rebeccapurple;" v-show="isShow" class="come">你好</h3> --><!-- vue的动画组件 如果起name 了 就不能使用v了 就是hello开头  appear第一次就生效动画 --><transition name="hello"  appear><h3 v-show="isShow" >你好</h3></transition></div>
</template><script>
export default {name: 'School',  data(){return{isShow:true}},
}
</script>
<style scoped>
h3{background-color: rebeccapurple;/* transition: 0.5s linear; */
}
/* 进入的起点,离开的终点 */
.hello-enter,.hello-leave-to{transform: translateX(-100%);
}
/* 进入的终点,离开的起点 */
.hello-enter-to,.hello-leave{transform: translateX(0);
}
/* 进入时候激活的样式,离开时候激活的样式 */
.hello-enter-active,.hello-leave-active{transition: 0.5s linear;
}
</style>

多个元素过渡 transition-group

<template><div><button @click="isShow=!isShow">显示/隐藏</button><!-- 自己写的动画 --><!-- <h3 style="background-color: rebeccapurple;" v-show="isShow" class="come">你好</h3> --><!-- vue的动画组件 如果起name 了 就不能使用v了 就是hello开头  appear第一次就生效动画 --><!-- transition-group 需要key值 --><transition-group name="hello"  appear><h3 v-show="!isShow" key="1">你好</h3><h3 v-show="isShow" key="2">肯德基</h3></transition-group></div>
</template><script>
export default {name: 'School',  data(){return{isShow:true}},
}
</script>
<style scoped>
h3{background-color: rebeccapurple;/* transition: 0.5s linear; */
}
/* 进入的起点,离开的终点 */
.hello-enter,.hello-leave-to{transform: translateX(-100%);
}
/* 进入的终点,离开的起点 */
.hello-enter-to,.hello-leave{transform: translateX(0);
}
/* 进入时候激活的样式,离开时候激活的样式 */
.hello-enter-active,.hello-leave-active{transition: 0.5s linear;
}
</style>

第三方动画库

https://animate.style/
安装:npm inatall animate.css
引入 : import ‘animate.css’

<template><div><button @click="isShow=!isShow">显示/隐藏</button><!-- enter-active-class 进入的动画   leave-active-class 离开的动画 --><transition-group name="animate__animated animate__bounce"appear enter-active-class="animate__swing"leave-active-class="animate__backOutUp"><h3 v-show="!isShow" key="1">家乐福</h3><h3 v-show="isShow" key="2">了来得及</h3></transition-group></div></template><script>import 'animate.css'export default {name: 'Test',  data(){return{isShow:true}},}</script><style scoped>
h3{background-color: rebeccapurple;/* transition: 0.5s linear; */
}
</style>

配置代理vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true,//lintOnSave:false,  //关闭eslint校验 官方并不建议直接关闭校验devServer:{ //开启代理服务器host:'localhost',port:8080,https:false,open:true,//是否自动启动到浏览器当中proxy:{//代理'/api':{ //匹配所有以 '/api'开头的请求路径target:'http://127.0.0.1:7001', //代理目标的基础路径changeOrigin:true,//用于控制请求头中的host值  不写默认也是truepathRewrite:{ //重写路径'^/api':''}},'/foo': {target: 'http://127.0.0.1:9000',ws: true, //用于支持websocket 不写默认也是truechangeOrigin: true,//用于控制请求头中的host值  不写默认也是truepathRewrite:{'^/foo':''}},}
}})

slot插槽

1.作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件—》子组件
默认插槽
子组件

<template><div><h3>{{ title }}分类</h3><!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) --><slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot></div>
</template><script>
export default {name: 'School',  props:['title']
}
</script>

父组件

<template><div><School title="活动价" ></School><School title="极乐空间"><ol><li>捡垃圾</li></ol></School></div>
</template><script>
//引入组件
import School from './components/School.vue'
export default {name: 'App', //组件名components: {  //注册组件School},  
}
</script>

具名插槽
子组件

<template><div><h6>{{ title }}分类</h6><!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) --><slot name="demo">我是一些默认值,当使用者没有传递具体结构时,我会出现</slot><slot name="test">我是一些默认值,当使用者没有传递具体结构时,我会出现</slot></div>
</template><script>
export default {name: 'School',  props:['title']
}
</script>

父组件

<template><div><School title="活动价" ><template v-slot:demo><h3 slot="demo">熊警察局</h3></template><!-- 简写 需要template包裹 v-slot:test 或者#test --><template #test><h3 >放假夸大事实</h3></template></School><School title="极乐空间"><!-- slot="test" 要和插槽name名称对应 --><ol slot="test"><li>捡垃圾</li></ol><h5 slot="demo">金科股份</h5><!-- 可以追加 --><!-- <h5 slot="demo">金科股份</h5> --></School></div>
</template><script>
//引入组件
import School from './components/School.vue'
export default {name: 'App', //组件名components: {  //注册组件School},  
}
</script>

作用域插槽
1.理解:数据在组件的自身,但根据数据生成的结果需要组件的使用者来决定,(list数据在school组件中,
但使用数据所遍历出来的结构由APP组件决定)
子组件

<template><div><h6>{{ title }}分类</h6><!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) --><slot :youxis="list" msg="hello">我是一些默认值,当使用者没有传递具体结构时,我会出现</slot></div>
</template><script>
export default {name: 'School',  props:['title'],data(){return {list:['进度款','就看看','九二五']}}
}
</script>

父组件

<template><div><School title="活动价" ><template slot-scope="haha">{{ haha }}<ul><li v-for="(item,index) in haha.youxis" :key="index">{{ item }}</li></ul></template></School><School title="活动价" ><!-- 支持解构赋值 --><template slot-scope="{youxis}"><!-- {{ haha }} --><ol><li v-for="(item,index) in youxis" :key="index">{{ item }}</li></ol></template></School></div>
</template><script>
//引入组件
import School from './components/School.vue'
export default {name: 'App', //组件名components: {  //注册组件School},  }
</script>

vuex

要严格遵循版本
在2022年2月7日,vue3成为了默认版本,npm i vue,安装的直接就是vue3了,vue3成为默认版本的同时
,vuex也更新到了4版本,npm i vuex ,安装的是vuex4,vuex的4版本,只能在vue3中使用
vue2中,要用vuex的3版本 npm i vuex@3
vue3中,要用vuex的4版本
安装
npm i vuex@3
//在脚手架里面 不管import之间写了多少代码 它会优先扫描整个文件的import语句
//按照import编写顺序 全都汇总到最上方 按照顺序执行

引入main.js

//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
//在脚手架里面 不管import之间写了多少代码 它会优先扫描整个文件的import语句
//按照import编写顺序 全都汇总到最上方 按照顺序执行
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//引入store
import store from './store'//关闭vue的生产提示
Vue.config.productionTip = false
//创建vue实例对象---vm
new Vue({render: h => h(App),store,
}).$mount('#app')

在这里插入图片描述
store/index.js

//该文件用于创建vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)//准备actions 用于响应组件中的动作 处理业务逻辑
const actions={}
//准备mutations 用于操作数据(state) 修改数据
const mutations={}
//准备state 用于存储数据
const state={}//创建并暴露store
export default new Vuex.Store({actions,mutations,state
})

组件触发方法
组件中修改vuex中的数据:$store.dispatch('action中的方法名',数据)或$store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过action,即不写dispatch,直接编写commit

<template><div><!-- 模板里面不需要加this -->{{ $store.state.sum }} <hr><!-- {{ haha }}  -->{{ sum }}<!-- <button @click="jiajia">++</button> --><button @click="jiajia(n)">++</button><button @click="jiajia1(n)">++1</button><!-- <button @click="jia(n)">++1</button> --><!-- <button @click="JIA(n)">++</button> --><h3>{{$store.getters.bigSum}} 放大了10</h3><!-- <h3>{{big}} 放大了10</h3> --><h3>{{bigSum}} 放大了10</h3></div>
</template><script>
//引入映射属性 模版里面就可以简写了 省略掉$store.state.    mapState只能生成带有state里面的代码
import { mapState,mapGetters,mapMutations,mapActions } from 'vuex';
export default {name: 'App', //组件名data(){return {n:10}},computed:{//借助mapState生成计算属性,从state中读取数据 (对象写法)//  ...mapState({//      haha:'sum'//  }),//借助mapState生成计算属性,从state中读取数据 (数组写法)...mapState(['sum']),//借助mapGetters生成计算属性,从getters中读取数据 (对象写法)//  ...mapGetters({big:'bigSum'}),//借助mapGetters生成计算属性,从getters中读取数据 (数组写法)...mapGetters(['bigSum']),},methods:{//程序员亲自写方法// jiajia(){//   //dispatch和actions 对话//  // this.$store.dispatch('jia',this.n)//   //也可以直接commit 和mutations对话//   this.$store.commit('JIA',this.n)// },//简写上面的方法 this.$store.commit 模板点击事件需要传参  //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations  (感觉有点鸡肋)(对象写法)...mapMutations({jiajia:'JIA'}),//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations  (感觉有点鸡肋)(数组写法)// ...mapMutations(['JIA']),//简写上面的方法 this.$store.dispatch 模板点击事件需要传参  //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions  (感觉有点鸡肋)(对象写法)...mapActions({jiajia1:'jia'}),//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions  (感觉有点鸡肋)(数组写法)//   ...mapActions(['jia'])}
}
</script>

store/index.js转换数据
当state中的数据需要经过加工后再使用时,可以使用getters加工

//该文件用于创建vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)//准备actions 用于响应组件中的动作 处理业务逻辑 函数
const actions={//两个参数  第一个参数是 迷你版的store 是 context  里面最想用的commit 如果这里用state直接修改数据 开发者工具就失效了  可以解构 第二个参数是值jia({commit},value){console.log('actions中的jia被调用了',commit,value)commit('JIA',value)}
}
//准备mutations 用于操作数据(state) 修改数据 函数
const mutations={//两个参数  第一个参数是 state   第二个参数是值  开发规范方法名基本是大写JIA(state,value){console.log('mutations中的JIA被调用了',state,value)state.sum +=value}
}
//准备state 用于存储数据  像极了data
const state={sum:0 //当前的和
}
//准备getters 用于将state中的数据进行加工  函数  像极了computed
const getters={bigSum(state){return state.sum*10}
}//创建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})

vuex模块化+命名空间

目的:让代码更好维护,让多种数据分类更加明确
需要注意开启空间命名 后getters获取值的方式 以及commit推送的命名规则
store/index.js 可以区分开多个文件,这里都放入了一个文件里面

//该文件用于创建vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//使用Vuex插件
Vue.use(Vuex)//模块化 求和相关的配置
const peiqi={namespaced:true,//命名空间 写了这个之后 a的分类名才能被mapState 认识  默认值是false//准备actions 用于响应组件中的动作 处理业务逻辑actions:{//两个参数  第一个参数是 迷你版的store 是 context  里面最想用的commit 如果这里用state直接修改数据 开发者工具就失效了  可以解构 第二个参数是值jia({commit},value){console.log('actions中的jia被调用了',commit,value)commit('JIA',value)}},//准备mutations 用于操作数据(state)  修改数据mutations:{//两个参数  第一个参数是 state   第二个参数是值  开发规范方法名基本是大写JIA(state,value){console.log('mutations中的JIA被调用了',state,value)state.sum +=value}},//准备state 用于存储数据state:{sum:0 //当前的和},getters:{bigSum(state){return state.sum*10}}
}//模块化 人员相关的配置
const qiaozhi={namespaced:true,//命名空间 写了这个之后 b的分类名才能被mapState 认识  默认值是false//准备actions 用于响应组件中的动作 处理业务逻辑actions:{},//准备mutations 用于操作数据(state)  修改数据mutations:{},//准备state 用于存储数据state:{peronslist:[{id:1,name:'李四',age:19},{id:2,name:'张三',age:29},]},getters:{}
}
//创建并暴露store
export default new Vuex.Store({modules:{a:peiqi,b:qiaozhi}
})

组件使用

<template><div><!-- 模板里面不需要加this -->{{ $store.state.a.sum }} <hr><!-- 获取getters里面的属性值 -->{{ $store.getters['a/bigSum'] }} <hr>{{ sum }}{{  bigSum}}<button @click="jiajia1">++</button><button @click="jiajia(n)">++n</button>{{ peronslist }}</div>
</template><script>
import { mapState,mapMutations,mapGetters } from 'vuex';
export default {name: 'App', //组件名data(){return {n:10}},computed:{//state里面有什么 我们才拿什么 简写...mapState('a',['sum']),...mapState('b',['peronslist']),...mapGetters('a',['bigSum'])},methods:{//程序员亲自写方法jiajia1(){console.log(this.$store)//  a/JIA  a模块里面的方法  前面是分类名// this.$store.commit('a/JIA',this.n)this.$store.dispatch('a/jia',this.n)},...mapMutations('a',{jiajia:'JIA'})}
}
</script>

路由

2022年2月7日以后,vue-router的默认版本,为4版本,而且vue-router4,只能在vue3中去使用,
vue-router3才能用在vue2中去使用。
安装: npm i vue-router@3

全局路由守卫

router/index.js

//该文件专门用于创建整个应用的路由器
//引入vue-router
import VueRouter from 'vue-router'
//引入组件
import About from "../pages/About.vue";
import Home from "../pages/Home.vue";
import News from "../pages/News.vue";
import Detail from "../pages/Detail.vue";
import Message from "../pages/Message.vue";
//创建一个路由器
const router= new VueRouter({routes:[{name:'guanyu', //跳转的时候可以简化路由的跳转path:'/about',component:About,meta:{title:'关于'}},{name:'zhuye',path:'/home',component:Home,meta:{title:'主页'},children:[{name:'xinwen',path:'news',//子路由不要加斜杆 加了就是画蛇添足了component:News,meta:{peiqi:true,title:'新闻'}},{name:'xiaoxi',path:'message',//子路由不要加斜杆 加了就是画蛇添足了component:Message,meta:{peiqi:true,title:'消息'},children:[{name:'xiangqing',// path:'detail',//子路由不要加斜杆 加了就是画蛇添足了 query参数path:'detail/:id/:title',// 占位符   detail/:id/:title  params参数需要这样配置meta:{peiqi:true,title:'详情'},component:Detail,//props的第一种写法,值为对象(传递的是死数据),该对象中的所有key-value都会以props的形式传给Detail组件// props:{ a:1,b:'hello' },//props的第二种写法,值为布尔值,若布尔值为true,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件//局限性 不接收query参数//props:true,//props的第三种写法,值函数  query和params参数都可以 也可以解构赋值// props($route){//     return {id:$route.params.id,title:$route.params.title}// }props({params:{id,title}}){return {id,title}}}]}]},]
})
//全局前置路由守卫---初始化的时候被调用,每次路由切换之前被调用
//to 要去那  from来自那  next放行
router.beforeEach((to,from,next)=>{console.log('前置路由守卫',to,from)//添加需要的限制条件 比如权限  to.name也行 都可以//这样判断有点麻烦  如果是很多个就要写很多次 || ,可以自定义一个路由属性 只能往meta里面放 比如meta:{peiqi:true}, meta里面是可以让程序员自定义的属性//if(to.path==='/home/news' || to.path ==='/home/message')  改写 if(to.meta.peiqi)if(to.meta.peiqi){ //判断是否需要鉴权if(localStorage.getItem('school')==='haha'){next() //放行}else{alert('学校名不对,无权限查看!')}}else{next() //放行}})
//全局后置路由守卫---初始化的时候被调用,每次路由切换之后被调用 没有next
router.afterEach((to,from)=>{console.log('后置路由守卫',to,from)document.title=to.meta.title || '哈哈系统'
})export default router

main.js引入

//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
//在脚手架里面 不管import之间写了多少代码 它会优先扫描整个文件的import语句
//按照import编写顺序 全都汇总到最上方 按照顺序执行
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//引入vue-router
import VueRouter from 'vue-router'
//引入store
import store from './store'
import router from './router'//应用插件
Vue.use(VueRouter)
//关闭vue的生产提示
Vue.config.productionTip = false
//创建vue实例对象---vm
new Vue({render: h => h(App),store,router
}).$mount('#app')

APP.vue页面使用
replace
1.作用:控制路由跳转时操作浏览器历史记录的模式
2.浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录
,路由跳转时候默认为push
3.如何开启replace模式:router-link 加上这个replace属性就行

<template><div><!-- vue中借助router-link标签实现路由的切换  replace不开启历史记录 --><router-link replace to="/about" active-class="act">about</router-link><!-- active-class路由激活样式 路由自带的 --><router-link replace to="/home" active-class="act">home</router-link><hr><div><!-- 指定组件的呈现位置 --><router-view></router-view></div></div>
</template><script>export default {name: 'App', //组件名data(){return {}},}
</script>
<style>
.act{color: red;
}
</style>

嵌套(多级)路由

路由配置规则,使用children配置项
跳转(要写完整路径)

缓存路由组件 keep-alive

作用:让不展示的路由组件保持挂载,不被销毁

home页面

<template><div>home<hr><!-- vue中借助router-link标签实现路由的切换 --><router-link to="/home/news" active-class="act">news</router-link><!-- active-class路由激活样式 路由自带的 --><router-link to="/home/message" active-class="act">message</router-link><div><!-- 缓存路由组件  不写缓存下面所有的路由组件 include是指定包含某个 组件名称 缓存--><!-- 缓存多个 用数组 --><keep-alive :include="['News1','Message']"><!-- 指定组件的呈现位置 --><router-view></router-view></keep-alive><!-- 缓存一个 --><!-- <keep-alive include="News1"><router-view></router-view></keep-alive> --></div></div>
</template><script>export default {name: 'Home', //组件名beforeDestroy(){console.log('Home组件即将被销毁了')},mounted(){console.log('Home组件挂载完毕了')}}
</script>

路由传参 query参数

params参数

:配置路由,声明接收params参数

路由的props配置 简化接收的参数

作用:让路由组件更方便的收到参数

编程式路由导航

作用:不借助router-link实现路由跳转,让路由跳转更加灵活

主页面

<template><div>message<hr><ol><li v-for="m in messageList" :key="m.id"><!-- 跳转路由并携带query参数,to的字符串写法   --><!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`" active-class="act">{{m.title}}</router-link> --><!-- 跳转路由并携带query参数,to的对象写法   --><!-- <router-link :to="{path:'/home/message/detail',query:{id:m.id,title:m.title}}" active-class="act">{{m.title}}</router-link> --><!-- <router-link :to="{name:'xiangqing',query:{id:m.id,title:m.title}}" active-class="act">{{m.title}}</router-link> --><!-- 跳转路由并携带params参数,to的字符串写法 路由需要配置  --><!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`" active-class="act">{{m.title}}</router-link> --><!-- 跳转路由并携带params参数,to的对象写法 注意:如果携带的是params参数 必须使用name 不能使用path  --><router-link :to="{name:'xiangqing',params:{id:m.id,title:m.title}}" active-class="act">{{m.title}}</router-link></li></ol><button @click="pushShow">push查看</button><button @click="replaceShow">replace查看</button><div><!-- 指定组件的呈现位置 --><router-view></router-view></div></div>
</template><script>export default {name: 'Message', //组件名data(){return{messageList:[{id:'001',title:'消息001'},{id:'002',title:'消息002'},{id:'003',title:'消息003'},]}},methods:{pushShow(){console.log(this.$router)this.$router.push({name:'xiangqing',params:{id:'0011',title:'线进出口'}})//后退// this.$router.back()// //前进// this.$router.forward()//往前或往后走几步 正数是前进  负数是后退 可前进也可以后退//this.$router.go(1)},replaceShow(){this.$router.replace({name:'xiangqing',params:{id:'0014',title:'健科出口'}})}}}
</script>

子页面

<template><div><ul><!-- 接收query参数 --><!-- <li>消息编号:{{ $route.query.id }}</li><li>消息标题:{{ $route.query.title }}</li> --><!-- 接收params参数 --><li>消息编号:{{ $route.params.id }}</li><li>消息标题:{{ $route.params.title }}</li></ul><!--路由props配置的参数 简化了上面的写法接收数据 --><!-- 第一种写法 死数据 --><!-- <div>{{ a }}  /{{ b }}</div> --><!-- 第二种写法 就是params传递的属性 --><div>{{ id }}  /{{ title }}</div></div>
</template><script>export default {name:'Detail',//props:['a','b'],//第一种写法 死数据props:['id','title'],//第二种写法 就是params传递的属性mounted(){console.log(this.$route)}}
</script>

两个新的生命周期钩子

activated 路由组件被激活时触发
deactivated 路由组件失活时触发
作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
组件缓存的时候 这两个钩子很有用

<template><div><h4 :style="{opacity}">学生</h4><div>复测:  <input type="text"></div></div>
</template><script>export default {name: 'News1', //组件名data(){return{opacity:1}},// beforeDestroy(){//     console.log('News组件即将被销毁了')//     clearInterval(this.timer)// },// mounted(){//     this.timer=setInterval(() => {//         console.log('@')//         this.opacity -=0.01//         if(this.opacity <=0) this.opacity =1//     }, 16);// },//激活activated(){console.log('News组件被激活了')this.timer=setInterval(() => {console.log('@')this.opacity -=0.01if(this.opacity <=0) this.opacity =1}, 16);},//取消激活deactivated(){console.log('News组件失活了')clearInterval(this.timer)}}
</script>

独享路由守卫

router/index.js

//该文件专门用于创建整个应用的路由器
//引入vue-router
import VueRouter from 'vue-router'
//引入组件
import About from "../pages/About.vue";
import Home from "../pages/Home.vue";
import News from "../pages/News.vue";
import Detail from "../pages/Detail.vue";
import Message from "../pages/Message.vue";
//创建一个路由器
const router= new VueRouter({mode:'history',//不带#号  hash模式带#号  默认是hash模式routes:[{name:'guanyu', //跳转的时候可以简化路由的跳转path:'/about',component:About,meta:{title:'关于'}},{name:'zhuye',path:'/home',component:Home,meta:{title:'主页'},children:[{name:'xinwen',path:'news',//子路由不要加斜杆 加了就是画蛇添足了component:News,meta:{peiqi:true,title:'新闻'},//独享路由守卫 只有前置 没有后置  进入之前beforeEnter:(to,from,next)=>{console.log('独享路由守卫',to,from)if(to.meta.peiqi){ //判断是否需要鉴权if(localStorage.getItem('school')==='haha'){next() //放行}else{alert('学校名不对,无权限查看!')}}else{next() //放行}}},{name:'xiaoxi',path:'message',//子路由不要加斜杆 加了就是画蛇添足了component:Message,meta:{peiqi:true,title:'消息'},children:[{name:'xiangqing',// path:'detail',//子路由不要加斜杆 加了就是画蛇添足了 query参数path:'detail/:id/:title',// 占位符   detail/:id/:title  params参数需要这样配置meta:{peiqi:true,title:'详情'},component:Detail,//props的第一种写法,值为对象(传递的是死数据),该对象中的所有key-value都会以props的形式传给Detail组件// props:{ a:1,b:'hello' },//props的第二种写法,值为布尔值,若布尔值为true,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件//局限性 不接收query参数//props:true,//props的第三种写法,值函数  query和params参数都可以 也可以解构赋值// props($route){//     return {id:$route.params.id,title:$route.params.title}// }props({params:{id,title}}){return {id,title}}}]}]},]
})
//全局前置路由守卫---初始化的时候被调用,每次路由切换之前被调用
//to 要去那  from来自那  next放行
// router.beforeEach((to,from,next)=>{
//     console.log('前置路由守卫',to,from)//     //添加需要的限制条件 比如权限  to.name也行 都可以
//     //这样判断有点麻烦  如果是很多个就要写很多次 || ,可以自定义一个路由属性 只能往meta里面放 比如meta:{peiqi:true}, meta里面是可以让程序员自定义的属性
//     //if(to.path==='/home/news' || to.path ==='/home/message')  改写 if(to.meta.peiqi)
//    if(to.meta.peiqi){ //判断是否需要鉴权
//         if(localStorage.getItem('school')==='haha'){
//             next() //放行
//         }else{
//             alert('学校名不对,无权限查看!')
//         }
//    }else{
//         next() //放行
//    }// })
//全局后置路由守卫---初始化的时候被调用,每次路由切换之后被调用 没有next
router.afterEach((to,from)=>{console.log('后置路由守卫',to,from)document.title=to.meta.title || '哈哈系统'
})export default router

组件内路由守卫

<template><div>about</div>
</template><script>export default {name: 'About', //组件名beforeDestroy(){console.log('About组件即将被销毁了')},mounted(){console.log('About组件挂载完毕了')},//当路由进入之前  通过路由规则,进入该组件时被调用beforeRouteEnter(to,from,next){console.log('当路由进入之前',to,from,next)if(to.meta.peiqi){ //判断是否需要鉴权if(localStorage.getItem('school')==='haha'){next() //放行}else{alert('学校名不对,无权限查看!')}}else{next() //放行}},//当路由离开之前 通过路由规则,离开该组件时被调用beforeRouteLeave(to,from,next){console.log('当路由离开之前',to,from,next)next() //放行}}
</script>

安装PC端 组件库element-ui

https://element.eleme.io/#/zh-CN/component/installation
安装 npm i element-ui

按需引入 需要安装这个
npm install babel-plugin-component -D

修改babel.config.js文件内容 注意**@babel/preset-env**这个和官方的有区别

module.exports = {presets: ['@vue/cli-plugin-babel/preset',["@babel/preset-env", { "modules": false }]],plugins: [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}

main.js

//引入vue  引入的其实是运动版的vue   vue.runtime.esm.js
//在脚手架里面 不管import之间写了多少代码 它会优先扫描整个文件的import语句
//按照import编写顺序 全都汇总到最上方 按照顺序执行
import Vue from 'vue'
//引入APP组件  它是所有组件的父组件
import App from './App.vue'
//引入vue-router
import VueRouter from 'vue-router'
//引入store
import store from './store'
import router from './router'//按需引入
import { Button } from 'element-ui';
Vue.component(Button.name, Button);//完整引入
//引入ElementUI组件库
// import ElementUI from 'element-ui';
// //引入ElementUI全部样式
// import 'element-ui/lib/theme-chalk/index.css';
// //应用ElementUI
// Vue.use(ElementUI);//应用插件
Vue.use(VueRouter)
//关闭vue的生产提示
Vue.config.productionTip = false
//创建vue实例对象---vm
new Vue({render: h => h(App),store,router
}).$mount('#app')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767543.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 STL 容器发生异常的常见原因分析与总结

目录 1、概述 2、使用STL列表中的元素越界 3、遍历STL列表删除元素时对迭代器自加处理有问题引发越界 4、更隐蔽的遍历STL列表删除元素时引发越界的场景 5、多线程同时操作STL列表时没有加锁导致冲突 6、对包含STL列表对象的结构体进行memset操作导致STL列表对象内存出异…

python之(19)CPU性能分析常见工具

Python之(19)CPU性能分析常见工具 Author: Once Day Date: 2024年3月24日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏:Python开发_Once-Day的博客…

深度学习 tablent表格识别实践记录

下载代码&#xff1a;https://github.com/asagar60/TableNet-pytorch 下载模型&#xff1a;https://drive.usercontent.google.com/download?id13eDDMHbxHaeBbkIsQ7RSgyaf6DSx9io1&exportdownload&confirmt&uuid1bf2e85f-5a4f-4ce8-976c-395d865a3c37 原理&#…

查看文件内容的指令:cat,tac,nl,more,less,head,tail,写入文件:echo

目录 cat 介绍 输入重定向 选项 -b -n -s tac 介绍 输入重定向 nl 介绍 示例 more 介绍 选项 less 介绍 搜索文本 选项 head 介绍 示例 选项 -n tail 介绍 示例 选项 echo 介绍 输出重定向 追加重定向 cat 介绍 将标准输入(键盘输入)的内容打…

pta L1-077 大笨钟的心情

L1-077 大笨钟的心情 分数 15 退出全屏 作者 陈越 单位 浙江大学 有网友问&#xff1a;未来还会有更多大笨钟题吗&#xff1f;笨钟回复说&#xff1a;看心情…… 本题就请你替大笨钟写一个程序&#xff0c;根据心情自动输出回答。 输入格式&#xff1a; 输入在一行中给出…

【ZYNQ】基于ZYNQ 7020的OPENCV源码交叉编译

目录 安装准备 检查编译器 安装OpenCV编译的依赖项 下载OpenCV源码 下载CMake 编译配置 编译器说明 参考链接 安装准备 使用的各个程序的版本内容如下&#xff1a; 类别 软件名称 软件版本 虚拟机 VMware VMware-workstation-full-15.5.0-14665864 操作系统 Ub…

线性表的合并之求解一般集合的并集问题(单链表)

目录 1问题描述&#xff1a; 2问题分析&#xff1a; 3代码如下&#xff1a; 4运行结果&#xff1a; 1问题描述&#xff1a; 已知两个集合A和B&#xff0c;现要求一个新的集合AAuB。例如&#xff0c;设 A&#xff08;7&#xff0c;5&#xff0c;3&#xff0c;11&#xff09;…

基于Matlab的血管图像增强算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

设计数据库之外部模式:数据库的应用

Chapter5&#xff1a;设计数据库之外部模式&#xff1a;数据库的应用 笔记来源&#xff1a;《漫画数据库》—科学出版社 设计数据库的步骤&#xff1a; 概念模式 概念模式(conceptual schema)是指将现实世界模型化的阶段进而&#xff0c;是确定数据库理论结构的阶段。 概念模…

k8s笔记27--快速了解 k8s pod和cgroup的关系

k8s笔记27--快速了解 k8s pod和 cgroup 的关系 介绍pod & cgroup注意事项说明 介绍 随着云计算、云原生技术的成熟和广泛应用&#xff0c;K8S已经成为容器编排的事实标准&#xff0c;学习了解容器、K8S技术对于新时代的IT从业者显得极其重要了。 之前在文章 docker笔记13–…

【Web APIs】事件高级

目录 1.事件对象 1.1获取事件对象 1.2事件对象常用属性 2.事件流 1.1事件流的两个阶段&#xff1a;冒泡和捕获 1.2阻止事件流动 1.3阻止默认行为 1.4两种注册事件的区别 3.事件委托 1.事件对象 1.1获取事件对象 事件对象&#xff1a;也是一个对象&#xff0c;这个对象里…

电子电器架构 —— 诊断数据DTC具体故障篇

电子电器架构 —— 诊断数据DTC起始篇 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师 (Wechat:gongkenan2013)。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了,不要在意别人怎么看自己。江湖一碗茶,喝完再挣扎…

算法---前缀和练习-2(和为k的子数组)

和为k的子数组 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 创建一个无序映射&#xff08;哈希表&#xff09; hash&#xff0c;用于统计前缀和的出现次数。初始时&#xff0c;将前缀和为 0 的次数设为 1&#xff0c;表示…

牛客题霸-SQL篇(刷题记录二)

本文基于前段时间学习总结的 MySQL 相关的查询语法&#xff0c;在牛客网找了相应的 MySQL 题目进行练习&#xff0c;以便加强对于 MySQL 查询语法的理解和应用。 由于涉及到的数据库表较多&#xff0c;因此本文不再展示&#xff0c;只提供 MySQL 代码与示例输出。 以下内容是…

HarmonyOS应用开发实战 - Api9 拍照、拍视频、选择图片、选择视频、选择文件工具类

鸿蒙开发过程中&#xff0c;经常会进行系统调用&#xff0c;拍照、拍视频、选择图库图片、选择图库视频、选择文件。今天就给大家分享一个工具类。 1.话不多说&#xff0c;先展示样式 2.设计思路 根据官方提供的指南开发工具类&#xff0c;基础的拍照、拍视频、图库选照片、选…

使用Python进行自动化测试Selenium与PyTest的结合【第150篇—自动化测试】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python进行自动化测试&#xff1a;Selenium与PyTest的结合 在软件开发中&#xff0c;自…

css盒子模型及浮动

内容(content)、内边距(padding)、边框(border)、外边距(margin) oder:1px solid red; 边框的粗细 边框的样式&#xff08;虚线还是实线&#xff09; 边框的颜色 border中也有一些属性可以直接调某一个方向上的边框的粗细&#xff0c;样式&#xff0c;颜色 border-left\bord…

2024/3/24 LED点阵屏

显示原理&#xff1a; 类似矩阵键盘&#xff0c;逐行or逐列扫描 74HC595是串行 寄存器 感觉就是三转八寄存器 并行&#xff1a;同时输出&#xff1b;串行&#xff1a;一位一位输出 先配置74HC595&#xff0c;重新进行位声明 sbit RCKP3^5; //RCLK sbit SCKP3^6; …

淘宝|天猫|京东|1688主流电商平台的实时数据返回接口|附Python实例

导读&#xff1a;随着淘宝/天猫直通车功能升级&#xff0c;很多功能越来越白盒化&#xff0c;越来越简化&#xff0c;更方便用户的操作&#xff0c;只需一键即可看出淘宝/天猫直通车存在的问题。淘宝/天猫直通车千人千面后有了实时数据工具&#xff0c;下面通过一个案例告诉大家…

23. UE5 RPG制作属性面板(一)

随着角色的属性越来越多&#xff0c;我们不能每次都进行showdebug abilitysystem进行查看&#xff0c;而且玩家也需要查看角色属性&#xff0c;所以需要一个查看玩家角色属性的面板。 在前面&#xff0c;我们创建三种类型的属性 Primary Attributes&#xff08;主要属性&#…