20230427----重返学习-移动端商城

day-059-fifty-nine-20230427-移动端商城

移动端商城

vant2

安装vant2
  • 安装vant2插件
npm i vant@latest-v2
使用vant2组件

选一种使用

  • 方式一-自动按需引入组件 (推荐)

    1. 安装插件

      npm i babel-plugin-import -D
      
    2. /babel.config.js中添加

      module.exports = {
        presets: [
          '@vue/cli-plugin-babel/preset'
        ],
        plugins: [
          ['import', {
            libraryName: 'vant',
            libraryDirectory: 'es',
            style: true
          }, 'vant']
        ]
      }
      
    3. /src/main.js中导入

        import 'vant/lib/index.css';
        import { Button } from 'vant';
        Vue.use(Button)
      
      1. 不过一般在/src/vant/index.js中统一配置,以统一处理并解耦关于vant的组件引入

        // 1. 引入vue;
        import Vue from "vue";
        
        // 2. 引入vant的css样式
        import "vant/lib/index.css";
        
        // 3. 引入button组件,在组件中使用时是用`van-button`使用
        import { Button } from "vant";
        Vue.use(Button);
        
      2. /src/main.js中引入/src/vant/index.js并让它运行一次

        import './vant/index.js'
        
  • 方式二-手动按需引入组件

    • 在不使用插件的情况下,可以手动引入需要的组件。

    • 在具体的某个组件内

      <template>
        <div class="home">
          <van-button type="danger">使用van-button组件</van-button>
          <h1>h1</h1>
          <h3>h3</h3>
        </div>
      </template>
      
      <script>
      import 'vant/lib/button/style';//引入button的样式,使用这个的前提是安装了vant这个ui框架。
      import Button from 'vant/lib/button';//引入button的js代码,使用这个的前提是安装了vant这个ui框架。
      export default {
        name: "HomeView",
        components: {
          "van-button": Button,//要重命名引入的组件,最好是两个字母,中间用连接符分隔。
        },
      };
      </script>
      
  • 方式三-导入所有组件

    • Vant支持一次性导入所有组件,引入所有组件会增加代码包体积,因此不推荐这种做法。

    • /src/main.js中导入

      //1. 全局导入
      //import Vue from 'vue';//这个一般不用写,因为之前Vue脚手架已经导入了
      import Vant from 'vant';
      import 'vant/lib/index.css';
      Vue.use(Vant);
      
vant2组件的注册方式
全局注册
  • 全局组件-要全局注册

    1. /src/main.js/src/vant/index.js中导入对应的组件

      import Vue from 'vue';
      import { Button } from 'vant';
      
    2. 全局注册组件

      1. 通过 Vue.use 注册

        // 方式一. 通过 Vue.use 注册
        // 注册完成后,在模板中通过 <van-button> 或 <VanButton> 标签来使用按钮组件
        Vue.use(Button);
        
      2. 通过 Vue.component 注册

        // 方式二. 通过 Vue.component 注册
        // 注册完成后,在模板中通过 <van-button> 标签来使用按钮组件
        Vue.component(Button.name, Button);
        
    • 全局注册后,在项目所有的vue文件中都可以直接在模板中使用
局部注册
  • 局部组件-要局部注册

    • 在具体的一个vue组件中调用

      <template>
        <div class="home">
          <van-button type="primary">主要按钮</van-button>
          <van-button type="info">信息按钮</van-button>
          <van-button type="default">默认按钮</van-button>
          <van-button type="warning">警告按钮</van-button>
          <van-button type="danger">危险按钮</van-button>
          <h1>h1</h1>
          <h3>h3</h3>
        </div>
      </template>
      
      <script>
      import { Button } from 'vant';
      export default {
        name: "HomeView",
        components: {
          "van-button": Button,//要重命名引入的组件,最好是两个字母,中间用连接符分隔。
        },
      };
      </script>
      
    • 局部注册后,你只可以在当前组件中使用注册的 Vant 组件。

  • 仅演示,一般项目不用这种方式,有点麻烦

    • 但如果要放博客或vue2与vue3兼容,这种方式比较清晰
作用域插槽
  • Vant 提供了丰富的组件插槽,通过插槽可以对组件的某一部分进行个性化定制。
<template>
  <div>
    <van-checkbox v-model="checked">
      <!-- 使用组件提供的 icon 插槽 -->
      <!-- 将默认图标替换为个性化图片 -->
      <template #icon="props">
        <img :src="props.checked ? 'https://img01.yzcdn.cn/vant/user-active.png' : 'https://img01.yzcdn.cn/vant/user-inactive.png'" />
      </template>
    </van-checkbox>
  </div>
</template>

<script>
export default {
  data() {
    return {
      checked: true,
    };
  },
};
</script>

浏览器适配

移动端适配
  • Viewport 布局

    • Vant 默认使用 px 作为样式单位,如果需要使用 viewport 单位 (vw, vh, vmin, vmax),推荐使用 postcss-px-to-viewport 进行转换。
    • 步骤:
      1. 安装postcss插件和postcss-px-to-viewport插件

        //npm i postcss -D //vant默认已经安装了
        npm i postcss-px-to-viewport -D
        
      2. /postcss.config.js

        module.exports = {
          plugins: {
            'postcss-px-to-viewport': {
            viewportWidth: 375,
            },
          },
        };
        
  • Rem 布局适配

    • 根标签设置rem基准值,使用rem单位
    • px em rem 区别?
      • px是物理像素,em是相对父元素字体大小,rem是相对根元素字体大小。
    • 步骤
      1. 引入插件,用于在根标签设置rem基准值

        npm i -S amfe-flexible
        yarn add amfe-flexible
        
      2. 要求在根元素中引入一个js文件–即amfe-flexible插件中生成的js文件

        • 生效版:在/src/main.js中导入

          import "../node_modules/amfe-flexible/index.js"
          
        • 官网推荐:在模块文件/public/index.html中使用

          <script src="./node_modules/amfe-flexible/index.js"></script>
          
          • 不过不生效,是因为路径出错了。没能引到amfe-flexible插件中生成的js文件
            • 应该要在vue-cli或webpack中配置好,或者script的标签写对路径
      3. 使用rem单位

        • 自己计算转化
        • 自动计算转化,通过postcss-pxtorem这个postcss插件
          • 在项目中可以直接写px,自动转化为rem,不需要进行计算了
          • 步骤:
            1. 安装postcss插件和postcss-pxtorem插件

              //npm i postcss -D //vant默认已经安装了
              npm install postcss postcss-pxtorem@5.1.1 --save-dev//vue2的postcss-pxtorem要用@5.1.1,最新版不太支持。vue3可以使用最新版比较多。
              
            2. /postcss.config.js

              //设计稿的尺寸是 375
              // postcss.config.js
              
              module.exports = {
              plugins: {
                  'postcss-pxtorem': {
                  rootValue: 37.5,
                  propList: ['*'],
                  },
                },
              };
              
桌面端适配
  • Vant 是一个面向移动端的组件库,因此默认只适配了移动端设备,这意味着组件只监听了移动端的 触摸touch 事件,没有监听桌面端的 鼠标mouse 事件。
    • 如果需要在桌面端使用 Vant,可以引入Vant提供的 @vant/touch-emulator。
      • 这个库会在桌面端自动将 mouse 事件转换成对应的 touch 事件,使得组件能够在桌面端使用。
  • 步骤:
    1. 安装@vant/touch-emulator模块

      npm i @vant/touch-emulator -S
      
    2. /src/main.js中导入

      // 引入模块后自动生效
      import '@vant/touch-emulator';
      

底部安全区适配

  • iPhone X 等机型底部存在底部指示条,指示条的操作区域与页面底部存在重合,容易导致用户误操作,因此我们需要针对这些机型进行安全区适配。
    • Vant 中部分组件提供了 safe-area-inset-topsafe-area-inset-bottom 属性,设置该属性后,即可在对应的机型上开启适配。
  • 步骤:
    1. 在 head 标签中添加 meta 标签,并设置 viewport-fit=cover 值。

      • /public/index.html

        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover"
        />
        
    2. 在vue组件中使用safe-area-inset-topsafe-area-inset-bottom属性。

      • 顶部安全区适配

        <template>
          <div class="home-root">
            <!-- 开启顶部安全区适配 -->
            <van-nav-bar safe-area-inset-top />
          </div>
        </template>
        
      • 底部安全区适配

        <template>
          <div class="home-root">
            <!-- 开启底部安全区适配 -->
            <van-number-keyboard safe-area-inset-bottom />
          </div>
        </template>
        

基础页面

<template>
  <div style="height: 2000px">
    <h1>ClassifyView</h1>
  </div>
</template>
<script>
export default {};
</script>
<style>
</style>

路由配置

  1. 写五个vue页面组件,用于让van-tabbar标签来跳转对应的页面。
    • /src/views/IndexView.vue
      <template>
        <div style="height: 2000px">
          <h1>IndexView</h1>
        </div>
      </template>
      <script>
      export default {};
      </script>
      
    • /src/views/ClassifyView.vue
      <template>
        <div style="height: 2000px">
          <h1>ClassifyView</h1>
        </div>
      </template>
      <script>
      export default {};
      </script>
      
    • /src/views/CartView.vue
      <template>
        <div style="height: 2000px">
          <h1>CartView</h1>
        </div>
      </template>
      <script>
      export default {};
      </script>
      
    • /src/views/MyView.vue
      <template>
        <div style="height: 2000px">
          <h1>MyView</h1>
        </div>
      </template>
      <script>
      export default {};
      </script>
      
    • /src/views/LoginView.vue
      <template>
        <div style="height: 2000px">
          <h1>LoginView</h1>
        </div>
      </template>
      <script>
      export default {};
      </script>
      
  2. 配置路由及重定向
    • /src/router/index.js
      import Vue from "vue";
      import VueRouter from "vue-router";
      import IndexView from "../views/IndexView.vue";
      
      
      Vue.use(VueRouter);
      
      const ClassifyView = () =>
        import(/* webpackChunkName: "ClassifyView" */ "../views/ClassifyView.vue");
      const CartView = () =>
        import(/* webpackChunkName: "CartView" */ "../views/CartView.vue");
      const MyView = () =>
        import(/* webpackChunkName: "MyView" */ "../views/MyView.vue");
      const LoginView = () =>
        import(/* webpackChunkName: "LoginView" */ "../views/LoginView.vue");
      const routes = [
        {
          path: "/",
          redirect: "/IndexView",//让`/#/`可以跳转到`/#/IndexView`
          //component: IndexView,
        },
        {
          path: "*",//让`/#/未定义路径`可以跳转到`/#/IndexView`
          redirect: "IndexView",
        },
      
        {
          path: "/IndexView",
          name: "IndexView",
          component: IndexView,
        },
        {
          path: "/ClassifyView",
          name: "ClassifyView",
          component: ClassifyView,
        },
        {
          path: "/CartView",
          name: "CartView",
          component: CartView,
        },
        {
          path: "/MyView",
          name: "MyView",
          component: MyView,
        },
        {
          path: "/LoginView",
          name: "LoginView",
          component: LoginView,
        },
      ];
      
      const router = new VueRouter({
        routes,
      });
      
      export default router;
      
  3. 使用vant组件
    • 用[].forEach()
      // 1. 引入vue;
      import Vue from "vue";
      
      // 2. 引入vant的css样式
      import "vant/lib/index.css";
      
      // 3. 引入button组件,在组件中使用时是用`van-button`使用
      import { Button } from "vant";
      Vue.use(Button);
      
      // 更集中
      import { Tabbar, TabbarItem } from 'vant';
      let list01 = [Tabbar, TabbarItem]
      list01.forEach(item=>[
        Vue.use(item)
      ])
      // 等价于:分散的写法
      // import { Tabbar, TabbarItem } from 'vant';
      // Vue.use(Tabbar);
      // Vue.use(TabbarItem);
      
    • /src/components/FooterPage.vue
      <template>
        <div>
          <van-tabbar v-model="active" active-color="#1baeae" :route="true">
            <van-tabbar-item icon="home-o" to="/IndexView">首页</van-tabbar-item>
            <van-tabbar-item icon="search" dot to="/ClassifyView">
              <span>分类</span>
              <template #icon="props">
                <i class="iconfont icon-fenlei"></i>
              </template>
            </van-tabbar-item>
            <van-tabbar-item icon="shopping-cart-o" badge="5" to="/CartView">
              购物车
            </van-tabbar-item>
            <van-tabbar-item icon="user-o" badge="20" to="/MyView">
              我的
            </van-tabbar-item>
          </van-tabbar>
        </div>
      </template>
      <script>
      export default {
        data() {
          return {
            active: 0,
          };
        },
      };
      </script>
      
  4. 改Tabbar图标选中颜色样式
    • /src/components/FooterPage.vue
      <template>
        <div>
          <van-tabbar v-model="active" active-color="#1baeae"></van-tabbar>
        </div>
      </template>
      
  5. 用自定义图标
    • /src/components/FooterPage.vue

      <template>
        <div>
          <i class="iconfont icon-fenlei"></i>
        </div>
      </template>
      
      <style lang="less" scoped>
      @import url("../assets/icon.less");
      </style>
      
  6. App组件中使用,但一些页面不用Tabbar组件显示
    • /src/App.vue
      <template>
        <div id="app">
          <router-view />
          <FooterPage></FooterPage>
        </div>
      </template>
      <script>
      import FooterPage from "./components/FooterPage.vue";
      export default {
        components: {
          FooterPage,
        },
      };
      </script>
      
  7. 用路由的mate属性控制App中的Tabbar的显隐
    • /src/router/index.js
      const routes = [
        {
          path: "/",
          redirect: "/IndexView",//让`/#/`可以跳转到`/#/IndexView`
          //component: IndexView,
        },
        {
          path: "*",//让`/#/未定义路径`可以跳转到`/#/IndexView`
          redirect: "IndexView",
        },
      
        {
          path: "/IndexView",
          name: "IndexView",
          component: IndexView,
          meta: {
            isShowFooter: true,//在这个meta.isShowFooter为true的,显示App.vue中的导航栏。
          },
        },
        {
          path: "/ClassifyView",
          name: "ClassifyView",
          component: ClassifyView,
          meta: {
            isShowFooter: true,
          },
        },
        {
          path: "/CartView",
          name: "CartView",
          component: CartView,
          meta: {
            isShowFooter: true,
          },
        },
        {
          path: "/MyView",
          name: "MyView",
          component: MyView,
          meta: {
            isShowFooter: true,
          },
        },
        {
          path: "/LoginView",
          name: "LoginView",
          component: LoginView,
          // meta: {
          //   isShowFooter: false,//或不写;
          // },
        },
      ];
      
      const router = new VueRouter({
        routes,
      });
      
    • /src/App.vue
      <template>
        <div id="app">
          <router-view />
          <FooterPage v-show="flag"></FooterPage>
        </div>
      </template>
      <script>
      import FooterPage from "./components/FooterPage.vue";
      export default {
        data() {
          return {
            flag: true,
          };
        },
        watch: {
          $route: {
            handler(newValue) {
              console.log(`newValue-->`, newValue);
              this.flag = newValue?.meta?.isShowFooter || false;
            },
            immediate: true,
          },
        },
        components: {
          FooterPage,
        },
      };
      </script>
      
  8. 开启van-tabbar标签的路由模式,让van-tabbar自动随着路由路径的变化而切换当前选中的van-tabbar-item标签。
    • /src/components/FooterPage.vue
      <template>
        <div>
          <van-tabbar v-model="active" active-color="#1baeae" :route="true"></van-tabbar>
        </div>
      </template>
      
  9. 最终代码
    • /src/App.vue最终代码
      <template>
        <div id="app">
          <router-view />
          <FooterPage v-show="flag"></FooterPage>
        </div>
      </template>
      <script>
      import FooterPage from "./components/FooterPage.vue";
      export default {
        data() {
          return {
            flag: true,
          };
        },
        watch: {
          $route: {
            handler(newValue) {
              console.log(`newValue-->`, newValue);
              this.flag = newValue?.meta?.isShowFooter || false;//在这个this.$route.meta.isShowFooter为true的,显示App.vue中的导航栏。
            },
            immediate: true,
          },
        },
        components: {
          FooterPage,
        },
      };
      </script>
      
      <style lang="less" scoped>
      // #app {
      //   font-family: Avenir, Helvetica, Arial, sans-serif;
      //   -webkit-font-smoothing: antialiased;
      //   -moz-osx-font-smoothing: grayscale;
      //   text-align: center;
      //   color: #2c3e50;
      
      //   nav {
      //     padding: 30px;
      //     a {
      //       font-weight: bold;
      //       color: #2c3e50;
      //       &.router-link-exact-active {
      //         color: #42b983;
      //       }
      //     }
      //   }
      // }
      </style>
      
    • /src/router/index.js最终代码
      import Vue from "vue";
      import VueRouter from "vue-router";
      import IndexView from "../views/IndexView.vue";
      
      
      Vue.use(VueRouter);
      
      const ClassifyView = () =>
        import(/* webpackChunkName: "ClassifyView" */ "../views/ClassifyView.vue");
      const CartView = () =>
        import(/* webpackChunkName: "CartView" */ "../views/CartView.vue");
      const MyView = () =>
        import(/* webpackChunkName: "MyView" */ "../views/MyView.vue");
      const LoginView = () =>
        import(/* webpackChunkName: "LoginView" */ "../views/LoginView.vue");
      const routes = [
        {
          path: "/",
          redirect: "/IndexView",//让`/#/`可以跳转到`/#/IndexView`
          //component: IndexView,
        },
        {
          path: "*",//让`/#/未定义路径`可以跳转到`/#/IndexView`
          redirect: "IndexView",
        },
      
        {
          path: "/IndexView",
          name: "IndexView",
          component: IndexView,
          meta: {
            isShowFooter: true,//在这个meta.isShowFooter为true的,显示App.vue中的导航栏。
          },
        },
        {
          path: "/ClassifyView",
          name: "ClassifyView",
          component: ClassifyView,
          meta: {
            isShowFooter: true,
          },
        },
        {
          path: "/CartView",
          name: "CartView",
          component: CartView,
          meta: {
            isShowFooter: true,
          },
        },
        {
          path: "/MyView",
          name: "MyView",
          component: MyView,
          meta: {
            isShowFooter: true,
          },
        },
        {
          path: "/LoginView",
          name: "LoginView",
          component: LoginView,
          // meta: {
          //   isShowFooter: false,//或不写;
          // },
        },
      ];
      
      const router = new VueRouter({
        routes,
      });
      
      export default router;
      
    • /src/components/FooterPage.vue最终代码
      <template>
        <div>
          <van-tabbar v-model="active" active-color="#1baeae" :route="true">
            <van-tabbar-item icon="home-o" to="/IndexView">首页</van-tabbar-item>
            <van-tabbar-item icon="search" dot to="/ClassifyView">
              <span>分类</span>
              <template #icon>
                <i class="iconfont icon-fenlei"></i>
              </template>
            </van-tabbar-item>
            <van-tabbar-item icon="shopping-cart-o" badge="5" to="/CartView">
              购物车
            </van-tabbar-item>
            <van-tabbar-item icon="user-o" badge="20" to="/MyView">
              我的
            </van-tabbar-item>
          </van-tabbar>
        </div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            active: 0,
          };
        },
      };
      </script>
      
      <style lang="less" scoped>
      @import url("../assets/icon.less");
      </style>
      

自定义图标

  • /src/components/FooterPage.vue

    <template>
      <div>
        <i class="iconfont icon-fenlei"></i>
      </div>
    </template>
    
    <style lang="less" scoped>
    @import url("../assets/icon.less");
    </style>
    
  • /src/assets/icon.less

    @font-face {
      font-family: "iconfont";
      /* Project id 3141501 */
      src: url('//at.alicdn.com/t/font_3141501_ftrvn4vtda5.woff2?t=1642133344053') format('woff2'),
        url('//at.alicdn.com/t/font_3141501_ftrvn4vtda5.woff?t=1642133344053') format('woff'),
        url('//at.alicdn.com/t/font_3141501_ftrvn4vtda5.ttf?t=1642133344053') format('truetype');
    }
    
    .iconfont {
      font-family: "iconfont" !important;
      font-size: 16px;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      font-size:22px;
    }
    
    .icon-gouwucheman:before {
      content: "\e600";
    }
    
    .icon-user:before {
      content: "\e63c";
    }
    
    .icon-fenlei:before {
      content: "\e612";
    }
    

滚动修改样式

  1. 样式一般用class代替,用一个变量来控制是否添加一个类名。

    <template>
      <div class="home-root">
        <div :class="['the-header', flag ? 'is-active' : '']">新峰商城</div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          flag: false,
        };
      },
    };
    </script>
    
    <style lang="less" scoped>
    .home-root {
      .the-header {
        opacity: 0.2;
        &.is-active {
          opacity: 1;
        }
      }
    }
    </style>
    
  2. 一般使用DOMElement.addEventListener()与DOMElement.removeEventListener()操作事件的绑定与解绑。

    • 主要原因是DOM2级事件可以绑定多个。
      • 用DOM0级,只能绑定一个,可能会对其它组件中绑定的事件造成影响。
    • 一般函数方法在methods中进行定义,允许在vue组件的一些生命周期中可以调用到。
      • methods中的方法,可以被DOMElement.addEventListener()与DOMElement.removeEventListener()操作事件的绑定与解绑。
        • 在生命周期中定义的方法,一般很难可以被重复调用。
    • 一般在created()为window之类的全局变量绑定一个方法。
      • 如果涉及到DOM,可以在mounted()中绑定。
    • 在destroyed()为绑定的事件进行解绑,防止内存一直占用,DOM删除不了,造成内存泄露。
    • 事件绑定与解绑说明
      • DOM0级事件绑定与解绑

        • DOM0级事件绑定方式所绑定的事件,可以直接在生命周期中定义

          <script>
          export default {
            data() {
              return {
                flag: false,
              };
            },
            created() {
              console.log(`window-->`, window);
          
              window.onscroll = () {
                let html = document.documentElement || document.body;
                console.log(`111-->`, 111);
          
                if (html.scrollTop > 100) {
                  this.flag = true;
                } else {
                  this.flag = false;
                }
              };
            },
            destroyed() {
              window.onscroll = null
            },
          };
          </script>
          
      • DOM2级事件的绑定与解绑

        • DOM0级事件绑定方式所绑定的事件,一般不能在生命周期中定义。而要在mothods中进行定义。

          • 以便在绑定与解绑时,都能访问到同一个事件。
          <script>
          export default {
            data() {
              return {
                flag: false,
              };
            },
            created() {
              console.log(`window-->`, window);
              //创建组件的时候向事件池中添加方法--DOM已经存在
              window.addEventListener("scroll", this.showHeader);
            },
            methods: {
              showHeader() {
                let html = document.documentElement || document.body;
                console.log(`111-->`, 111);
          
                if (html.scrollTop > 100) {
                  this.flag = true;
                } else {
                  this.flag = false;
                }
              },
            },
            destroyed() {
              window.removeEventListener("scroll", this.showHeader);
            },
          };
          </script>
          
  • 例子完整版

    <template>
      <div class="home-root">
        <div :class="['the-header', flag ? 'is-active' : '']">新峰商城</div>
        <div class="the-body">
          <h1>11111</h1>
          <h1>11111</h1>
          <h1>11111</h1>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          flag: false,
        };
      },
      created() {
        console.log(`window-->`, window);
    
        // window.onscroll = () => {};
        //创建组件的时候向事件池中添加方法--DOM已经存在
        window.addEventListener("scroll", this.showHeader);
      },
      methods: {
        showHeader() {
          let html = document.documentElement || document.body;
          console.log(`111-->`, 111);
    
          if (html.scrollTop > 100) {
            this.flag = true;
          } else {
            this.flag = false;
          }
        },
      },
    
      destroyed() {
        window.removeEventListener("scroll", this.showHeader);
      },
    };
    </script>
    
    <style lang="less" scoped>
    .home-root {
      .the-header {
        width: 100%;
        height: 50px;
        background-color: #1baeae;
        text-align: center;
        color: #fff;
        font-size: 20px;
        line-height: 50px;
        // position: fixed;
        position: sticky;
        top: 0;
        left: 0;
        opacity: 0.2;
        &.is-active {
          opacity: 1;
        }
      }
      .the-body {
        height: 2000px;
      }
    }
    </style>
    

进阶参考

  1. 新蜂App–项目预览
  2. vant框架–vant2023最新框架-vant4适用于vue3
  3. vant框架–vant3适用于vue2
  4. vue可以用框架有哪些?-vue框架–总结主要使用方向
### 回答1: 这个问题我可以回答。CVE-2019-16759漏洞是LibreOffice软件中的一个漏洞,攻击者可以利用该漏洞通过特制的ODF文档文件来执行任意代码。该漏洞的原理是由于LibreOffice在处理ODF文档时,没有正确地验证文档中的宏代码,导致攻击者可以通过恶意代码来执行任意命令。该漏洞已经被修复,建议用户及时更新软件版本。 ### 回答2: CVE-2019-16759是一个存在于某个软件或系统中的安全漏洞。该漏洞具体的原理是指某个软件或系统的设计或实现过程中存在的缺陷,使得攻击者可以利用这个缺陷来执行恶意操作。 对于CVE-2019-16759漏洞而言,具体的原理可以分为以下几个方面进行解析。 首先,CVE-2019-16759漏洞可能涉及到软件或系统中的某个输入验证机制存在问题。在正常的运行过程中,软件或系统需要接受用户的输入,并对输入进行验证,以确保输入的合法性。然而,由于软件或系统在输入验证方面存在缺陷,攻击者可以发送恶意输入来绕过验证过程,从而导致安全漏洞的产生。 其次,CVE-2019-16759漏洞可能与某个安全控制机制的问题有关。安全控制机制是指软件或系统中用于限制用户权限和保护敏感数据的一系列规则和方法。然而,由于软件或系统在安全控制方面存在漏洞,攻击者可以绕过控制机制,获取未经授权的访问权限或窃取敏感数据。 第三,CVE-2019-16759漏洞可能涉及到软件或系统中的某个错误处理机制存在问题。在软件或系统的运行过程中,会出现各种错误和异常情况,需要有相应的处理机制来处理这些问题。然而,由于软件或系统在错误处理方面存在缺陷,攻击者可以利用这些错误和异常情况来执行恶意操作,进而导致安全漏洞的产生。 总之,CVE-2019-16759漏洞的原理可以归结为输入验证机制的问题、安全控制机制的问题和错误处理机制的问题等方面。攻击者可以利用这些缺陷来绕过验证、获取未经授权的权限或窃取敏感数据,从而导致软件或系统的安全性受到威胁。为了解决该漏洞,开发者或维护者需要修复相关的软件或系统,增强输入验证、安全控制和错误处理等方面的能力,确保软件或系统的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值