Vue2笔记--组件化进阶

Vue2笔记--组件化进阶,第1张

Vue脚手架(2) 1.Vue动画

自己使用 Css 也能实现


// apper属性可以让动画加载时出现 简写 apper 属性直接添加
<transition name="hello" :apper="true" apper>
	<div>
        <button @click="isShow = !isShow">
            显示/隐藏
        button>
        <h1 v-show="isShow">
            我是动画元素
        h1>
    div>
transition>



<style>
    
    /* .之后的名称与name一致 不加name默认为v */
    .hello-enter-active {
        animation: 动画名 持续时间;
    }
    .hello-leave-active {
        animation: 动画名 持续时间 everse;
    }
    
    
    .v-enter-active {
        animation: 动画名 持续时间;
    }
    .v-leave-active {
        animation: 动画名 持续时间 everse;
    }
    
    @keyfarm 动画名{
        ...
	}
style>
2.Vue过渡

// apper属性可以让动画加载时出现 简写 apper 属性直接添加
<transition name="hello" :apper="true" apper>
	<div>
        <button @click="isShow = !isShow">
            显示/隐藏
        button>
        <h1 v-show="isShow">
            我是动画元素
        h1>
    div>
transition>



<style>
    
    /* .之后的名称与name一致 不加name默认为v */
	/* 给所需动画添加过度属性 */
    h1 {
        transition: all 0.5s linear;
    }

    /* 初始效果 离开的终点 */
    .v-enter,.v-leave-to {
        animation: 动画名 持续时间;
    }
    
    /* 过渡效果中 */
    .v-enter-active,.v-leave-active {
        transition: all 0.5s linear;
    }    
    
    /* 结束效果 结束的起点 */
    .v-leave-enter-to,.v-leave {
        animation: 动画名 持续时间 everse;
    }
    
    @keyfarm 动画名{
        ...
	}
style>
3.多个元素过渡

// apper属性可以让动画加载时出现 简写 apper 属性直接添加
<button @click="isShow = !isShow">
    显示/隐藏
button>

<transition-group group name="hello" apper>
	<div>
        <h1 v-show="isShow">
            我是动画元素
        h1>
        <h1 v-show="isShow">
            我是动画元素
        h1>
    div>
transition-group>



<style>
    
    /* .之后的名称与name一致 不加name默认为v */
	/* 给所需动画添加过度属性 */
    h1 {
        transition: all 0.5s linear;
    }

    /* 初始效果 离开的终点 */
    .v-enter,.v-leave-to {
        animation: 动画名 持续时间;
    }
    
    /* 过渡效果中 */
    .v-enter-active,.v-leave-active {
        transition: all 0.5s linear;
    }    
    
    /* 结束效果 结束的起点 */
    .v-leave-enter-to,.v-leave {
        animation: 动画名 持续时间 everse;
    }
    
    @keyfarm 动画名{
        ...
	}
style>

4.超级好用的动画库

animate.css

// 使用方法
// name="animate__animated animate__bounce" 在 transition中添加该属性

// 在官网找到喜欢的属性配置 复制添加到
// enter-active- leave-active-

官网:Animate.css | A cross-browser library of CSS animations.

5.Http请求 代理
// 对 xhr 进行封装
// xhr new XMLHttpRequest() xhr.open() xhr.send()
// jQuery $.get $.post
// axios

// 与 xhr平级
// fetch

Vue 项目中 推荐使用 axios

解决跨域问题

1.CORS

2.Jsonp script src 只能使用 get

3.代理服务器 代理服务器默认端口号 8080

1.-- nginx

2.-- vue-cli

5.1简易代理
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
    // 在配置文件中添加以下配置 开启代理服务器 代理服务器开启在 8080
  devServer: {
      // 需要转发给谁
    proxy:'http://后端服务器地址',
  }
})


/*
注意
8080端口服务器 的根目录为 public 其中有的东西直接回返回
不会转发请求
*/

// 在axios中请求
axios.get('http://localhost:8080/后端路由地址').then(
	response =>{
        
    },
    errror =>{
        
    },
)

5.2完美代理
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
    // 在配置文件中添加以下配置 开启代理服务器 代理服务器开启在 8080
  devServer: {
     proxy:{
         // 配置 转发服务器的前缀
         '/api':{
             // 转发地址
             target:'http://后端服务器地址',
             //加入此配置项 转发地址为 /api/student 替换为 /student 不然会请求原路径
             pathRewrite:{
                 '^/api':''
             },
             ws:true, // 用于支持 websocket 
             changeOrigin:true, // 说谎(伪装请求地址) 默认为 true
         },
         // 可配置多个
         '/cas':{
             target:'http://后端服务器地址',
             pathRewrite:{
                 '^/cas':''
             },
             ws:true,
             changeOrigin:true,
         }
     }
  }
})

axios.get('http://localhost:8080/配置的前缀/后端路由地址')
6.静态组件
import '....' // vue 会进行严格的语法检查 放在assat进行引入
// 推荐放入 public 文件夹 在 index.html 中使用 link 引入 bootstrap.. 等 

ES6 合并对象语法 Obj = {…对象1名称,…对象2名称}

7.vue-resource vue的插件库

对 xhr 进行封装

Vue.use(vueResource) 在main.js中进行全局配置

在 vm 中会出现 $http

使用 this.$http 代替 axios api完全一致 vue1.0广泛使用

8.slot 插槽 8.1默认插槽

<Student/>
<Student>Student>




<Student>
    
	<img src="">
Student>


<div>
    
	<slot>使用者没有传入插槽 会将我展示slot>
div>


8.2(具名插槽)多个插槽


<Student>
    
	<img src="" slot="slot名称1">
    <vido src="" slot="slot名称2">
        
    
        
    <template slot="slot名称1" slot:slot名称1>
        <h1>我是h1h1>
        <div>我是divviv>
    template>
Student>


<div>
    
	<slot name="slot名称1">使用者没有传入插槽 会将我展示slot>
    <slot name="slot名称2">使用者没有传入插槽 会将我展示slot>
div>


8.3作用域插槽


<Student>
    
    <template scop="Obj">
        
        <h1>{{Obj.games}}h1>
        <h1>{{Obj.msg}}h1>
    template>
Student>


<div>
    
	<slot :games="games" msg="这里是msg信息">使用者没有传入插槽 会将我展示slot>
div>


9.Vuex

多组件共享数据 状态 = 数据

多个组件依赖于同一个状态来自不同组件的行为需要修改同一状态
1.npm i vuex

2.import Vuex from 'vuex' // 在 index.js 中 引入
// vue2 -> vuex3
// vue3 -> vuex4
3.Vue.use(Vuex)

Vue({
    store:"hello",
})

// 在 vm 中 出现 $store 保存传入的数据

在components同级文件夹下添加 store 文件夹

添加 index.js

// 该文件用于创建 Vuex 中最为核心的store

// 引入 
import Vue from 'vue'
import Vuex from 'vuex'
// 应用Vuex插件
Vue.use(Vuex)
// 准备 actions
const actions = {
    // 需要dispatch的函数
    "函数名"(context,value){
        console.log('actions 中的函数被调用了',context,value); 
        
        // 分配给 其他 dispatch 分段处理 便于维护代码
        context.dispatch("函数2",value);
        
        context.commit("函数名(使用大写与actions进行区分)",value);
    }
}
// 准备 mutations  *** 作 data
// 开发者工具 检测 mutations
const mutations = {
    "大写函数名"(state,value){
		state.value += value;
    }
}
// 准备 state 用于存储数据 全局 data
const state = {e
    // 准备数据
    value:0,
    // 改变后会替代 vc 里的 data
}

// 实现全局的 计算属性 computed
const getters = {
    // 对 state 进行加工
    bigSum(state){
        return state.sum*10;
    }
}

// 创建并暴露 store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})

main.js

import store from './store/index.js'
// 配置项中添加store
new Vue({
    store
})

js 执行 import 全部 import 会被提升到最高层

vue 规定必须 先 ues(vuex) 再 创建 store 实例

使用2.import Vuex from ‘vuex’
// vue2 -> vuex3
// vue3 -> vuex4
3.Vue.use(Vuex)

methds:{
    this.$store.dispatch("事件名",传入的数据);
    // 直接跨过action
    this.$store.commit("事件名",传入的数据);
    // 获得计算属性
    this.$store.getters.bigSum;
}

可直接夸过 Actions 进行 Commit 调用 mutation 的函数

vuex 开发者工具 历史记录符号

回到该次数据 历史记录符号

可以删除历史记录 禁用符号

合并记录 下载符号

底部分 可以 导入导出 / 粘贴复制

ES6 语法

let Obj1 = {x:1,y:2}
let Obj2 ={
    z:3,
    ...Obj1, // 直接将Obj1的键值对插入
    m:7,
}
9.1 **mapState **mapGetters
import {mapState} from 'vue'
// 映射 State 中的数据
computed:{
    // 借助mapState生成计算属性 从state中读取数据
    ...mapState({sum:'sum',adress:'adress'}) // 可直接在计算属性中添加
    // 不可简写 对象简写方式为 {sum:sum} === {sum}  !== {sum:"sum"}
    
    // Vue 可识别 简写方法 与上述方法用途一致
    ...mapState(['sum','subject'])
    
    // 全局计算属性获取
    ...mapGeters(['bigSum'])
}
9.2 mapAction mapMutations
import {mapState} from 'vue'
// 映射 State 中的数据
methods:{
    
    // 数组 / 对象 形式默认生成方法 需要在调用时传参
    /*add(value){
    	this.$store.commit('add',value)
	}*/  
    
	...mapActions(['add']),
    ...mapMutations(['add'])
}
9.3Vuex模块化

index.js

import Vuex from 'vuex'

// 计数相关属性
const countOptions = {
   // 配置该项可在 组件 中使用更简洁的写法
   namespaced:true,
   
   // 与正常 vuex 配置完全一致
   action:{},
   mutation:{},
   state:{},
   getter:{},
}

// 人员相关属性
const personOptions = {
   action:{},
   mutation:{},
   state:{},
   getter:{},
}

export default new Vuex.Store({
   modules:{
       countAbout:countOptions,
       personAbout:personOptions
   }
})
// 组件中简写使用
computed:{
    // 普通简写
    // 调用 state时 需要使用 countAbout.data
    ...mapState(['countAbout','personAbout']),
    
    // 需要在 vuex 中 开启 namespaced
    // 调用时 直接使用 data 就可以
    ...mapState('countAbout',['data']),
    ...mapState('personAbout',['data']),
        
    // 其他 map 同理使用
        
        // getter 模块化之后 值为 countAbout/bigSum  countAbout不再为对象
}
10.路由 10.1 路由基础

单页面应用 路由改变 页面局部刷新 (没有全部刷新)

使用 vue 的插件库 vue-router

npm install -g vue-router

/*
vue-router 3 版本对应 vue 2
vue-router 4 版本对应 vue 3
*/

// npm install vue-router@3

在 components 同级文件夹下创建 router 文件夹

index.js

// 引入 vue-router
import Vuerouter from 'vue-router'
// 引入组件
import TheList from '../components/TheList.vue';
import AboutSnowman from '../components/AboutSnowman.vue';

// 创建 并 暴露 一个路由器
export default new VueRouter({
    routes: [
        {
            path:"/TodoList",
            component:TheList,
        },
        {
            path:"/about",
            component:AboutSnowman,
        },
        // path 为 * 表示匹配全部 可以匹配全部路径 路径匹配为从上至下
        {
            path:"*",
            component:AboutSnowman,
        },

    ]
})

main.js

// 引入 路由器
import router from './router'

new Vue({
  render: h => h(App),
  // 设置 router
  router:router,
}).$mount('#app')



<router-link to="/TodoList" active-class="active">每日清单router-link>
<router-link to="/about" active-class="active">关于我的主页router-link>


<router-view>router-view>

在 components 同级文件夹下创建 pages 文件夹

便于分类 pages存放 路由组件 components文件夹存放 一般组件

原理 : {不断销毁与挂在组件}

每个组件都有自己的$route属性,里面存储着自己的路由信息整个应用只有一个router, 可以通过组件的$router属性获取到 10.2 多级路由 (嵌套路由)

index.js

// 引入 vue-router
import VueRouter from 'vue-router'
// 引入组件
import TheList from '../components/TheList.vue';
import AboutSnowman from '../components/AboutSnowman.vue';

// 创建 并 暴露 一个路由器
export default new VueRouter({
    routes: [
        // 一级路由
        {
            path:"/TodoList",
            component:TheList,
            // 路由嵌套从这里开始
            // 二级路由
            children:[{
                // 第二级不需要加 / 会出问题
                path:"new",
                component:TheList,
            }]
        },
        // 一级路由
        {
            path:"/about",
            component:AboutSnowman,
        },

    ]
})





<router-link to="/TodoList/new" active-class="active">每日清单router-link>
<router-link to="/about/new" active-class="active">关于我的主页router-link>


<router-view>router-view>
10.3 路由传参

query参数 get传参

<router-link to="/TodoList/new?name=雪人&age=18" active-class="active">每日清单router-link>


<router-link :to="`/TodoList/new?name=${name}&age=${age}`" active-class="active">每日清单router-link>


每日清单router-link>

<router-link to="/about/new" active-class="active">关于我的主页router-link>
// 组件中获取
this.$route.query.name
this.$route.query.age
10.4 命名路由
export default new VueRouter({
    routes: [
        {
            // 配置姓名 简化传参
            name:'ListName',
            path:"/TodoList",
            component:TheList,
            children:[{
                // 配置姓名 简化传参
                name:'new',
                path:"new",
                component:TheList,
            }]
        },
    ]
})


<router-link :to="`{
                  // 此处直接传入 路由器 定义的名字
                  name:"ListName",
                  query:{
                         name:name,
                         age:age,
                         }               
                  }
                  `" active-class="active">每日清单router-link>
10.5 params参数

<router-link :to="`/TodoList/new/11/王二`" active-class="active">每日清单router-link>

<router-link :to="`{
                  // params 只能使用name path会报错!!!
                  name:"ListName",
                  params:{
                         id:11,
                         name:"王二",
                         }               
                  }
                  `" active-class="active">每日清单router-link>
export default new VueRouter({
    routes: [
        {
            // 添加占位符设置参数
            name:'ListName',
            path:"/TodoList/:id/:name",
            component:TheList,
            children:[{
                // 添加占位符设置参数
                name:'new/:id/:name',
                path:"new",
                component:TheList,
            }]
        },
    ]
})
// 组件中获取
this.$route.params.name
this.$route.params.age
10.6 props的配置
export default new VueRouter({
    routes: [
        {
            name:'ListName',
            path:"/TodoList/:id/:name",
            component:TheList,
            children:[{
                name:'new/:id/:name',
                path:"new",
                component:TheList,
                // props 写法一
                // 该对象中的所有 key-value 都会以props的形式传给 组件 TheList中
                props:{id:1,name:'hello'},
                
                // props 写法二
                // props值为布尔值,若布尔值为真,就会把该参数的 params值当做 props 值传递给组件
                props:true,
                
                // props 写法三
                // 值为函数 返回值 以props 传递给组件
                // $route 被回调传入 真好
                props($route){
                    return {id:$route.query.id,name:'hello'}
				}
                
                // 结构赋值写法
                props({query}){
                    return {id:query.id,name:query.name}
				}
            }]
        },
    ]
})
10.7 replace 记录

默认为push记录 栈的不断添加

replace 替换当前记录 不能返回


<router-link to="/TodoList/new" active-class="active" :replace="true">每日清单router-link>

<router-link to="/about/new" active-class="active" replace>关于我的主页router-link>
10.8 编程式路由导航

在 $router 中 直接 *** 作 不借助 router-link




10.8 缓存路由组件

组件切走时会被销毁 内容消失 如何保存?

需要保存数据的去缓存



<keep-alive inlude="组件名">
	<router-view>router-view>
keep-alive>


<keep-alive :inlude="['组件名1','组件名2','组件名3']">
	<router-view>router-view>
keep-alive>
10.9激活与失活声明周期

用于路由组件的 开启定时器 比 mounted更高效

methods:{
	activated(){
        // 开启定时器
    },
    deactivated(){
        // 定时器自动关闭
    }
}
10.10路由守卫 1.前 / 后 置路由守卫

保护路由的安全 验证数据库再展示

全局前置路由守卫

export default new VueRouter({
    routes: [
        {
            path:"/TodoList",
            component:TheList,
            // 用于存放用户需要的特殊数据
            // 可以在判断中进行索引 不指定默认为 undefined 为 false
            meta:{isAuth:true,title:"每日清单"},
        }
    ]
})



// 全局前置路由守卫
// to 路由去向 路由对象
// from 路由由来 路由对象
// next 回调函数 使用 next()才能切换路由
router.beforeEach((to,from,next)=>{
	if(to.path === '/home'){
        // 利用meta判断
        if(from.meta.isAuth){
            next()
        }
        next()
    }
    next()
})
export default router
// 全局后置路由守卫
// 无 next 路由跳转已经完成后触发
router.afterEach((to,from)=>{
    // 可在跳转完成后更改路由
	doucment.title = to.meta.title || '网页标题' // 短路判断
})
2.独享路由守卫
export default new VueRouter({
    routes: [
        {
            path:"/TodoList",
            component:TheList,
            // 用于存放用户需要的特殊数据
            // 可以在判断中进行索引 不指定默认为 undefined 为 false
            meta:{isAuth:true,title:"每日清单"},
            
            // 独享路由守卫 仅有前置 无后置
            beforeEnter:(to,from,next)=>{
                if(...){
                   next()
                   }
			}
        }
    ]
})
3.组件内路由守卫

11.浏览器路由模式

main.js

// hash 带 # 兼容性好 不美观 
// history 不带 # 兼容性差(相对) 美观 会寻找服务器路径资源 容易出错(后端解决)

new VueRouter({
    // 设置模式
    mode:history,
})
12.打包 上传服务器
>>> npm run build
// 生成 dist 文件夹
// 为打包后的 css js html 文件
// 直接点击 index.html 无法运行必须在服务器部署

如何部署服务器

node.js express 框架

->npm init

->text_serve 包名

->npm i express

中间件解决 history 模式 404问题

->npm i connect-history-api-fallback

// 在 server.js 同级目录下 新建 js

const express = require('express')
const history = require('connect-history-api-fallback')

const app = express()

// 解决history 404 问题
app.use(history)
// 默认选择 index.html
app.use(express.static(__dirname+"./static"))

app.get('/person',(req,res)=>{
    res.send({
        name:'tom',
        age:18
	})
})

app.listen(5005,(err)=>{
    if(!err) console.log('服务器启动成功了!')
})
13.Vue UI 组件库

7.1 移动端常用组件库

Vant https://youzan.github.io/vanteCube UI https://didi.github.io/cube-uiMint Ul http://mint-ui.github.io

7.2PC端常用UI组件库

Element Ul https://element.eleme.cnlView Ul https://www.iviewui.comant design Ant Design - 一套企业级 UI 设计语言和 React 组件库

直接用就行

此处介绍Element UI

->npm i element-ui

import Vue from 'vue';
import ElementUI from 'element-ui';
// 引入全部样式
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

// 此处use 后 会注册全部组件为全局组件
// 引入的 js 非常大 7.2M(别用)
Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

按需引入

-> npm install babel-plugin-component -D 按需引入的库 -D为开发依赖(开发环境)

需要修改 babel.config.js 配置

module.exports = {
  presets: [
      // vue 相关js
    '@vue/cli-plugin-babel/preset',
      // element ui 预设
      // ["es2015", { "modules": false }] 官网没更新 旧版脚手架的
      ["@babel/preset-env", { "modules": false }],
      // 两个都试一下 版本问题
      ["@babel/env", { "modules": false }]
  ],
    // element ui 插件
    "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

main.js

// 按需引入 
import {Button,Row,...} from 'element-ui'
// 配置之后会引入需要的 css 而不是全部css
import 'element-ui/lib/theme-chalk/index.css';

// Button 的组件名 可以自定义
// 注册全局组件
VUe.component(Button.name,Button)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1297232.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存