作者: admin

  • vue-router笔记

    使用vue2

    https://www.jianshu.com/p/4c5c99abb864

    vue-router是可以实现当页应用的工具

     

    路由参数总览

    new VueRouter({
           routes:[
                {
                   path: '/', 
                   name: 'Hello',
                   component:{
                        template: '<div>User</div>'
                   },
                   children: [
                        {
                          path: 'profile',
                          component: UserProfile
                        },
                        {
                          path: 'posts',
                          component: UserPosts
                        }
                   ],
                   redirect:""
                }
           ]
      })

     

     

     

    环境搭建:

    npm init --yes  //创建默认package.json

     

    安装

    npm i vue@2.6.11 vue-router@3.3.4 -S
    npm i @vue/cli-service@4.4.6 vue-template-compiler@2.6.11 -D
    npm i html-webpack-plugin@3.2.0 -D

    @vue/cli-service //模块基于webpack的 webpack-dev-server又在进行二次开发封装
    vue-template-compiler //读取识别vue格式的文件
    html-webpack-plugin //指定默认模板 /public/index.html

     

    指定html模板

    https://cli.vuejs.org/zh/guide/html-and-static-assets.html#public-%E6%96%87%E4%BB%B6%E5%A4%B9

    安装好html-webpack-plugin,在跟目录下创建public/index.html,就默认使用了

    //index.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="renderer" content="webkit">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <title><%= webpackConfig.name %></title>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>

     

    @vue/cli-service

    vue项目,打包,开发都是通过命令启动

    https://cli.vuejs.org/zh/guide/cli-service.html#%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4

    编辑package.json,添加快捷键:

    {
      "scripts": {
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build"
      }
    }

    最基本两个命令是
    1,打包 npm run build
    2,开发 npm run serve
    执行以上两个命令默认都会执行./src/main.js ,说明main.js就是整个项目的入口文件了

     

    入口、模板创建

    新建目录src
    创建:/src/main.js //这个就是所有文件的入口

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import App from './app.vue' //vue母版页
    import Index from './index.vue'  //首页html、js
    Vue.use(VueRouter)
    
    
    var CreateVue = new Vue({
      el:'#app',
      router:new VueRouter({
           routes:[
               { path: '/', component: Index }
           ]
      }),
      render(createElement){
            return createElement(App);
       },
    })

     

    创建:/src/app.vue //视图入口模板

    <template>
        <div id="app">
            <router-view/>  //所有的html都引入到这里
        </div>
    </template>
    
    <script>
        export default {
            name: "app"
        }
    </script>
    
    <style scoped>
    </style>

     

    //创建一个首页模板
    /src/index.vue //以后的模板页都类似这样创建,index.vue的内容会被引入到app.vue中
    <template>
        <div>
            首页
        </div>
    </template>
    
    <script>
        export default {
            name: "index"
        }
    </script>
    
    <style scoped>
    </style>

     

     

    vue-router模式
    有两种模式:hash(默认),history

    (1)hash
    hash 原理 依靠监听onhashchange事件,获取到#后面的参数,始终都以index.html作为模板页,实现组件切换视图,页面不会去刷新再次请求资源

    (2)history
    history 模式的原理
    H5新推出的两个神器:pushState与replaceState
    作用就是将url替换且不刷新,好比挂羊头卖狗肉,http并没有去请求服务器该路径下的资源,缺点就是,一旦刷新就会暴露这个实际不存在的“羊头”,显示404,以下是解决找不到页面的办法。

    1,需要后台支持history模式,就需要配置nginx、apache或者IIS,这里以nginx为案例
    例如项目地址是:http://localhost:8080/dist/#/

    module.exports={
        publicPath: '/dist',
    }

     

    new Router({
            mode:'history',
            base: '/dist'
    })

     

    location / {
     
        try_files       $uri $uri/ /dist/index.html; #意思是找不到文件或者目录找到该文件
    }

    vue-router路由hash和history原理及history需后台配置

    导航钩子 (也就是url)
    1.全局的
    2.单个路由独享的
    3.组件级的

     

    全局:

    router.beforeEach((to, from, next) => {
        //to: Route,代表要进入的目标,它是一个路由对象
        // from: Route,代表当前正要离开的路由,同样也是一个路由对象
        //next: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数
    });
    
    router.afterEach((to, from) => {
        // do someting
    });

     

    路由独享的钩子:

    cont router = new VueRouter({
        routes: [
            {
                path: '/file',
                component: File,
                beforeEnter: (to, from ,next) => {
                    // do someting
                }
            }
        ]
    });

     

    组建内的导航钩子:

    data(){
      return(){
      }
    },
        beforeRouteEnter(to, from, next) {
            // do someting
            // 在渲染该组件的对应路由被 confirm 前调用
        },
        beforeRouteUpdate(to, from, next) {
            // do someting
            // 在当前路由改变,但是依然渲染该组件是调用
        },
        beforeRouteLeave(to, from ,next) {
            // do someting
            // 导航离开该组件的对应路由时被调用
        }
    },
    methods:{
    }

     

     

    路由异步加载
    {
    path: '/redirect',
    component: Layout,
    hidden: true,
    children: [
      {
        path: '/redirect/:path(.*)',
        //import方式引入,只有访问该页面时才会加载该页面资源
        component: () => import('@/views/redirect/index') 
      }
    ]
    },

     

    同步
    以这种方式引入,一开始进入首页时就会全部都加载出来

    import Home from '../views/Home.vue'
    {
        path: '/redirect/:path(.*)',
        //import方式引入,只有访问该页面时才会加载该页面资源
        component: Home
    }

     

     

    路由跳转 (类似创建a链接)
    跳转方式一:
    this.$router.push({
        name:'guanyu',
    })
    
    跳转方式二:
    <router-link :to="{name:'guanyu'}">关于我们</router-link>
    
    上面的name就是创建路由的name
    { path: '/about', component: About ,name:'guanyu' }

     

    传参 (页面之间传参)

    方式一: params传参
    goAbout(){
        this.$router.push({
            name:'guanyu', //要使用params传参必须使用,name路由跳转才能使用
            params:{key:11}
        })
    }
    
    <router-link :to="{name:'guanyu',params:{key:11}}">关于我们</router-link>
    
    获取:this.$route.params
    优点:可以传大的数据量
    缺点:传过来的数据,刷新当前页面参数就被清空
    
    方式二:query传参
    <router-link :to="{name:'guanyu',query:{key:11}}">关于我们</router-link>
    
    this.$router.push({
        name:'guanyu',
        query:{key:11}
    })
    获取:this.$route.query
    优点:传过来的数据,刷新当前页面参数依然存在
    缺点:数据过大会丢失,因为是以get方式提交过来的

     

    公共组件回调

    情景:/user/aside导航到 /user/foo,如果加载了公共组件例如<header></header>
    因为两个路由都渲染同个组件,比起销毁再创建,复用则更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
    <header></header>组件生命周期钩子created和mounted都不会调用。
    但是有些业务逻辑,是需要根据不同路径执行不同业务。

    //在header组件添加
    watch: {
      $route: {
            handler: function(route) {
               console.log(route)
            },
            immediate: true,
            deep: true,
      }
    },

    或者

    编辑/src/App.vue (推荐)

    <router-view :key="key" /> //添加:key="key"
    
    computed: {
          key() {
            return this.$route.path
          }
    }

    有点类似在url加版本上就可以清除缓存,每次跳转,即使加载同一个组件,
    也会每次都会去加载渲染,这样created和mounted又能触发了

     

     

     

  • 页面缩放触发js事件

    <script>
    
        function devicepix(){
            let currentPixelRatio = window.devicePixelRatio;
    
            if (currentPixelRatio !== lastPixelRatio) {
                console.log('页面缩放变化了');
            }
    
            lastPixelRatio = currentPixelRatio;
            console.log(lastPixelRatio)
        }
    
    
        let lastPixelRatio = window.devicePixelRatio;
        window.addEventListener('resize', devicepix);
    
        devicepix()
    </script>

     

  • js开始时间结束时间显示第几周

    例如,输入’2021-3-1’到’2023-9-31’就会显示

    这里需要注意,年底的最后一周即使不满7天我也算成一周,新年的1月份不满7天我也会算第一周,截图如下;

     

    demo:zhouzhou

  • 微信、QQ截图粘贴图片触发js

    <!DOCTYPE HTML>
    <html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <title>利用 clipboardData 在网页中实现截屏粘贴的功能</title>
        <style type="text/css">
            #box{ width:200px; height:200px; border:1px solid #ddd; }
        </style>
    </head>
    <body>
    
    <h1>利用 clipboardData 在网页中实现截屏粘贴的功能</h1>
    <hr />
    <div><input type="text" id="testInput" placeholder="截屏后粘贴到输入框中" size="30" /></div>
    <script type="text/javascript">
        (function(){
            var imgReader = function( item ){
                var blob = item.getAsFile(),
                    reader = new FileReader();
                // 读取文件后将其显示在网页中
                reader.onload = function( e ){
                    var img = new Image();
    
                    img.src = e.target.result;
                    document.body.appendChild( img );
    
                    console.log(img)
                };
                // 读取文件
                reader.readAsDataURL( blob );
            };
            document.getElementById( 'testInput' ).addEventListener( 'paste', function( e ){
                // 添加到事件对象中的访问系统剪贴板的接口
                var clipboardData = e.clipboardData,
                    i = 0,
                    items, item, types;
    
                if( clipboardData ){
                    items = clipboardData.items;
                    if( !items ){
                        return;
                    }
                    item = items[0];
                    // 保存在剪贴板中的数据类型
                    types = clipboardData.types || [];
                    for( ; i < types.length; i++ ){
                        if( types[i] === 'Files' ){
                            item = items[i];
                            break;
                        }
                    }
                    // 判断是否为图片数据
                    if( item && item.kind === 'file' && item.type.match(/^image\//i) ){
                        imgReader( item );
                    }
                }
            });
        })();
    </script>
    </body>
    </html>
    

    案例:zhantie

  • 等宽、等高、全屏自适应大屏幕解决方案

    核心原理就是通过scale属性计算。

    直接看demo:zishiying