前端Vue
基础语法
<div id="div">
<h1>This is a data:{
{data}}</h1>
<h1>This is a method:{
{method()}}</h1>
</div>
<script>
//创建vue实例需要传入配置对象,el指定一个元素作为容器,data保存需要的数据,methods定义函数,不要写成箭头函数
//在html标签体中使用vue中的数据需要{
{}}来引用,{
{}}内可以写vue数据和js表达式
const vue = new Vue({
el:"#div",
//如果在组件内需要写成函数形式
data:{
data:val,
...
},
methods:{
method(){
},
...
},
});
</script>
模板语法
<div id="div">
<!-- v-text:插入文本 -->
<div v-text="text"></div>
<!-- v-html:插入html代码 -->
<div v-html="html"></div>
<!-- v-bind:在html标签属性上使用vue的数据或js表达式 -->
<div :class="bind">This is v-bind</div>
<!-- 样式绑定 -->
<div :class="css">This is css</div>
<div :style="style">This is style</div>
<!-- v-model:实现html和vue双向数据绑定,只能用在表单类元素上 -->
<input type="text" v-model="model">
<!-- v-on:绑定事件 -->
<!-- 事件修饰符:stop阻止冒泡,prevent阻止默认事件,once只触发一次 -->
<input type="button" value="v-on事件" @click="click">
<input type="text" @keyup="keyup">
<!-- v-once:只做一次渲染 -->
<div v-once>This is {
{once}}</div>
<!-- v-show:是否渲染 -->
<div v-show="true">This is {
{show}}</div>
<!-- v-if:判断是否插入元素 -->
<div v-if="v_if">if</div>
<div v-else>else</div>
<!-- v-for:遍历数组或对象,key值最好为数据id-->
<ul>
<li v-for="(item,index) in arr" :key="item.id">
{
{index}}:{
{value}}
</li>
</ul>
<ul>
<li v-for="(value,key,index) in obj" :key="key">
{
{index}}:{
{key}}:{
{value}}
</li>
</ul>
</div>
<script>
const vue=new Vue({
el:"#div",
data:{
text:"<h1>v-text</h1>",
html:"<h1>v-html</h1>",
bind:"v-bind",
css:{
css1:true,css2:false},
style:{
color:"red"},
model:"v-model",
once:"v-once",
show:"v-show",
v_if:true,
arr:["item1","item2"],
obj:{
key1:"val1",key2:"val2"},
},
methods:{
click(){
console.log("click");},
keyup(e){
console.log("keyup:"+e.key);},
},
});
</script>
计算属性
computed:{
//默认只提供get方法
compute1(){
},
//提供get和set方法,可以读取和修改属性值,set需要修改依赖数据
compute2:{
get(){
},
set(value,...){
},
},
}
监听属性
watch:{
//普通监听
watch1(newVal,oldVal){
},
watch2:{
//初始化是否监听
immediate:true,
//watch默认不监听对象内部属性变化,需要手动开启
deep:true,
handler(newVal,oldVal){
}
}
}
过滤器
filters:{
//调用方式{
{xxx | filter}}
filter(value,...){
},
}
自定义指令
directives:{
//指令名调用格式v-xxx-xxx
//默认只有bind和update
directive1(element,bind){
},
//设置不同时机的调用函数
directive2:{
//绑定时触发
bind(element,bind){
},
//元素插入时触发
inserted(element,bind){
},
//重新解析时触发
update(element,bind){
},
}
}
生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1kP7mwKp-1683727373481)(asset/vue.png)]
beforeCreate(){
},
created(){
},//vue实例创建
beforeMount(){
},//虚拟DOM生成
mounted(){
},//实体DOM生成并挂载完数据,一般进行初始化操作
beforeUpdate(){
},//数据更新,DOM未更新
updated(){
},
beforeDestroy(){
},//进行结尾工作
destroyed(){
},
组件
<template>
<!-- 这里写模板,且只有一个根标签 -->
<div>
<!-- ref属性代替id属性,在方法中通过this.$refs.xxx获取DOM对象或者组件实例对象 -->
<div ref="ref">This is {
{template}}</div>
<!-- 父组件通过元素的slot属性将其放入指定插槽,且只能放入一个根元素,
该元素通过slot-scope属性获取绑定在slot上的数据对象,数据名即为属性名,
以此创建不同结构的相同组件 -->
<slot name="slotName" :data="innerData">This is default content</slot>
</div>
</template>
<script>
//这里写组件配置
export default{
name:"Component",//组件名称
//props接收外部传递的参数(父->子通信),有两种方式,且参数只读
//props:['params',...],
props:{
params:{
type: //接收值类型
required: //是否必需
default: //默认值
},
},
//混入,将混入文件中的数据合并到当前组件
mixins:[mixin,...],
//引入自定义组件
components:{
},
data(){
return{
template:"template",
innerData:"This is innerData"
}
},
}
</script>
<style lang="scss" scoped>
/* 这里写局部样式 */
</style>
自定义事件(子->父通信)
//在子组件内部触发事件,并向父组件传递参数
this.$emit("event",params,...);
//在父组件中,绑定子组件触发事件后的回调函数并接收参数,function应在methods中定义或者为箭头函数
this.$on("event",(params,...)=>{
});
//在父组件中,解绑子组件触发事件的回调函数
this.$off("event");
//组件绑定事件
<Component @event=""/>
<Component @click.native=""/>
全局事件总线(全局通信)
//设置全局事件总线$bus
new Vue({
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus=this;
}
}).$mount('#app')
//在组件中触发总线事件
this.$bus.$emit("event",params...);
//在组件中设置总线事件回调
this.$bus.$on("event",(params,...)=>{
});
//在组件中取消总线事件回调
this.$bus.$off("event");
//消息发布与订阅,与全局总线类似
//下载依赖
npm i pubsub-js
//订阅消息
this.pubId=pubsub.subscribe('name',(name,params,...)=>{
});
//发布消息
pubsub.publish('name',params,...);
//取消订阅
pubsub.unsubscribe(this.pubId);
Vue CLI
vue官方脚手架
#下载
npm install -g @vue/cli
#创建项目
vue create project
#运行项目
npm run serve
脚手架结构
文件目录
├── node_modules 依赖文件
├── public
│ ├── favicon.ico 页签图标
│ └── index.html 主页面
├── src
│ ├── assets 存放静态资源
│ │ └── logo.png
│ │── components 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue 汇总所有组件
│ └── main.js 入口文件
├── .gitignore git版本管制忽略的配置
├── babel.config.js babel的配置文件
├── package.json 应用包配置文件
├── README.md 应用描述文件
├── package-lock.json 包版本控制文件
└── vue.config.js vue配置文件
Vuex
Vuex是用来管理组件的公共数据的插件
- store.js配置
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex);
//存储共享数据
const state={
data
};
//类似于computed计算属性
const getters={
getterData(state){
}
};
//修改数据的前置操作
const actions={
action(context,params,...){
...
//提交修改请求
context.commit("ACTION",params,...);
},
};
//修改数据
const mutations={
ACTION(state,params,...){
}
};
export default new Vuex.Store({
state,
actions,
mutations,
getters,
});
//每个组件都能访问到$store对象
//访问数据
this.$store.state.data;
this.$store.getters.getterData;
//处理数据
this.$store.dispatch("action",params,...);
this.$store.commit("ACTION",params,...);
//为简化外部访问和调用,可以将其直接配置到当前组件上
import {
mapState,mapGetters,mapActions,mapMutations} from "vuex"
//通过对象解构生成计算属性
computed:{
...mapState(["data",...]),
...mapGetters(["getterData",...]),
},
//需要在调用方法时进行传参
methods:{
...mapActions(["action",...]),
...mapMutations(["ACTION",...]),
},
- 除此之外,还可以将数据拆分为多个模块进行管理
export default new Vuex.Store({
//公共数据及处理操作
state,
getters,
actions,
mutations,
//拆分为多个文件模块分别引入
modules:{
module:{
namespaced:true,//开启命名空间
state,
getters,
actions,
mutations,
},
}
})
//访问数据
this.$store.state.module.data;
this.$store.getters["module/getterData"];
//处理数据
this.$store.dispatch("module/action",value);
this.$store.commit("module/ACTION",value);
//简化调用
import {
mapState,mapGetters,mapActions,mapMutations} from "vuex"
computed:{
...mapState("module",["data",...]),
...mapGetters("module",["getterData",...]),
},
methods:{
...mapActions("module",["action",...]),
...mapMutations("module",["ACTION",...]),
},
Vue Router
Vue Router是用来实现多个视图的单页面web应用插件
- router.js配置
import Vue from "vue"
import VueRouter from "vue-router"
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
path:"/path",
component:() => import('@/components/Component'),
meta:{
},//自定义路由信息
//简化路由参数的引用,参数在路由组件的props中获取
props($route){
return {
key:val,...}}
children:[
{
path:"path",
name:"routeName",//路由名称
//通过命名视图可以在同一路由展示多个组件
components:{
//未命名视图default
default:Component,
viewName1:Component1,
viewName2:Component2
}
},
]
},
]
})
<!-- 展示与该视图元素所在层级相同的路由组件 -->
<router-view name="viewName"></router-view>
<!-- 路由导航 -->
<router-link to="/path"></router-link>
<!-- 路由传参一,通过this.$route.query.xxx引用 -->
<router-link :to="`/path?param=${param}`"></router-link>
<router-link :to="{
path:'/path',
query:{params,...}
}"></router-link>
<!-- 路由传参二,通过this.$route.params.xxx引用 -->
<router-link :to="/path/:param"></router-link>
<router-link :to="{
name:'routeName',
params:{params,...},
}"></router-link>
- 编程式路由导航
this.$router.push({
path:"/path",
query:{
params,...}
});
this.$router.push({
name:"routeName",
params:{
params,...}
});
this.$router.back();//后退
this.$router.forward();//前进
- 缓存路由组件
<!-- 让不展示的路由组件保持挂载,不被销毁 -->
<!-- 默认全部缓存 -->
<keep-alive include="Component">
<router-view></router-view>
</keep-alive>
- 路由组件生命周期
//激活与非激活
activated(){
}
deactivated(){
}
- 路由守卫
//全局前置守卫(进入前)
router.beforeEach((to,from,next)=>{
...
next("/path");//放行
});
//全局后置守卫(进入后)
router.afterEach((to,from)=>{
...
next();
});
//独享路由守卫(进入本路由前)
beforeEnter(to,from,next){
...
next();
}
//组件内守卫(路由进入前)
beforeRouteEnter(to,from,next){
...
next();
}
//组件内守卫(路由离开前)
beforeRouteLeave(to,from,next){
...
next();
}
- 注意项
- 通过切换,隐藏了的路由组件,默认是被销毁掉的,需要的时候再去挂载
- 每个组件都有自己的$route属性,里面存储着自己的路由信息
ctivated(){}
deactivated(){}
5. 路由守卫
```js
//全局前置守卫(进入前)
router.beforeEach((to,from,next)=>{
...
next("/path");//放行
});
//全局后置守卫(进入后)
router.afterEach((to,from)=>{
...
next();
});
//独享路由守卫(进入本路由前)
beforeEnter(to,from,next){
...
next();
}
//组件内守卫(路由进入前)
beforeRouteEnter(to,from,next){
...
next();
}
//组件内守卫(路由离开前)
beforeRouteLeave(to,from,next){
...
next();
}
- 注意项
- 通过切换,隐藏了的路由组件,默认是被销毁掉的,需要的时候再去挂载
- 每个组件都有自己的$route属性,里面存储着自己的路由信息
- 每个组件都能访问到全局$router