超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)

前言

  • 此文章接前面笔记内容,主要内容是vue-cli、vue-router
  • 前面笔记
    • 超详细!Vue-coderwhy个人学习笔记(一)(Day1-Day2)
    • 超详细!Vue-coderwhy个人学习笔记(二)(Day3)
    • 超详细!Vue-coderwhy个人学习笔记(三)(Day4-Day5)


七 、Vue CLI详解

(一)、Vue CLI

1.什么是Vue CLI

  • 如果你只是简单写几个Vue的Demo程序, 那么你不需要Vue CLI.
  • 如果你在开发大型项目, 那么你需要, 并且必然需要使用Vue CLI
    • 使用Vue.js开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。
    • 如果每个项目都要手动完成这些工作,那无疑效率比较低效,所以通常我们会使用一些脚手架工具来帮助完成这些事情。
  • CLI是什么意思?
    • CLI是Command-Line Interface, 翻译为命令行界面, 但是俗称脚手架.
    • Vue CLI是一个官方发布 vue.js 项目脚手架
    • 使用 vue-cli 可以快速搭建Vue开发环境以及对应的webpack配置. 
  • 脚手架长什么样子?

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第1张图片

2.Vue CLI使用前提 - Node

  • 安装NodeJS

    • 可以直接在官方网站中下载安装.

    • 网址: http://nodejs.cn/download/ 

  • 检测安装的版本
    • 默认情况下自动安装Node和NPM
    • Node环境要求8.9以上或者更高版本

  • 什么是NPM呢?
    • NPM的全称是Node Package Manager
    • 是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准。
    • 后续我们会经常使用NPM来安装一些开发过程中依赖包. 
  • cnpm安装
    • 由于国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像。
    • 你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:
    • npm install -g cnpm --registry=https://registry.npm.taobao.org
    • 这样就可以使用 cnpm 命令来安装模块了:

      cnpm install [name]
      

3.Vue CLI使用前提 - Webpack

  • Vue.js官方脚手架工具就使用了webpack模板

    • 对所有的资源会压缩等优化操作

    • 它在开发过程中提供了一套完整的功能,能够使得我们开发过程中变得高效。

  • Webpack的全局安装 
npm install webpack -g

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第2张图片

4.Vue CLI的使用

  • 安装Vue脚手架

    • npm install -g @vue/cli
  • 注意:上面安装的是Vue CLI3的版本,如果需要想按照Vue CLI2的方式初始化项目时不可以的。

 超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第3张图片

  •  Vue CLI2初始化项目
vue init webpack my-project
  • Vue CLI3初始化项目
vue create my-project

(二)、Vue CLI2

 1.(掌握)Vue CLI2详解--Vue CLI初始化项目过程

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第4张图片

 2.(理解)目录结构详解

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第5张图片

3.(理解)Runtime-Compiler和Runtime-only的区别

  • 简单总结
    • 如果在之后的开发中,你依然使用template,就需要选择Runtime-Compiler
    • 如果你之后的开发中,使用的是.vue文件夹开发,那么可以选择Runtime-only 

4.render和template

  • Runtime-CompilerRuntime-only

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第6张图片

  • 为什么存在这样的差异呢?
    • 我们需要先理解Vue应用程序是如何运行起来的。
    • Vue中的模板如何最终渲染成真实DOM。
    • 我们来看下面的一幅图。 

5.Vue程序运行过程

 超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第7张图片

  •  总结
    • Runtime-Compiler:

      • template -> ast -> render -> vdom -> 真实DOM

    • Runtime-only:(1.性能更高 2.下面的代码量更少)

    • render -> vdom -> UI

6.render函数的使用

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第8张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第9张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第10张图片

 main.js代码:

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false // 消息提示的环境配置,设置为开发环境或者生产环境

/* eslint-disable no-new */
/* 

// runtime-compiler
new Vue({
  el: '#app',
  components: { App },
  template: '',
})

*/


// const cpn = { // 组件
//   template: '
{{message}}
', // data() { // return { // message: '我是组件message' // } // } // } // 也可以用下面这个方案 runtime-only new Vue({ el: '#app', render: function (createElement) { // createElement是一个函数 // 1.使用方式一: createElement('标签', {标签的属性}, ['内容']) // 1.1 基本使用 // return createElement('h2', { // class: 'box' // }, // ['Hello World']) // 1.2 嵌套render函数 // return createElement('h2', { // class: 'box' // }, // ['Hello World', createElement('button', ['按钮'])]) // 2.传入组件对象: // return createElement(cpn) return createElement(App) } }) // runtime-compiler(v1) // template -> ast -> render -> vdom -> UI // runtime-only(v2)(1.性能更高 2.下面的代码量更少) // render -> vdom -> UI
  • 那么.vue文件中的template是由谁处理的了?

    • 是由vue-template-compiler

7.npm run build

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第11张图片

8.npm run dev 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第12张图片

 9.修改配置:webpack.base.conf.js起别名

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第13张图片


(三)、Vue CLI3

1.认识Vue CLI3

  • vue-cli 3 与 2 版本有很大区别

    • vue-cli 3 是基于 webpack 4 打造,vue-cli 2 还是 webapck 3

    • vue-cli 3 的设计原则是“0配置”,移除的配置文件根目录下的,build和config等目录

    • vue-cli 3 提供了 vue ui 命令,提供了可视化配置,更加人性化

    • 移除了static文件夹,新增了public文件夹,并且index.html移动到public中 

 2.Vue CLI3

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第14张图片

3.目录结构详解

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第15张图片

 4.配置去哪里了?

  • UI方面的配置
    • 启动配置服务器:vue ui

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第16张图片

  • 一大堆配置文件去哪里了?

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第17张图片

 5.自定义配置:起别名

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第18张图片


 (四)、(掌握)箭头函数

1.箭头函数的基本使用

  • 箭头函数: 也是一种定义函数的方式

  • 定义函数的方式

function
  const aaa = function () {

  }

  // 2.对象字面量中定义函数
  const obj = {
    bbb() {

    }
  }

  // 3.ES6中的箭头函数
  // const ccc = (参数列表) => {
  //
  // }
  const ccc = () => {

  }

 2.箭头函数参数和返回值


  // 1.参数问题:
  // 1.1.放入两个参数
  const sum = (num1, num2) => {
    return num1 + num2
  }

  // 1.2.放入一个参数
  const power = num => {
    return num * num
  }

  // 2.函数中
  // 2.1.函数代码块中有多行代码时
  const test = () => {
    // 1.打印Hello World
    console.log('Hello World');

    // 2.打印Hello Vuejs
    console.log('Hello Vuejs');
  }

  // 2.2.函数代码块中只有一行代码
  // const mul = (num1, num2) => {
  //   return num1 + num2
  // }
  const mul = (num1, num2) => num1 * num2
  console.log(mul(20, 30));

  // const demo = () => {
  //   console.log('Hello Demo');
  // }
  const demo = () => console.log('Hello Demo')
  console.log(demo());

 3.箭头函数中this的使用

  • 什么时候使用箭头函数?
    • 当把一个函数作为参数传到另外一个函数

setTimeout(function () {
    console.log(this);
  }, 1000)
  
  setTimeout(() => {
    console.log(this);
  }, 1000)
  • 问题: 箭头函数中的this是如何查找的了?

  • 答案: 向外层作用域中, 一层层查找this, 直到有this的定义.

     
      const obj = {
          aaa() {
            setTimeout(function () {
              console.log(this); // window
            })
    
            setTimeout(() => {
              console.log(this); // obj对象
            })
          }
        }
    
        obj.aaa()
    
    
        const obj = {
          aaa() {
            setTimeout(function () {
              setTimeout(function () {
                console.log(this); // window
              })
    
              setTimeout(() => {
                console.log(this); // window
              })
            })
    
            setTimeout(() => {
              setTimeout(function () {
                console.log(this); // window
              })
    
              setTimeout(() => {
                console.log(this); // obj
              })
            })
          }
        }
    
        obj.aaa()


八、vue-router详解

(一)、内容概述

  • 认识路由
  • vue-router基本使用
  • vue-router嵌套路由
  • vue-router参数传递
  • vue-router导航守卫
  • keep-alive

(二)、(理解)认识路由

 1.什么是路由?

  • 说起路由你想起了什么?
    • 路由是一个网络工程里面的术语。
    • 路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动. --- 维基百科
  • 额, 啥玩意? 没听懂
    • 在生活中, 我们有没有听说过路由的概念呢? 当然了, 路由器嘛.
    • 路由器是做什么的? 你有想过吗?
    • 路由器提供了两种机制: 路由和转送.
      • 路由是决定数据包从来源目的地的路径.
      • 转送将输入端的数据转移到合适的输出端.
    • 路由中有一个非常重要的概念叫路由表.
      • 路由表本质上就是一个映射表, 决定了数据包的指向.

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第19张图片

2.后端路由阶段

  • 早期的网站开发整个HTML页面是由服务器来渲染的.

    • 服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示. 

  • 但是, 一个网站, 这么多页面服务器如何处理呢?
    • 一个页面有自己对应的网址, 也就是URL.
    • URL会发送到服务器, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller进行处理.
    • Controller进行各种处理, 最终生成HTML或者数据, 返回给前端.
    • 这就完成了一个IO操作. 
  • 上面的这种操作, 就是后端路由.
    • 当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户顿.
    • 这种情况下渲染好的页面, 不需要单独加载任何的js和css, 可以直接交给浏览器展示, 这样也有利于SEO的优化. 
  • 后端路由的缺点:
    • 一种情况是整个页面的模块由后端人员来编写和维护的.
    • 另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码.
    • 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情.

3.前端路由阶段

  • 前后端分离阶段:

    • 随着Ajax的出现, 有了前后端分离的开发模式.

    • 后端只提供API来返回数据, 前端通过Ajax获取数据, 并且可以通过JavaScript将数据渲染到页面中.

    • 这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上.

    • 并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API即可.

    • 目前很多的网站依然采用这种模式开发. 

  • 单页面富应用阶段:
    • 其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由.
    • 也就是前端来维护一套路由规则. 
  • 前端路由的核心是什么呢?
    • 改变URL,但是页面不进行整体的刷新。
    • 如何实现呢? 

(三)、(掌握)前端路由的规则

1.URL的hash

  • URL的hash

    • URL的hash也就是锚点(#), 本质上是改变window.location的href属性.

    • 我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新 

 超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第20张图片

2.HTML5的history模式:pushState

  • history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面.

  • history.pushState() 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第21张图片

3.HTML5的history模式:replaceState 

  •  history.replaceState()

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第22张图片

 4.HTML5的history模式:go

  • history.go()

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第23张图片

5.补充说明

  • 上面只演示了三个方法
  • 因为 history.back() 等价于 history.go(-1)
  • history.forward() 则等价于 history.go(1)
  • 这三个接口等同于浏览器界面的前进后退。 


(四)、(掌握)vue-router基础

1.认识vue-router

  • 目前前端流行的三大框架, 都有自己的路由实现:
    • Angular的ngRouter
    • React的ReactRouter
    • Vue的vue-router
  • 当然, 我们的重点是vue-router
    •  vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。
    • 我们可以访问其官方网站对其进行学习: https://router.vuejs.org/zh/
  • vue-router是基于路由和组件的
    • 路由用于设定访问路径, 将路径和组件映射起来.
    • 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换.

2.安装和使用vue-router

  • 因为我们已经学习了webpack, 后续开发中我们主要是通过工程化的方式进行开发的.

    • 所以在后续, 我们直接使用npm来安装路由即可.

    • 步骤一: 安装vue-router 

      npm install vue-router --save

    • 步骤二: 在模块化工程中使用它(因为是一个插件, 所以可以通过Vue.use()来安装路由功能) 

      • 第一步:导入路由对象,并且调用 Vue.use(VueRouter)

        import Vue from 'vue' 
        import VueRouter from 'vue-router' 
        
        Vue.use(VueRouter)
        
      • 第二步:创建路由实例,并且传入路由映射配置超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第24张图片

      • 第三步:在Vue实例挂载创建的路由实例超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第25张图片

  •  使用vue-router的步骤:
    • 第一步: 创建路由组件超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第26张图片
    • 第二步: 配置路由映射: 组件和路径映射关系超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第27张图片
    • 第三步: 使用路由: 通过

    超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第28张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第29张图片


(五)、(掌握)细节处理

1.路由的默认路径

  • 我们这里还有一个不太好的实现:

    • 默认情况下, 进入网站的首页, 我们希望渲染首页的内容.

    • 但是我们的实现中, 默认没有显示首页组件, 必须让用户点击才可以. 

  • 如何可以让路径默认跳到到首页, 并且渲染首页组件呢?
    • 非常简单, 我们只需要配置多配置一个映射就可以了. 

 超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第30张图片

  • 配置解析:
    • 我们在routes中又配置了一个映射.
    • path配置的是根路径: /
    • redirect是重定向, 也就是我们将根路径重定向到/home的路径下, 这样就可以得到我们想要的结果了. 

2.HTML5的History模式

  • 我们前面说过改变路径的方式有两种:

    • URL的hash

    • HTML5的history

    • 默认情况下, 路径的改变使用的URL的hash.

  • 如果希望使用HTML5的history模式, 非常简单, 进行如下配置即可: 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第31张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第32张图片

  • 补充:history模式的url不会有#符号 

3.router-link补充

 4.修改linkActiveClass

  • 该class具体的名称也可以通过router实例的属性进行修改

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第33张图片

  • exact-active-class 类似于active-class,
    • 只是在精准匹配下才会出现的class.
    • 后面看到嵌套路由时, 我们再看下这个属性. 

 超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第34张图片

5.路由代码跳转

  •  有时候, 页面的跳转可能需要执行对应的JavaScript代码,

  • 这个时候, 就可以使用第二种跳转方式了 比如, 我们将代码修改如下:

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第35张图片

 阶段代码

  • router里的index.js 

// 配置路由相关的信息
// 导入路由对象
import VueRouter from 'vue-router'
import Vue from 'vue'

import Home from '../components/Home'
import About from '../components/About'

// 1.通过Vue.use(插件), 安装插件
Vue.use(VueRouter)

// 2.创建VueRouter对象
const routes = [
  {
    path: '',
    // redirect重定向
    redirect: '/home'
  },
  {
    path: '/home',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]
// 创建路由实例,并且传入路由映射配置
const router = new VueRouter({
  // 配置路由和组件之间的应用关系
  routes,
  mode: 'history',
  linkActiveClass: 'active'
})
// 3.将router对象传入到Vue实例
export default router

 App.vue






main.js

import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  // 在Vue实例中挂载创建的路由实例
  router,
  render: h => h(App)
})

6.动态路由

  • 在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面时,希望是如下的路径:

    • /user/aaaa或/user/bbbb

    • 除了有前面的/user之外,后面还跟上了用户的ID

    • 这种path和Component的匹配关系,我们称之为动态路由(也是路由传递数据的一种方式)。 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第36张图片

 代码:

  •  创建一个User.vue组件





  • router文件夹下index.js
...
const routes = [
    ...
    {
        path:'/user/:id',
        component:User
    }
]
const router = new VueRouter({
    routes,
    mode:'history',
    linkActiveClass:'active'
})
export default router
  • App.vue 




(六)、(掌握)路由懒加载

1.认识路由的懒加载

  • 官方给出了解释:
    • 当打包构建应用时,Javascript 包会变得非常大,影响页面加载。
    • 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了
  • 官方在说什么呢?
    • 首先, 我们知道路由中通常会定义很多不同的页面.
    • 这个页面最后被打包在哪里呢? 一般情况下, 是放在一个js文件中.
    • 但是, 页面这么多放在一个js文件中, 必然会造成这个页面非常的大.
    • 如果我们一次性从服务器请求下来这个页面, 可能需要花费一定的时间, 甚至用户的电脑上还出现了短暂空白的情况.
    • 如何避免这种情况呢? 使用路由懒加载就可以了.
  • 路由懒加载做了什么?
    • 路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块.
    • 只有在这个路由被访问到的时候, 才加载对应的组件

2.路由懒加载的效果

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第37张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第38张图片

 懒加载打包

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第39张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第40张图片

3.懒加载的方式

  • 方式一: 结合Vue的异步组件和Webpack的代码分析. 

const Home = resolve => {
    require.ensure(['../components/Home.vue'], () => {
        resolve(require('../components/Home.vue'))
    })
};
  •  方式二: AMD写法
const About = resolve => require(['../components/About.vue'], resolve);
  • 方式三: 在ES6中, 我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割.
const Home = () => import('../components/Home.vue')

(七)、(掌握)路由嵌套

1.认识嵌套路由

  • 嵌套路由是一个很常见的功能
    • 比如在home页面中, 我们希望通过/home/news和/home/message访问一些内容.
    • 一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件.
  • 路径和组件的关系如下:

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第41张图片

  • 实现嵌套路由有两个步骤:
    • 创建对应的子组件, 并且在路由映射中配置对应的子路由.
    • 在组件内部使用标签. 

2.嵌套路由实现

  • 定义两个组件: 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第42张图片

 超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第43张图片

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第44张图片

3.嵌套默认路径

  • 嵌套路由也可以配置默认的路径, 配置方式如下: 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第45张图片


(八)、(掌握)传递参数

 1.准备工作

  • 为了演示传递参数, 我们这里再创建一个组件, 并且将其配置好
    • 第一步: 创建新的组件Profile.vue超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第46张图片
    • 第二步: 配置路由映射超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第47张图片
    • 第三步: 添加跳转的超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第48张图片

2.传递参数的方式

  •  传递参数主要有两种类型:

    • paramsquery

  • params的类型:
    • 配置路由格式: /router/:id
    • 传递的方式: 在path后面跟上对应的值
    • 传递后形成的路径: /router/123, /router/abc
  •  query的类型:
    • 配置路由格式: /router, 也就是普通配置
    • 传递的方式: 对象中使用query的key作为传递方式
    • 传递后形成的路径: /router?id=123, /router?id=abc
  • 如何使用它们呢? 也有两种方式: 的方式和JavaScript代码方式 

3.传递参数方式一:

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第49张图片

 4.传递参数方式二: JavaScript代码

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第50张图片

5.获取参数 

  • 获取参数通过$route对象获取的.
    • 在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,并且当路由切换时,路由对象会被更新。 
  • 通过$route获取传递的信息如下: 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第51张图片

  • 推荐文章
    • vue-router如何传递参数(三种方法)
    • vue-router传递参数的几种方式 

6.(理解)$route和$router是有区别的

  • $route和$router是有区别的

    • $router为VueRouter实例,想要导航到不同URL,则使用$router.push方法

    • $route为当前router跳转对象里面可以获取name、path、query、params等 

超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第52张图片

 7.代码

  • profile.vue





  • App.vue






(九)、导航守卫

“导航”表示路由正在发生改变。

正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

 1.为什么使用导航守卫?

  • 我们来考虑一个需求: 在一个SPA应用中, 如何改变网页的标题呢?
    • 网页标题是通过来显示的, 但是SPA只有一个固定的HTML, 切换不同的页面时, 标题并不会改变.</li> <li>但是我们可以通过JavaScript来修改<title>的内容.window.document.title = '新的标题'.</li> <li>那么在Vue项目中, 在哪里修改? 什么时候修改比较合适呢?</li> </ul></li> <li>普通的修改方式: <ul> <li>我们比较容易想到的修改标题的位置是每一个路由对应的组件.vue文件中.</li> <li>通过mounted声明周期函数, 执行对应的代码进行修改即可. <pre><code class="language-javascript">// Home.vue mounted() { console.log('home mounted'); document.title='首页' }, // About.vue mounted() { console.log('home mounted'); document.title='关于' }, // ... // 其他页面也是这样写</code></pre> <p></p> </li> <li>但是当页面比较多时, 这种方式不容易维护(因为需要在多个页面执行类似的代码). </li> </ul></li> <li>有没有更好的办法呢? 使用导航守卫即可.</li> <li>什么是导航守卫? <ul> <li>vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.</li> <li>vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发. </li> </ul></li> </ul> <h3>2.(掌握)导航守卫使用</h3> <ul> <li> <p><span style="color:#0d0016;">我们可以利用beforeEach来完成标题的修改. </span></p> <ul> <li> <p><span style="color:#0d0016;">首先, 我们可以在钩子当中定义一些标题, 可以利用meta来定义 </span></p> </li> <li> <p><span style="color:#0d0016;">其次, 利用导航守卫,修改我们的标题. </span></p> </li> </ul></li> </ul> <p><a href="http://img.e-com-net.com/image/info8/457f562f46e24dc59d54b5a6d985a4dd.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第53张图片" height="510" src="http://img.e-com-net.com/image/info8/457f562f46e24dc59d54b5a6d985a4dd.jpg" width="650" style="border:1px solid black;"></a></p> <p> <a href="http://img.e-com-net.com/image/info8/06029fee40644f3da8457064efe7fcf6.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第54张图片" height="366" src="http://img.e-com-net.com/image/info8/06029fee40644f3da8457064efe7fcf6.jpg" width="650" style="border:1px solid black;"></a></p> <ul> <li><strong>导航钩子的三个参数解析:</strong> <ul> <li>to: 即将要进入的目标的路由对象.</li> <li>from: 当前导航即将要离开的路由对象.</li> <li>next: 调用该方法后, 才能进入下一个钩子. </li> </ul></li> <li> router下的<span style="color:#be191c;"><span style="background-color:#fef2f0;">index.js</span></span></li> </ul> <pre><code class="language-javascript">// ... const routes = [ { path: '', // redirect重定向 redirect: '/home' }, { path: '/home', component: Home, // meta元数据(描述数据的数据) meta: { title: '首页' }, // 嵌套路由 children: [ // { // path: '', // redirect: 'news' // }, { path: 'news',// 没有斜杠 / component: HomeNews }, { path: 'message', component: HomeMessage } ] }, { path: '/about', component: About, meta: { title: '关于' }, }, { path: '/user/:id', component: User, meta: { title: '用户' }, }, { path: '/profile', component: Profile, meta: { title: '档案' }, } ] const router = new VueRouter({ // ... }) // 1. 全局导航守卫 // 1.1 前置守卫(guard) 路由跳转之前 // beforeEach()注册一个全局前置守卫,本身是一个函数,又传入一个函数guard,有三个参数 router.beforeEach((to, from, next) => { // 从from跳转到to // // to 和 from都是route对象 // document.title = to.meta.title // 上面这样写的话如果有嵌套路由的话是undefined,要使用matched(匹配)获取 document.title = to.matched[0].meta.title console.log(to);// 到哪个页面去? console.log(from);// 从哪个页面来? // 调用该方法后,才能进入下一个钩子 // 如果是后置钩子,也就是afterEach,不需要主动调用next()函数 // 这里其实可以判断用户登陆权限之类的,拦截访问 ,权限不符调用next(false)拦截 next() }) // 1.2 后置钩子(hook) 不需要主动调用next()函数 router.afterEach((to, from) => { console.log('----'); }) // 钩子->回调 export default router </code></pre> <ul> <li>推荐文章 <ul> <li>vue 路由守卫(导航守卫)及其具体使用</li> <li>vue-router钩子函数实现路由守卫</li> </ul></li> </ul> <h3>3.(理解)导航守卫补充</h3> <ul> <li>补充一:如果是后置钩子, 也就是afterEach, 不需要主动调用next()函数.</li> <li>补充二: 上面我们使用的导航守卫, 被称之为<strong>全局守卫</strong>(beforeEach、afterEach)<strong>.</strong> <ul> <li>路由独享的守卫(beforeEnter).</li> <li>组件内的守卫(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave). </li> </ul></li> <li>更多内容, 可以查看官网进行学习: <ul> <li>导航守卫 | Vue Router</li> </ul></li> <li><strong>路由独享的守卫</strong>(beforeEnter)</li> </ul> <pre><code class="language-javascript">const routes = [ // ... { path: '/about', component: About, meta: { title: '关于' }, // 2.路由独享的守卫 beforeEnter: (to, from, next) => { console.log('about beforeEnter'); next() } }, // ... ] const router = new VueRouter({ //... })</code></pre> <ul> <li><strong>组件内的守卫</strong>(beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave)</li> </ul> <pre><code class="language-html">// Home.vue <template> <div> <h2>我是首页</h2> <p>我是首页内容, 哈哈哈</p> <router-link to="/home/news">新闻</router-link> <router-link to="/home/message">消息</router-link> <router-view></router-view> <h2>{{message}}</h2> </div> </template> <script> export default { name: "Home", data() { return { name: "yyy", }; }, beforeRouteEnter(to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 // console.log(to); // console.log(from); console.log(this); // undefined next((vm) => { // 通过传一个回调给 next来访问组件实例 console.log(vm.name); }); }, beforeRouteUpdate(to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` console.log("beforeRouteUpdate"); next(); }, beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` console.log(this.$route.path); next(); }, }; </script> <style scoped> </style> </code></pre> <p></p> <hr> <h2>(十)、(掌握)keep-alive</h2> <h3>keep-alive遇见vue-router</h3> <ul> <li>keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。 <ul> <li>它们有两个非常重要的属性:</li> <li><strong>include</strong> - 字符串或正则表达,只有匹配的组件会被缓存</li> <li><strong>exclude</strong> - 字符串或正则表达式,任何匹配的组件都不会被缓存 </li> </ul></li> <li>router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存: </li> </ul> <p><a href="http://img.e-com-net.com/image/info8/ddbf79a687dc4c5d8c415887393e9118.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第55张图片" height="116" src="http://img.e-com-net.com/image/info8/ddbf79a687dc4c5d8c415887393e9118.jpg" width="650" style="border:1px solid black;"></a></p> <ul> <li> 通过create声明周期函数来验证</li> </ul> <p><span style="color:#be191c;"><span style="background-color:#fef2f0;"> App.vue</span></span></p> <pre><code class="language-html"><template> <div id="app"> <!-- 导航守卫 keep-alive --> <router-link to="/home">首页</router-link> <router-link to="/about">关于</router-link> <!-- 在vue中我们可以使用keepalive来进行组件缓存 --> <keep-alive exclude="Profile,User"> <router-view /> </keep-alive> </div> </template> </code></pre> <p><span style="color:#be191c;"><span style="background-color:#fef2f0;"> Home.vue</span></span></p> <pre><code class="language-html"><template> <div> <h2>我是首页</h2> <p>我是首页内容, 哈哈哈</p> <router-link to="/home/news">新闻</router-link> <router-link to="/home/message">消息</router-link> <router-view></router-view> <h2>{{ message }}</h2> </div> </template> <script> export default { name: "Home", data() { return { message: "你好啊", path: "/home/news", }; }, created() { console.log("home created"); }, mounted() { console.log("home mounted"); // document.title='首页' }, destroyed() { console.log("home destroyed"); }, // 这两个函数, 只有该组件被保持了状态使用了keep-alive时, 才是有效的 activated() { // 活跃状态 this.$router.push(this.path); console.log("activated"); }, deactivated() { console.log("deactivated"); }, // 离开当前路由页面时调用 beforeRouteLeave(to, from, next) { // 首页中使用path属性记录离开时的路径,在beforeRouteLeave中记录 console.log(this.$route.path); this.path = this.$route.path; next(); }, }; </script> <style scoped> </style> </code></pre> <p> <span style="color:#be191c;"><span style="background-color:#fef2f0;"> Profile.vue</span></span></p> <pre><code class="language-html"> <script> export default { name: "Profile", created() { console.log('Profile created'); }, destroyed() { console.log('Profile destroyed'); } } </script></code></pre> <p><span style="color:#be191c;"><span style="background-color:#fef2f0;">User.vue</span></span></p> <pre><code class="language-html"><script> export default { name: "User", created() { console.log('User created'); }, destroyed() { console.log('User destroyed'); }, } </script> </code></pre> <hr> <h2>(十一)、(掌握)TabBar练习</h2> <h3>1.TabBar实现思路</h3> <p><a href="http://img.e-com-net.com/image/info8/b18ee90d6808448384b8dbb113e44eaf.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第56张图片" height="672" src="http://img.e-com-net.com/image/info8/b18ee90d6808448384b8dbb113e44eaf.jpg" width="384" style="border:1px solid black;"></a></p> <ul> <li>1. 如果在下方有一个单独的TabBar组件,你如何封装 <ul> <li>自定义TabBar组件,在APP中使用</li> <li>让TabBar出于底部,并且设置相关的样式</li> </ul></li> <li>2.TabBar中显示的内容由外界决定 <ul> <li>定义插槽</li> <li>flex布局平分TabBar</li> </ul></li> <li>3.自定义TabBarItem,可以传入 图片和文字 <ul> <li>定义TabBarItem,并且定义两个插槽:图片、文字。</li> <li>给两个插槽外层包装div,用于设置样式。</li> <li>填充插槽,实现底部TabBar的效果 </li> </ul></li> <li>4.传入 高亮图片 <ul> <li>定义另外一个插槽,插入active-icon的数据</li> <li>定义一个变量isActive,通过v-show来决定是否显示对应的icon</li> </ul></li> <li>5.TabBarItem绑定路由数据 <ul> <li>安装路由:npm install vue-router —save</li> <li>完成router/index.js的内容,以及创建对应的组件</li> <li>main.js中注册router</li> <li>APP中加入<router-view>组件</li> </ul></li> <li>6.点击item跳转到对应路由,并且动态决定isActive <ul> <li>监听item的点击,通过this.$router.replace()替换路由路径</li> <li>通过this.$route.path.indexOf(this.link) !== -1来判断是否是active</li> </ul></li> <li>7.动态计算active样式 封装新的计算属性:this.isActive ? {'color': 'red'} : {} </li> </ul> <h3>2.代码实现 </h3> <p><a href="http://img.e-com-net.com/image/info8/bb513fe038bd42dbae6a7a6fcc28f3c5.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第57张图片" height="718" src="http://img.e-com-net.com/image/info8/bb513fe038bd42dbae6a7a6fcc28f3c5.jpg" width="605" style="border:1px solid black;"></a></p> <p> <a href="http://img.e-com-net.com/image/info8/0361549c5d6a47ebb9d92387b64f4230.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第58张图片" height="537" src="http://img.e-com-net.com/image/info8/0361549c5d6a47ebb9d92387b64f4230.jpg" width="650" style="border:1px solid black;"></a></p> <p>分析:</p> <p><a href="http://img.e-com-net.com/image/info8/ea986fff39e7496dade7b89191520a30.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第59张图片" height="358" src="http://img.e-com-net.com/image/info8/ea986fff39e7496dade7b89191520a30.jpg" width="650" style="border:1px solid black;"></a></p> <h3> 3.步骤代码详解</h3> <p><strong>(1)基本结构的搭建(无封装组件)</strong></p> <ul> <li> assets / css / <span style="color:#be191c;"><span style="background-color:#fef2f0;">base.css</span></span></li> </ul> <pre><code class="language-css">body{ margin: 0; padding: 0; }</code></pre> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;">App.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div id="app"> <div id="tab-bar"> <div class="tab-bar-item">首页</div> <div class="tab-bar-item">分类</div> <div class="tab-bar-item">购物车</div> <div class="tab-bar-item">我的</div> </div> </div> </template> <script> export default { name: "App", components: {}, }; </script> <style> @import "../src/assets/css/base.css"; #tab-bar { /* 本身的样式 */ background-color: #f6f6f6; box-shadow: 0 -1px 1px rgba(100, 100, 100, 0.2); /* 利用flex进行布局 */ display: flex; /* 定位相关 */ position: fixed; left: 0; right: 0; bottom: 0; } .tab-bar-item { flex: 1; text-align: center; height: 49px; } </style> </code></pre> <ul> <li>效果图,基本结构搭建完成 </li> </ul> <p><a href="http://img.e-com-net.com/image/info8/dda536c670e14c9392de247666e7b071.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第60张图片" height="449" src="http://img.e-com-net.com/image/info8/dda536c670e14c9392de247666e7b071.jpg" width="278" style="border:1px solid black;"></a></p> <p></p> <p><strong> (2) TabBar和TabBarItem组件封装</strong></p> <p>复习知识点:(十一)插槽 </p> <ul> <li> <span style="color:#be191c;"><span style="background-color:#fef2f0;">App.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div id="app"> <tab-bar> <!--TabBar的 slot 有几个就填几个item --> <tab-bar-item> <!-- TabBarItem的slot 传入不同图片 --> <img slot="item-icon" src="./assets/img/tabbar/home.svg" alt=""> <div slot="item-text">首页</div> </tab-bar-item> <tab-bar-item> <img slot="item-icon" src="./assets/img/tabbar/category.svg" alt=""> <div slot="item-text">分类</div> </tab-bar-item> <tab-bar-item> <img slot="item-icon" src="./assets/img/tabbar/shopcart.svg" alt=""> <div slot="item-text">购物车</div> </tab-bar-item> <tab-bar-item> <img slot="item-icon" src="./assets/img/tabbar/profile.svg" alt=""> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </div> </template> <script> import TabBar from './components/tabbar/TabBar' import TabBarItem from './components/tabbar/TabBarItem' export default { name: 'App', components: { TabBar, TabBarItem } } </script> <style> /* 在css里面引用需要用@import; */ @import "./assets/css/base.css"; </style> </code></pre> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;">TabBar.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div id="tab-bar"> <!-- 使用插槽,以便能往里面动态传入TabBarItem --> <slot></slot> </div> </template> <script> export default { name: "TabBar", }; </script> <style scoped> #tab-bar { /* 利用flex进行布局 */ display: flex; /* 本身的样式 */ background-color: #f6f6f6; box-shadow: 0 -1px 1px rgba(100, 100, 100, 0.2); /* 定位相关 */ position: fixed; left: 0; right: 0; bottom: 0; } </style> </code></pre> <ul> <li> <span style="color:#be191c;"><span style="background-color:#fef2f0;">TabBarItem.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div class="tab-bar-item"> <!--所有的item都展示同一个图片, 同一个文字,--> <!--<img src="../../assets/img/tabbar/home.svg" alt="">--> <!--<div>首页</div>--> <!-- 使用插槽动态传入图片文字 --> <slot name="item-icon"></slot> <slot name="item-text"></slot> </div> </template> <script> export default { name: "TabBarItem", }; </script> <style scoped> .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; /* 去掉图片与文字默认的间隔3px */ vertical-align: middle; margin-bottom: 2px; } </style> </code></pre> <ul> <li> 效果图,目前基本样式已完成</li> </ul> <p><a href="http://img.e-com-net.com/image/info8/bc79d18845874532a97d9883512cba85.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第61张图片" height="444" src="http://img.e-com-net.com/image/info8/bc79d18845874532a97d9883512cba85.jpg" width="280" style="border:1px solid black;"></a></p> <p> <strong>(3)给TabBarItem传入active图片</strong> </p> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;">  App.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div id="app"> <tab-bar> <tab-bar-item> <img slot="item-icon" src="../src/assets/img/tabbar/home.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/home_active.svg" alt=""> <div slot="item-text">首页</div> </tab-bar-item> <tab-bar-item> <img slot="item-icon" src="../src/assets/img/tabbar/category.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/category_active.svg" alt=""> <div slot="item-text">分类</div> </tab-bar-item> <tab-bar-item> <img slot="item-icon" src="../src/assets/img/tabbar/shopcart.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/shopcart_active.svg" alt=""> <div slot="item-text">购物车</div> </tab-bar-item> <tab-bar-item> <img slot="item-icon" src="../src/assets/img/tabbar/profile.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/profile_active.svg" alt=""> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </div> </template> </code></pre> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;">TabBarItem.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div class="tab-bar-item"> <slot v-if="!isActive" name="item-icon"></slot> <!-- 图片active插槽 --> <slot v-else name="item-icon-active"></slot> <slot :class="{ active: isActive }" name="item-text"></slot> </template> <script> export default { name: "TabBarItem", data() { return { isActive: true, }; }, }; </script> <style> /* ... */ .active { color: red; } </style></code></pre> <ul> <li>但是上面的TabBarItem.vue这样写会有问题,文字样式不起效果</li> </ul> <p><a href="http://img.e-com-net.com/image/info8/2a4f051ed2fd4722b7d3559454d49557.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第62张图片" height="391" src="http://img.e-com-net.com/image/info8/2a4f051ed2fd4722b7d3559454d49557.jpg" width="650" style="border:1px solid black;"></a></p> <ul> <li> 把<span style="color:#be191c;"><span style="background-color:#fef2f0;">TabBarItem.vue</span></span>的HTML改成下面</li> </ul> <pre><code class="language-html"><template> <div class="tab-bar-item"> <div v-if="!isActive"> <slot name="item-icon"></slot> </div> <!-- 图片active插槽 --> <div v-else> <slot name="item-icon-active"></slot> </div> <!-- 这样写样式不起效果 --> <!-- <slot :class="{ active: isActive }" name="item-text"></slot> --> <!-- 渲染的时候会直接把它这个替换成 <div slot="item-text">首页</div> --> <!-- 一般不会直接在插槽上绑定动态属性,因为渲染时会把它替换掉 外面套一个div这样不会把原来的替换掉,上面两个最好也这样写 --> <div :class="{ active: isActive }"> <slot name="item-text"></slot> </div> </div> </template> </code></pre> <ul> <li>效果图 </li> </ul> <p> <a href="http://img.e-com-net.com/image/info8/e99556e00efa45859f8f429734cc74e2.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第63张图片" height="434" src="http://img.e-com-net.com/image/info8/e99556e00efa45859f8f429734cc74e2.jpg" width="250" style="border:1px solid black;"></a></p> <p> <strong>(4)TabBarItem与路由结合效果</strong></p> <p>复习知识点:(七)父传子--props</p> <ul> <li>创建如下文件夹以及文件</li> </ul> <p><a href="http://img.e-com-net.com/image/info8/944025d4ff3a4b47991e4388cf4e3c5e.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第64张图片" height="294" src="http://img.e-com-net.com/image/info8/944025d4ff3a4b47991e4388cf4e3c5e.jpg" width="439" style="border:1px solid black;"></a></p> <ul> <li>安装路由,并配置,route下index.js代码 </li> </ul> <pre><code class="language-javascript">import Vue from 'vue' import VueRouter from 'vue-router' const Home = () => import('../views/home/Home') const Category = () => import('../views/category/Category') const Cart = () => import('../views/cart/Cart') const Profile = () => import('../views/profile/Profile') // 1.安装插件 Vue.use(VueRouter) // 2.创建路由对象 const routes = [ { path: '', redirect: '/home' }, { path: '/home', component: Home }, { path: '/category', component: Category }, { path: '/cart', component: Cart }, { path: '/profile', component: Profile } ] const router = new VueRouter({ routes, mode: 'history' }) // 3.导出router export default router </code></pre> <ul> <li> 用props传入动态的路径path,用itemClick监听点击,跳转到不同页面 <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;">TabBarItem.vue</span></span></li> </ul></li> </ul> <pre><code class="language-html"><template> <div class="tab-bar-item" @click="itemClick"> <div v-if="!isActive"> <slot name="item-icon"></slot> </div> <div v-else> <slot name="item-icon-active"></slot> </div> <div :class="{ active: isActive }"> <slot name="item-text"></slot> </div> </div> </template> <script> export default { name: "TabBarItem", data() { return { isActive: true, }; }, props:{ path:String }, methods: { itemClick(){ this.$router.replace(this.path) } }, }; </script> // ...</code></pre> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;"> App.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div id="app"> <router-view></router-view> <tab-bar> <!-- 因为这里是字符串,所以不需要加冒号: ,直接使用path传递 --> <tab-bar-item path='/home'> <img slot="item-icon" src="../src/assets/img/tabbar/home.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/home_active.svg" alt=""> <div slot="item-text">首页</div> </tab-bar-item> <tab-bar-item path='/category'> <img slot="item-icon" src="../src/assets/img/tabbar/category.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/category_active.svg" alt=""> <div slot="item-text">分类</div> </tab-bar-item> <tab-bar-item path='/cart'> <img slot="item-icon" src="../src/assets/img/tabbar/shopcart.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/shopcart_active.svg" alt=""> <div slot="item-text">购物车</div> </tab-bar-item> <tab-bar-item path='/profile'> <img slot="item-icon" src="../src/assets/img/tabbar/profile.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/profile_active.svg" alt=""> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </div> </template></code></pre> <ul> <li> 效果,点击哪个item就跳转到对应页面</li> </ul> <p><a href="http://img.e-com-net.com/image/info8/3f5a39f2aad54ef28f94ace46ec5efa6.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第65张图片" height="430" src="http://img.e-com-net.com/image/info8/3f5a39f2aad54ef28f94ace46ec5efa6.jpg" width="244" style="border:1px solid black;"></a></p> <p><strong>(5)TabBarItem的动态颜色控制</strong> </p> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;"> App.vue</span></span></li> </ul> <pre><code class="language-html"><template> <div id="app"> <router-view></router-view> <tab-bar> <tab-bar-item path='/home' activeColor='deepPink'> <img slot="item-icon" src="../src/assets/img/tabbar/home.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/home_active.svg" alt=""> <div slot="item-text">首页</div> </tab-bar-item> <tab-bar-item path='/category' activeColor='deepPink'> <img slot="item-icon" src="../src/assets/img/tabbar/category.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/category_active.svg" alt=""> <div slot="item-text">分类</div> </tab-bar-item> <tab-bar-item path='/cart' activeColor='deepPink'> <img slot="item-icon" src="../src/assets/img/tabbar/shopcart.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/shopcart_active.svg" alt=""> <div slot="item-text">购物车</div> </tab-bar-item> <tab-bar-item path='/profile' activeColor='deepPink'> <img slot="item-icon" src="../src/assets/img/tabbar/profile.svg" alt=""> <img slot="item-icon-active" src="../src/assets/img/tabbar/profile_active.svg" alt=""> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </div> </template> <script> import TabBar from "../src/components/tabbar/TabBar.vue"; import TabBarItem from "../src/components/tabbar/TabBarItem.vue"; export default { name: "App", components: { TabBar, TabBarItem, }, }; </script> <style> @import "../src/assets/css/base.css"; </style> </code></pre> <ul> <li><span style="color:#be191c;"><span style="background-color:#fef2f0;">TabBarItem.vue</span></span></li> </ul> <pre><code class="language-html"><template> <!-- 在这里监听点击 不要去App.vue里面的,在那写要监听四个 --> <div class="tab-bar-item" @click="itemClick"> <div v-if="!isActive"> <slot name="item-icon"></slot> </div> <!-- 图片active插槽 --> <div v-else> <slot name="item-icon-active"></slot> </div> <!-- 这样写样式不起效果 --> <!-- <slot :class="{ active: isActive }" name="item-text"></slot> --> <!-- 渲染的时候会直接把它这个替换成 <div slot="item-text">首页</div> --> <!-- 一般不会直接在插槽上绑定动态属性,因为渲染时会把它替换掉 外面套一个div这样不会把原来的替换掉,上面两个最好也这样写 --> <div :style="activeStyle"> <slot name="item-text"></slot> </div> </div> </template> <script> export default { name: "TabBarItem", props: { path: String, activeColor: { type: String, default: "red", }, }, data() { return { // isActive: true }; }, computed: { // 动态决定isActive isActive() { // /home -> item1(/home) = true // /home -> item1(/category) = false // /home -> item1(/cart) = false // /home -> item1(/profile) = false // indexOf()返回某个指定的字符串值在字符串中首次出现的位置。 == -1 说明不存在 return this.$route.path.indexOf(this.path) !== -1; // 或者用这个也行 // return this.$route.path === this.path; }, // 根据传进来的值activeColor 给文字动态绑定style activeStyle() { return this.isActive ? { color: this.activeColor } : {}; }, }, methods: { itemClick() { // 路由跳转 动态路径props里面的path this.$router.replace(this.path); }, }, }; </script> <style scoped> .tab-bar-item { flex: 1; text-align: center; height: 49px; font-size: 14px; } .tab-bar-item img { width: 24px; height: 24px; margin-top: 3px; vertical-align: middle; margin-bottom: 2px; } </style> </code></pre> <ul> <li>效果图,点击哪个,文字颜色就改变</li> </ul> <p><a href="http://img.e-com-net.com/image/info8/6cb5e65ff7e5401283f6d84216fe7368.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第66张图片" height="445" src="http://img.e-com-net.com/image/info8/6cb5e65ff7e5401283f6d84216fe7368.jpg" width="265" style="border:1px solid black;"></a></p> <p>可以再做一层封装 ,封装成<span style="color:#be191c;"><span style="background-color:#fef2f0;">MainTabBar.vue</span></span></p> <p><img alt="" height="0" src="http://img.e-com-net.com/image/info8/a62644acaec94ab0b4f3e2fe4789d56c.png" width="0"></p> <p></p> <pre><code class="language-html"><template> <tab-bar> <!-- 因为这里是字符串,所以不需要加冒号: ,直接使用path传递 --> <tab-bar-item path="/home" activeColor="pink"> <img slot="item-icon" src="~assets/img/tabbar/home.svg" alt=""> <img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt=""> <div slot="item-text">首页</div> </tab-bar-item> <tab-bar-item path="/category" activeColor="pink"> <img slot="item-icon" src="../../assets/img/tabbar/category.svg" alt=""> <img slot="item-icon-active" src="../../assets/img/tabbar/category_active.svg" alt=""> <div slot="item-text">分类</div> </tab-bar-item> <tab-bar-item path="/cart" activeColor="pink"> <img slot="item-icon" src="../../assets/img/tabbar/shopcart.svg" alt=""> <img slot="item-icon-active" src="../../assets/img/tabbar/shopcart_active.svg" alt=""> <div slot="item-text">购物车</div> </tab-bar-item> <tab-bar-item path="/profile" activeColor="deepPink"> <img slot="item-icon" src="../../assets/img/tabbar/profile.svg" alt=""> <img slot="item-icon-active" src="../../assets/img/tabbar/profile_active.svg" alt=""> <div slot="item-text">我的</div> </tab-bar-item> </tab-bar> </template> <script> import TabBar from 'components/tabbar/TabBar' import TabBarItem from 'components/tabbar/TabBarItem' export default { name: "MainTabBar", components: { TabBar, TabBarItem } } </script> <style scoped> </style> </code></pre> <p><span style="color:#be191c;"><span style="background-color:#fef2f0;">App.vue </span></span></p> <pre><code class="language-html"><template> <div id="app"> <router-view></router-view> <main-tab-bar/> </div> </template> <script> import MainTabBar from './components/mainTabbar/MainTabBar' export default { name: 'App', components: { MainTabBar } } </script> <style> @import "./assets/css/base.css"; </style> </code></pre> <h3> 4.tabbar文件路径问题</h3> <p>可以起别名,在dom中需要加 ~ ,其他地方不需要</p> <p><a href="http://img.e-com-net.com/image/info8/6650e73b65bb4555b5931aae92be7137.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第67张图片" height="225" src="http://img.e-com-net.com/image/info8/6650e73b65bb4555b5931aae92be7137.jpg" width="650" style="border:1px solid black;"></a></p> <p> <a href="http://img.e-com-net.com/image/info8/9a116eb0a5ce4f5b86628fd1abadce0f.jpg" target="_blank"><img alt="" height="50" src="http://img.e-com-net.com/image/info8/9a116eb0a5ce4f5b86628fd1abadce0f.jpg" width="398"></a></p> <p><a href="http://img.e-com-net.com/image/info8/7d9ae7375a814551978cb3a598f7d5cb.jpg" target="_blank"><img alt="超详细!Vue-coderwhy个人学习笔记(四)(Day6-Day7)_第68张图片" height="120" src="http://img.e-com-net.com/image/info8/7d9ae7375a814551978cb3a598f7d5cb.jpg" width="650" style="border:1px solid black;"></a></p> <p></p> <p></p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1505482231127277568"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Vue学习笔记,Vue,vue.js,前端)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1950232190038110208.htm" title="day15|前端框架学习和算法" target="_blank">day15|前端框架学习和算法</a> <span class="text-muted">universe_01</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a> <div>T22括号生成先把所有情况都画出来,然后(在满足什么情况下)把不符合条件的删除。T78子集要画树状图,把思路清晰。可以用暴力法、回溯法和DFS做这个题DFS深度搜索:每个边都走完,再回溯应用:二叉树搜索,图搜索回溯算法=DFS+剪枝T200岛屿数量(非常经典BFS宽度把树状转化成队列形式,lambda匿名函数“一次性的小函数,没有名字”setup语法糖:让代码更简洁好写的语法ref创建:基本类型的</div> </li> <li><a href="/article/1950209116165173248.htm" title="uniapp微信小程序 - 详解微信小程序平台用户授权登录全流程,uniapp v3版本中小程序端开发下用户点击登录后获取手机号/昵称/性别/头像等信息完成登录(提供完整示例代码,一键复制开箱即用)" target="_blank">uniapp微信小程序 - 详解微信小程序平台用户授权登录全流程,uniapp v3版本中小程序端开发下用户点击登录后获取手机号/昵称/性别/头像等信息完成登录(提供完整示例代码,一键复制开箱即用)</a> <span class="text-muted">十一猫咪爱养鱼</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E7%BB%84%E4%BB%B6%E4%B8%8E%E5%8A%9F%E8%83%BD%28%E5%BC%80%E7%AE%B1%E5%8D%B3%E7%94%A8%29/1.htm">前端组件与功能(开箱即用)</a><a class="tag" taget="_blank" href="/search/uniapp%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E5%86%B3/1.htm">uniapp常见问题解决</a><a class="tag" taget="_blank" href="/search/uniapp/1.htm">uniapp</a><a class="tag" taget="_blank" href="/search/vue3/1.htm">vue3</a><a class="tag" taget="_blank" href="/search/uniapp3%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%8E%88%E6%9D%83%E7%99%BB%E5%BD%95/1.htm">uniapp3小程序授权登录</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%99%BB%E5%BD%95%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E4%BF%A1%E6%81%AF%E6%95%99%E7%A8%8B/1.htm">微信小程序登录获取用户信息教程</a><a class="tag" taget="_blank" href="/search/%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E6%98%B5%E7%A7%B0%E6%89%8B%E6%9C%BA%E5%8F%B7%E5%A4%B4%E5%83%8F%E4%BF%A1%E6%81%AF%E7%99%BB%E5%BD%95/1.htm">获取用户昵称手机号头像信息登录</a><a class="tag" taget="_blank" href="/search/vue3%E7%89%88%E6%9C%AC%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%B9%B3%E5%8F%B0%E6%8E%88%E6%9D%83%E7%99%BB%E5%BD%95/1.htm">vue3版本小程序平台授权登录</a><a class="tag" taget="_blank" href="/search/uniap%E5%B0%8F%E7%A8%8B%E5%BA%8F%E7%AB%AF%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%E6%B5%81%E7%A8%8B/1.htm">uniap小程序端用户登录流程</a><a class="tag" taget="_blank" href="/search/uni%E5%AE%8C%E6%95%B4%E7%9A%84%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%B9%B3%E5%8F%B0%E7%99%BB%E5%BD%95%E6%BA%90%E7%A0%81/1.htm">uni完整的小程序平台登录源码</a> <div>效果图在uniapp微信小程序端开发中,超详细实现用户授权登录完整功能源码,用户授权后获取手机号/昵称/头像/性别等,提供完整思路流程及逻辑讲解。uniappVue3和Vue2都能用,你也可以直接复制粘贴,然后改下参数放到你的项目中去就行。整体思路做功能之前,先来看一下整体流程是</div> </li> <li><a href="/article/1950191208873652224.htm" title="vue element 封装表单" target="_blank">vue element 封装表单</a> <span class="text-muted">影子信息</span> <a class="tag" taget="_blank" href="/search/vue/1.htm">vue</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>背景:在前端系统开发中,系统页面涉及到的表单组件比较多,所以进行了简单的封装。封装的包括一些Form表单组件,如下:input输入框、select下拉框、等实现效果:理论知识:表单组件官方链接:点击跳转封装组件:封装组件的思路:不封装element组件,每一个input组件绑定一个form对象,例如官网。简单封装element组件,利用for循环生成form表单的每一项el-form-item。进</div> </li> <li><a href="/article/1950191165710069760.htm" title="前端面试每日 3+1 —— 第39天" target="_blank">前端面试每日 3+1 —— 第39天</a> <span class="text-muted">浪子神剑</span> <div>今天的面试题(2019.05.25)——第39天[html]title与h1、b与strong、i与em的区别分别是什么?[css]写出你知道的CSS水平和垂直居中的方法[js]说说你对模块化的理解[软技能]公钥加密和私钥加密是什么?《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。前端面试每日3+1题,以面试题来驱动学习,每天进步一点!让努力成为一种习惯,让奋斗成为一种享受!欢迎在Iss</div> </li> <li><a href="/article/1950179866523529216.htm" title="大学社团管理系统(11831)" target="_blank">大学社团管理系统(11831)</a> <span class="text-muted">codercode2022</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/echarts/1.htm">echarts</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/cloud/1.htm">cloud</a><a class="tag" taget="_blank" href="/search/sentinel/1.htm">sentinel</a><a class="tag" taget="_blank" href="/search/java-rocketmq/1.htm">java-rocketmq</a> <div>有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项目截图有需要的同学,源代码和配套文档领取,加文章最下方的名片哦!</div> </li> <li><a href="/article/1950178477592342528.htm" title="前端数据库:IndexedDB从基础到高级使用指南" target="_blank">前端数据库:IndexedDB从基础到高级使用指南</a> <span class="text-muted"></span> <div>文章目录前端数据库:IndexedDB从基础到高级使用指南引言一、IndexedDB概述1.1什么是IndexedDB1.2与其他存储方案的比较二、基础使用2.1打开/创建数据库2.2基本CRUD操作添加数据读取数据更新数据删除数据三、高级特性3.1复杂查询与游标3.2事务高级用法3.3性能优化技巧四、实战案例:构建离线优先的待办事项应用4.1数据库设计4.2同步策略实现五、常见问题与解决方案5.</div> </li> <li><a href="/article/1950169524384886784.htm" title="【Java Web实战】从零到一打造企业级网上购书网站系统 | 完整开发实录(三)" target="_blank">【Java Web实战】从零到一打造企业级网上购书网站系统 | 完整开发实录(三)</a> <span class="text-muted">笙囧同学</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F/1.htm">状态模式</a> <div>核心功能设计用户管理系统用户管理是整个系统的基础,我设计了完整的用户生命周期管理:用户注册流程验证失败验证通过验证失败验证通过用户名已存在用户名可用失败成功用户访问注册页面填写注册信息前端表单验证显示错误提示提交到后端后端数据验证返回错误信息用户名唯一性检查提示用户名重复密码加密处理保存用户信息保存成功?显示系统错误注册成功跳转登录页面登录认证机制深度解析我实现了一套企业级的多层次安全认证机制:认</div> </li> <li><a href="/article/1950169526440095744.htm" title="从零到一:打造基于GigaChat AI的艺术创作平台 | 笙囧同学的全栈开发实战" target="_blank">从零到一:打造基于GigaChat AI的艺术创作平台 | 笙囧同学的全栈开发实战</a> <span class="text-muted"></span> <div>作者简介:笙囧同学,中科院计算机大模型方向硕士,全栈开发爱好者联系方式:3251736703@qq.com各大平台账号:笙囧同学座右铭:偷懒是人生进步的阶梯前言在AI技术飞速发展的今天,如何将前沿的大模型技术与实际应用相结合,一直是我们开发者关注的焦点。今天,笙囧同学将带大家从零开始,构建一个基于GigaChatAI的艺术创作平台,实现React前端+Django后端的完整全栈解决方案。这不仅仅是</div> </li> <li><a href="/article/1950164861182865408.htm" title="VUE 座位图功能+扩展" target="_blank">VUE 座位图功能+扩展</a> <span class="text-muted">NUZGNAW</span> <a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>1、通过循环画出页面座位图0"style="display:table;margin:0auto;min-height:472px;position:relative;">{{i.sign}}2、画出右下角的预览图3、编写对应js方法watch:{seatList:{handler(newVal,oldVal){if(this.seatList&&!stringBlank(this.seatLis</div> </li> <li><a href="/article/1950164483057971200.htm" title="14.tornado操作之应用Websocket协议实现聊天室功能" target="_blank">14.tornado操作之应用Websocket协议实现聊天室功能</a> <span class="text-muted">孤寒者</span> <a class="tag" taget="_blank" href="/search/Tornado%E6%A1%86%E6%9E%B6%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%AE%9E%E6%88%98/1.htm">Tornado框架从入门到实战</a><a class="tag" taget="_blank" href="/search/websocket/1.htm">websocket</a><a class="tag" taget="_blank" href="/search/tornado/1.htm">tornado</a><a class="tag" taget="_blank" href="/search/%E8%81%8A%E5%A4%A9%E5%AE%A4%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0/1.htm">聊天室功能实现</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>目录:每篇前言:1.什么是WebSocket(1)定义(2)优点(3)和HTTP对比(4)适用场景2.WebSocket关键方法3.本tornado项目中使用WebSocket(1)准备一个聊天室的页面:第一步:编写视图:第二步:编写接口:(app.py中加入以下接口!)第三步:编写前端页面:测试接口——响应OK!(2)使用WebSocket:(3)聊天室的聊天功能的最终实现:第一步:战前准备第二</div> </li> <li><a href="/article/1950144218282389504.htm" title="为什么学习Web前端一定要掌握JavaScript?" target="_blank">为什么学习Web前端一定要掌握JavaScript?</a> <span class="text-muted">web前端学习指南</span> <div>为什么学习Web前端一定要掌握JavaScript?在前端的世界里,没有什么是JavaScript实现不了的,关于JS有一句话:凡是可以用JavaScript来写的应用,最终都会用JavaScript,JavaScript可运行在所有主要平台的所有主流浏览器上,也可运行在每一个主流操作系统的服务器端上。现如今我们在为网站写任何一个主要功能的时候都需要有懂能够用JavaScript写前端的开发人员。</div> </li> <li><a href="/article/1950143305194991616.htm" title="小架构step系列25:错误码" target="_blank">小架构step系列25:错误码</a> <span class="text-muted">秋千码途</span> <a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>1概述一个系统中,可能产生各种各样的错误,对这些错误进行编码。当错误发生时,通过这个错误码就有可能快速判断是什么错误,不一定需要查看代码就可以进行处理,提高问题处理效率。有了统一的错误码,还可以标准化错误信息,方便把错误信息纳入文档管理和对错误信息进行国际化等。没有错误码的管理,开发人员就会按自己的理解处理这些错误。有些直接把堆栈直接反馈到前端页面上,使用看不懂这些信息体验很差,也暴露了堆栈信息有</div> </li> <li><a href="/article/1950140903616212992.htm" title="Java朴实无华按天计划从入门到实战(强化速战版-66天)" target="_blank">Java朴实无华按天计划从入门到实战(强化速战版-66天)</a> <span class="text-muted">岫珩</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/%E6%97%B6%E9%97%B4%E5%AE%89%E6%8E%92/1.htm">时间安排</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92/1.htm">学习计划</a> <div>致敬读者感谢阅读笑口常开生日快乐⬛早点睡觉博主相关博主信息博客首页专栏推荐活动信息文章目录Java朴实无华按天计划从入门到实战(强化速战版-66天)1.基础(18)1.1JavaSE核心(5天)1.2数据库与SQL(5天)1.3前端基础(8天)2.进阶(17天)2.1JavaWeb核心(5天)2.2Mybatis与Spring全家桶(6天)2.3中间件入门(4天)2.4实践项目(2天)3.高阶(1</div> </li> <li><a href="/article/1950132204336115712.htm" title="《跨域资源共享CORS的深层逻辑与前端实践精要》" target="_blank">《跨域资源共享CORS的深层逻辑与前端实践精要》</a> <span class="text-muted"></span> <div>不同源头的资源交互已成为常态,而跨域资源共享(CORS)正是支撑这种交互的隐形架构。现代Web安全体系中平衡开放与防护的精妙设计。理解CORS的深层逻辑,不仅能解决实际开发中的跨域难题,更能触及网络安全与资源流通的核心矛盾,为前端工程师构建稳健的应用提供底层认知支撑。跨域资源共享的诞生,源于网络安全与应用发展的必然冲突。浏览器的同源策略,作为早期网络安全的基石,通过限制不同源文档的交互,有效阻挡了</div> </li> <li><a href="/article/1950131321980383232.htm" title="深入了解 Kubernetes(k8s):从概念到实践" target="_blank">深入了解 Kubernetes(k8s):从概念到实践</a> <span class="text-muted"></span> <div>目录一、k8s核心概念二、k8s的优势三、k8s架构组件控制平面组件节点组件四、k8s+docker运行前后端分离项目的例子1.准备前端项目2.准备后端项目3.创建k8s部署配置文件4.部署应用到k8s集群在当今云计算和容器化技术飞速发展的时代,Kubernetes(简称k8s)已成为容器编排领域的事实标准。无论是互联网巨头、传统企业还是初创公司,都在广泛采用k8s来管理和部署容器化应用。本文将带</div> </li> <li><a href="/article/1950130692448907264.htm" title="Vue CSR 到 Nuxt 3 SSR 迁移:技术实现与问题解决实录" target="_blank">Vue CSR 到 Nuxt 3 SSR 迁移:技术实现与问题解决实录</a> <span class="text-muted">二倍速播放</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a> <div>1.迁移动机与技术选型1.1CSR架构的局限性基于Vue3和Vite构建的客户端渲染(CSR)单页应用(SPA)提供了良好的开发体验和用户交互流畅性。但是其核心局限在于:搜索引擎优化(SEO):初始HTML响应仅包含一个根div元素,实际内容由JavaScript在浏览器端动态生成。虽然主流搜索引擎(如Google)能够执行部分JavaScript,但其抓取效率和稳定性不如直接获取完整HTML。非</div> </li> <li><a href="/article/1950126282490572800.htm" title="vue项目" target="_blank">vue项目</a> <span class="text-muted">阿什么名字不会重复呢</span> <a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>vue进行配置创建vue项目vuecreateone//one就是项目名字npmielement-ui--Snpmiaxios--savenpmiecharts--save配置main.jsimportVuefrom'vue'importAppfrom'./App.vue'importrouterfrom'./router'importstorefrom'./store'importElement</div> </li> <li><a href="/article/1950119980464926720.htm" title="开发避坑短篇(7):Vue+window.print()打印实践" target="_blank">开发避坑短篇(7):Vue+window.print()打印实践</a> <span class="text-muted">帧栈</span> <a class="tag" taget="_blank" href="/search/%E9%81%BF%E5%9D%91%E6%8C%87%E5%8D%97/1.htm">避坑指南</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/elementui/1.htm">elementui</a> <div>需求vue项目中如何打印当前页面内容?解决办法使用浏览器原生APIwindow.print(),这是最简单直接的方式,通过调用window.print()方法触发浏览器打印功能‌。在vue项目中直接调用print()方法即可,无须引入任何插件。如下:functionhandlePrint(){setTimeout(_=>print(),500)}打印页面样式控制可以使用@mediaprint来控制</div> </li> <li><a href="/article/1950119224630374400.htm" title="大厂都在用的前端缓存策略,你掌握了吗?" target="_blank">大厂都在用的前端缓存策略,你掌握了吗?</a> <span class="text-muted">AI架构全栈开发实战笔记</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a><a class="tag" taget="_blank" href="/search/ai/1.htm">ai</a> <div>大厂都在用的前端缓存策略,你掌握了吗?关键词:前端缓存、HTTP缓存、ServiceWorker、CDN缓存、缓存策略、性能优化、浏览器缓存摘要:本文将深入探讨前端开发中常用的缓存策略,从浏览器缓存到ServiceWorker,从HTTP缓存头到CDN缓存,全面解析大厂都在使用的高效缓存技术。通过生动的比喻和实际代码示例,帮助开发者理解并掌握这些提升Web应用性能的关键技术。背景介绍目的和范围本文</div> </li> <li><a href="/article/1950115062781898752.htm" title="26. 什么是雪碧图,作用和原理了解吗" target="_blank">26. 什么是雪碧图,作用和原理了解吗</a> <span class="text-muted">yqcoder</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95-CSS/1.htm">前端面试-CSS</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a> <div>总结小图合成一张,使用background来使用,减少资源请求一、什么是雪碧图?雪碧图(CSSSprite)是一种前端优化技术,指的是将多个小图标合并成一张大图,通过CSS控制显示其中的某一部分。它常用于网站中图标、按钮等小图较多的场景。二、雪碧图的作用作用说明✅减少HTTP请求次数合并多个图片为一张图,减少请求资源数✅提升页面加载速度尤其在图片较多时效果明显✅避免图片加载闪烁鼠标悬停切换图片时不</div> </li> <li><a href="/article/1950112039502409728.htm" title="H5UI微信小程序前端框架实战指南" target="_blank">H5UI微信小程序前端框架实战指南</a> <span class="text-muted">ai</span> <div>本文还有配套的精品资源,点击获取简介:H5UI是一个为微信小程序开发设计的前端框架,基于H5技术,提供简洁高效的组件库。框架集成了丰富的UI元素,如按钮、表格、导航栏等,简化了界面布局和交互的实现。通过安装、引入、使用组件和事件绑定四个步骤,开发者可以轻松构建功能齐全的应用。了解性能优化等注意事项对于高效开发同样重要。1.微信小程序前端开发框架介绍微信小程序概述微信小程序是微信官方推出的一种无需下</div> </li> <li><a href="/article/1950104854819041280.htm" title="Ubuntu安装LAMP" target="_blank">Ubuntu安装LAMP</a> <span class="text-muted">L_h1</span> <a class="tag" taget="_blank" href="/search/%E6%B5%8B%E8%AF%95/1.htm">测试</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a> <div>在安装vim时遇到了一个问题:E:无法获得锁/var/lib/dpkg/lock-frontend-open(11:资源暂时不可用)E:无法获取dpkg前端锁(/var/lib/dpkg/lock-frontend),是否有其他进程正占用它?解决办法:强制解锁sudorm/var/lib/dpkg/lock-frontendsudorm/var/cache/apt/archives/locksud</div> </li> <li><a href="/article/1950104727928762368.htm" title="震惊!DOM变化监控神器MutationObserver,前端开发必知的隐藏武器!" target="_blank">震惊!DOM变化监控神器MutationObserver,前端开发必知的隐藏武器!</a> <span class="text-muted">coding随想</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/html5/1.htm">html5</a> <div>一、什么是MutationObserver?如果你是一个前端开发者,一定会遇到这样的场景:页面动态加载内容后,某些操作失效了。比如,你写了一个监听按钮点击的代码,但按钮是通过AJAX动态加载的,你的代码根本无法触发。这个时候,你就需要一个“监控哨兵”——MutationObserver,它能实时监听DOM树的变化,帮你捕获那些“暗中作祟”的节点变动。MutationObserver是HTML5引入</div> </li> <li><a href="/article/1950099932132208640.htm" title="vue2中实现leader-line-vue连线文章对应字符" target="_blank">vue2中实现leader-line-vue连线文章对应字符</a> <span class="text-muted">小莉爱编程</span> <a class="tag" taget="_blank" href="/search/vue/1.htm">vue</a><a class="tag" taget="_blank" href="/search/bug%E8%AE%B0%E5%BD%95/1.htm">bug记录</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>效果展示通过点击右边的tag,触发连接操作第一步:获取右边tag展示1.右边的tag列表展示,我这边是分为两个list嵌套的数据结构;{"人员":[{</div> </li> <li><a href="/article/1950094764498022400.htm" title="Coze Studio 架构拆解:AI Agent 开发平台项目结构全分析" target="_blank">Coze Studio 架构拆解:AI Agent 开发平台项目结构全分析</a> <span class="text-muted">代码简单说</span> <a class="tag" taget="_blank" href="/search/2025%E5%BC%80%E5%8F%91%E5%BF%85%E5%A4%87%28%E9%99%90%E6%97%B6%E7%89%B9%E6%83%A0%29/1.htm">2025开发必备(限时特惠)</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/Coze/1.htm">Coze</a><a class="tag" taget="_blank" href="/search/Studio/1.htm">Studio</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/AI/1.htm">AI</a><a class="tag" taget="_blank" href="/search/Agent/1.htm">Agent</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E5%B9%B3%E5%8F%B0/1.htm">开发平台</a><a class="tag" taget="_blank" href="/search/%E5%85%A8%E6%A0%88/1.htm">全栈</a><a class="tag" taget="_blank" href="/search/AI/1.htm">AI</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E7%A8%8B%E5%8C%96/1.htm">工程化</a><a class="tag" taget="_blank" href="/search/%E5%9B%BE%E8%A7%A3%E6%9E%B6%E6%9E%84/1.htm">图解架构</a> <div>CozeStudio架构拆解:AIAgent开发平台项目结构全分析标签:CozeStudio项目架构、领域驱动设计DDD、全栈开发规范、Hertz框架、前后端协作、云原生容器、前端测试、IDL接口设计、微服务解耦、AI开发平台源码分析在最近研究AIAgent开发平台的过程中,我深入分析了刚刚开源的CozeStudio项目。这套系统是国内少有的开源全栈AI工程化项目,代码整洁、架构先进,特别是它基于</div> </li> <li><a href="/article/1950075480849838080.htm" title="关于前端的性能优化" target="_blank">关于前端的性能优化</a> <span class="text-muted"></span> <div>性能优化主要涵盖了以下四个方面:(tip:仅代表个人总结,如有不当,还希望看到的大佬多多指示)减少网络请求:合并文件、使用CDN、启用缓存。优化资源加载:代码分割、懒加载、图片压缩。提升渲染性能:减少重绘回流、防抖节流、使用WebWorker。监控和迭代:定期使用工具检测性能,持续优化。一、网络层面优化减少HTTP请求合并文件:将多个CSS或JavaScript文件合并成一个,减少请求次数。使用C</div> </li> <li><a href="/article/1950071444180365312.htm" title="【antdv4.0FormItem更新tooltip属性引发的思考】" target="_blank">【antdv4.0FormItem更新tooltip属性引发的思考】</a> <span class="text-muted"></span> <div>北京时间2023-10-19,ant-design-vue最近发布了4.0.4-4.0.6的小版本更新,其中4.0.4新增了对Form组件中FormItem的tooltip属性支持,这个功能我觉得在后台管理场景下还是非常实用的,tooltip属性作用于FormItem中的FormItemLabel区域,用来配置提示信息,当用户不确定该行的用处或者不知道填什么内容时,可以作为input里placeh</div> </li> <li><a href="/article/1950059723604684800.htm" title="linux网卡显示未知未托管,linux有线网络显示设备未托管" target="_blank">linux网卡显示未知未托管,linux有线网络显示设备未托管</a> <span class="text-muted"></span> <div>NetworkManagerNetworkManager是为了使网络配置尽可能简单而开发的网络管理软件包,如果使用DHCP,NetworkManager会替换默认的路由表、从DHCP服务器获取IP地址并根据情况设置域名服务器,NetworkManager的目标是使网络能够开箱即用。NetworkManager由两部分组成:一个以超级用户运行的守护进程(network-manager);一个前端管理</div> </li> <li><a href="/article/1950057579757498368.htm" title="零基础入门uniapp Vue3组合式API版本" target="_blank">零基础入门uniapp Vue3组合式API版本</a> <span class="text-muted">鹤早早</span> <a class="tag" taget="_blank" href="/search/uni-app/1.htm">uni-app</a> <div>前言:小程序学习笔记,课程来源up主咸虾米_。仅记录笔记,大家想学习可以去关注他。1.已安装HBuiderX(目前是4.36版本),微信开发者工具(但还没注册小程序码),相关配置OK了。1.16相关架构学习1.pages-index-index.vuebox1box2.layout{border:1pxsolidred;.box1{border:1pxsolidgreen;}.box2{borde</div> </li> <li><a href="/article/1950055310613868544.htm" title="Vue3组合API初体验" target="_blank">Vue3组合API初体验</a> <span class="text-muted">DTcode7</span> <a class="tag" taget="_blank" href="/search/Vue%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97/1.htm">Vue实战指南</a><a class="tag" taget="_blank" href="/search/VUE/1.htm">VUE</a><a class="tag" taget="_blank" href="/search/HTML/1.htm">HTML</a><a class="tag" taget="_blank" href="/search/web/1.htm">web</a><a class="tag" taget="_blank" href="/search/vue%E6%A1%86%E6%9E%B6/1.htm">vue框架</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>Vue3组合API初体验基本概念与作用说明示例一:使用ref创建响应式数据示例二:使用reactive创建响应式对象示例三:使用computed计算属性示例四:使用watch监听数据变化示例五:使用provide/inject进行父子组件间通信功能使用思路与实际开发技巧1.何时使用ref与reactive?2.如何在组合式API中保持逻辑的清晰?3.如何处理异步操作?随着Vue3的发布,组合式AP</div> </li> <li><a href="/article/16.htm" title="深入浅出Java Annotation(元注解和自定义注解)" target="_blank">深入浅出Java Annotation(元注解和自定义注解)</a> <span class="text-muted">Josh_Persistence</span> <a class="tag" taget="_blank" href="/search/Java+Annotation/1.htm">Java Annotation</a><a class="tag" taget="_blank" href="/search/%E5%85%83%E6%B3%A8%E8%A7%A3/1.htm">元注解</a><a class="tag" taget="_blank" href="/search/%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B3%A8%E8%A7%A3/1.htm">自定义注解</a> <div>一、基本概述        Annontation是Java5开始引入的新特征。中文名称一般叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。     更通俗的意思是为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且是供指定的工具或</div> </li> <li><a href="/article/143.htm" title="mysql优化特定类型的查询" target="_blank">mysql优化特定类型的查询</a> <span class="text-muted">annan211</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div> 本节所介绍的查询优化的技巧都是和特定版本相关的,所以对于未来mysql的版本未必适用。 1 优化count查询 对于count这个函数的网上的大部分资料都是错误的或者是理解的都是一知半解的。在做优化之前我们先来看看 真正的count()函数的作用到底是什么。 count()是一个特殊的函数,有两种非常不同的作用,他可以统计某个列值的数量,也可以统计行数。 在统</div> </li> <li><a href="/article/270.htm" title="MAC下安装多版本JDK和切换几种方式" target="_blank">MAC下安装多版本JDK和切换几种方式</a> <span class="text-muted">棋子chessman</span> <a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a> <div>环境: MAC AIR,OS X 10.10,64位   历史: 过去 Mac 上的 Java 都是由 Apple 自己提供,只支持到 Java 6,并且OS X 10.7 开始系统并不自带(而是可选安装)(原自带的是1.6)。 后来 Apple 加入 OpenJDK 继续支持 Java 6,而 Java 7 将由 Oracle 负责提供。   在终端中输入jav</div> </li> <li><a href="/article/397.htm" title="javaScript (1)" target="_blank">javaScript (1)</a> <span class="text-muted">Array_06</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a> <div>JavaScript 1、运算符   运算符就是完成操作的一系列符号,它有七类:   赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=)、算术运算符(+,-,*,/,++,--,%)、比较运算符(>,<,<=,>=,==,===,!=,!==)、逻辑运算符(||,&&,!)、条件运算(?:)、位</div> </li> <li><a href="/article/524.htm" title="国内顶级代码分享网站" target="_blank">国内顶级代码分享网站</a> <span class="text-muted">袁潇含</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jdk/1.htm">jdk</a><a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a><a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a> <div>       现在国内很多开源网站感觉都是为了利益而做的                  当然利益是肯定的,否则谁也不会免费的去做网站      &</div> </li> <li><a href="/article/651.htm" title="Elasticsearch、MongoDB和Hadoop比较" target="_blank">Elasticsearch、MongoDB和Hadoop比较</a> <span class="text-muted">随意而生</span> <a class="tag" taget="_blank" href="/search/mongodb/1.htm">mongodb</a><a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a><a class="tag" taget="_blank" href="/search/%E6%90%9C%E7%B4%A2%E5%BC%95%E6%93%8E/1.htm">搜索引擎</a> <div>  IT界在过去几年中出现了一个有趣的现象。很多新的技术出现并立即拥抱了“大数据”。稍微老一点的技术也会将大数据添进自己的特性,避免落大部队太远,我们看到了不同技术之间的边际的模糊化。假如你有诸如Elasticsearch或者Solr这样的搜索引擎,它们存储着JSON文档,MongoDB存着JSON文档,或者一堆JSON文档存放在一个Hadoop集群的HDFS中。你可以使用这三种配</div> </li> <li><a href="/article/778.htm" title="mac os 系统科研软件总结" target="_blank">mac os 系统科研软件总结</a> <span class="text-muted">张亚雄</span> <a class="tag" taget="_blank" href="/search/mac+os/1.htm">mac os</a> <div>1.1 Microsoft Office for Mac 2011      大客户版,自行搜索。      1.2 Latex (MacTex):      系统环境:https://tug.org/mactex/     &nb</div> </li> <li><a href="/article/905.htm" title="Maven实战(四)生命周期" target="_blank">Maven实战(四)生命周期</a> <span class="text-muted">AdyZhang</span> <a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a> <div>1. 三套生命周期     Maven拥有三套相互独立的生命周期,它们分别为clean,default和site。 每个生命周期包含一些阶段,这些阶段是有顺序的,并且后面的阶段依赖于前面的阶段,用户和Maven最直接的交互方式就是调用这些生命周期阶段。 以clean生命周期为例,它包含的阶段有pre-clean, clean 和 post</div> </li> <li><a href="/article/1032.htm" title="Linux下Jenkins迁移" target="_blank">Linux下Jenkins迁移</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/Jenkins/1.htm">Jenkins</a> <div>1. 将Jenkins程序目录copy过去      源程序在/export/data/tomcatRoot/ofctest-jenkins.jd.com下面            tar -cvzf jenkins.tar.gz ofctest-jenkins.jd.com &</div> </li> <li><a href="/article/1159.htm" title="request.getInputStream()只能获取一次的问题" target="_blank">request.getInputStream()只能获取一次的问题</a> <span class="text-muted">ayaoxinchao</span> <a class="tag" taget="_blank" href="/search/request/1.htm">request</a><a class="tag" taget="_blank" href="/search/Inputstream/1.htm">Inputstream</a> <div>问题:在使用HTTP协议实现应用间接口通信时,服务端读取客户端请求过来的数据,会用到request.getInputStream(),第一次读取的时候可以读取到数据,但是接下来的读取操作都读取不到数据   原因: 1. 一个InputStream对象在被读取完成后,将无法被再次读取,始终返回-1; 2. InputStream并没有实现reset方法(可以重</div> </li> <li><a href="/article/1286.htm" title="数据库SQL优化大总结之 百万级数据库优化方案" target="_blank">数据库SQL优化大总结之 百万级数据库优化方案</a> <span class="text-muted">BigBird2012</span> <a class="tag" taget="_blank" href="/search/SQL%E4%BC%98%E5%8C%96/1.htm">SQL优化</a> <div>网上关于SQL优化的教程很多,但是比较杂乱。近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充。 这篇文章我花费了大量的时间查找资料、修改、排版,希望大家阅读之后,感觉好的话推荐给更多的人,让更多的人看到、纠正以及补充。 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where </div> </li> <li><a href="/article/1413.htm" title="jsonObject的使用" target="_blank">jsonObject的使用</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a> <div>        在项目中难免会用java处理json格式的数据,因此封装了一个JSONUtil工具类。 JSONUtil.java package com.bijian.json.study; import java.util.ArrayList; import java.util.Date; import java.util.HashMap;</div> </li> <li><a href="/article/1540.htm" title="[Zookeeper学习笔记之六]Zookeeper源代码分析之Zookeeper.WatchRegistration" target="_blank">[Zookeeper学习笔记之六]Zookeeper源代码分析之Zookeeper.WatchRegistration</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/zookeeper/1.htm">zookeeper</a> <div>Zookeeper类是Zookeeper提供给用户访问Zookeeper service的主要API,它包含了如下几个内部类     首先分析它的内部类,从WatchRegistration开始,为指定的znode path注册一个Watcher,   /** * Register a watcher for a particular p</div> </li> <li><a href="/article/1667.htm" title="【Scala十三】Scala核心七:部分应用函数" target="_blank">【Scala十三】Scala核心七:部分应用函数</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a> <div>何为部分应用函数? Partially applied function: A function that’s used in an expression and that misses some of its arguments.For instance, if function f has type Int => Int => Int, then f and f(1) are p</div> </li> <li><a href="/article/1794.htm" title="Tomcat Error listenerStart 终极大法" target="_blank">Tomcat Error listenerStart 终极大法</a> <span class="text-muted">ronin47</span> <a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a> <div>Tomcat报的错太含糊了,什么错都没报出来,只提示了Error listenerStart。为了调试,我们要获得更详细的日志。可以在WEB-INF/classes目录下新建一个文件叫logging.properties,内容如下 Java代码  handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHa</div> </li> <li><a href="/article/1921.htm" title="不用加减符号实现加减法" target="_blank">不用加减符号实现加减法</a> <span class="text-muted">BrokenDreams</span> <a class="tag" taget="_blank" href="/search/%E5%AE%9E%E7%8E%B0/1.htm">实现</a> <div>        今天有群友发了一个问题,要求不用加减符号(包括负号)来实现加减法。         分析一下,先看最简单的情况,假设1+1,按二进制算的话结果是10,可以看到从右往左的第一位变为0,第二位由于进位变为1。    </div> </li> <li><a href="/article/2048.htm" title="读《研磨设计模式》-代码笔记-状态模式-State" target="_blank">读《研磨设计模式》-代码笔记-状态模式-State</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a> <div>声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/ /* 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况 把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化 如果在</div> </li> <li><a href="/article/2175.htm" title="CUDA程序block和thread超出硬件允许值时的异常" target="_blank">CUDA程序block和thread超出硬件允许值时的异常</a> <span class="text-muted">cherishLC</span> <a class="tag" taget="_blank" href="/search/CUDA/1.htm">CUDA</a> <div>调用CUDA的核函数时指定block 和 thread大小,该大小可以是dim3类型的(三维数组),只用一维时可以是usigned int型的。 以下程序验证了当block或thread大小超出硬件允许值时会产生异常!!!GPU根本不会执行运算!!! 所以验证结果的正确性很重要!!! 在VS中创建CUDA项目会有一个模板,里面有更详细的状态验证。 以下程序在K5000GPU上跑的。</div> </li> <li><a href="/article/2302.htm" title="诡异的超长时间GC问题定位" target="_blank">诡异的超长时间GC问题定位</a> <span class="text-muted">chenchao051</span> <a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/cms/1.htm">cms</a><a class="tag" taget="_blank" href="/search/GC/1.htm">GC</a><a class="tag" taget="_blank" href="/search/hbase/1.htm">hbase</a><a class="tag" taget="_blank" href="/search/swap/1.htm">swap</a> <div>HBase的GC策略采用PawNew+CMS, 这是大众化的配置,ParNew经常会出现停顿时间特别长的情况,有时候甚至长到令人发指的地步,例如请看如下日志: 2012-10-17T05:54:54.293+0800: 739594.224: [GC 739606.508: [ParNew: 996800K->110720K(996800K), 178.8826900 secs] 3700</div> </li> <li><a href="/article/2429.htm" title="maven环境快速搭建" target="_blank">maven环境快速搭建</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/%E5%AE%89%E8%A3%85/1.htm">安装</a><a class="tag" taget="_blank" href="/search/mavne/1.htm">mavne</a><a class="tag" taget="_blank" href="/search/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/1.htm">环境配置</a> <div>一 下载maven 安装maven之前,要先安装jdk及配置JAVA_HOME环境变量。这个安装和配置java环境不用多说。 maven下载地址:http://maven.apache.org/download.html,目前最新的是这个apache-maven-3.2.5-bin.zip,然后解压在任意位置,最好地址中不要带中文字符,这个做java 的都知道,地址中出现中文会出现很多</div> </li> <li><a href="/article/2556.htm" title="PHP网站安全,避免PHP网站受到攻击的方法" target="_blank">PHP网站安全,避免PHP网站受到攻击的方法</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a> <div> 对于PHP网站安全主要存在这样几种攻击方式:1、命令注入(Command Injection)2、eval注入(Eval Injection)3、客户端脚本攻击(Script Insertion)4、跨网站脚本攻击(Cross Site Scripting, XSS)5、SQL注入攻击(SQL injection)6、跨网站请求伪造攻击(Cross Site Request Forgerie</div> </li> <li><a href="/article/2683.htm" title="yii中给CGridView设置默认的排序根据时间倒序的方法" target="_blank">yii中给CGridView设置默认的排序根据时间倒序的方法</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/GridView/1.htm">GridView</a> <div>public function searchWithRelated() {         $criteria = new CDbCriteria;         $criteria->together = true; //without th</div> </li> <li><a href="/article/2810.htm" title="Java集合对象和数组对象的转换" target="_blank">Java集合对象和数组对象的转换</a> <span class="text-muted">dyy_gusi</span> <a class="tag" taget="_blank" href="/search/java%E9%9B%86%E5%90%88/1.htm">java集合</a> <div>    在开发中,我们经常需要将集合对象(List,Set)转换为数组对象,或者将数组对象转换为集合对象。Java提供了相互转换的工具,但是我们使用的时候需要注意,不能乱用滥用。 1、数组对象转换为集合对象     最暴力的方式是new一个集合对象,然后遍历数组,依次将数组中的元素放入到新的集合中,但是这样做显然过</div> </li> <li><a href="/article/2937.htm" title="nginx同一主机部署多个应用" target="_blank">nginx同一主机部署多个应用</a> <span class="text-muted">geeksun</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a> <div>近日有一需求,需要在一台主机上用nginx部署2个php应用,分别是wordpress和wiki,探索了半天,终于部署好了,下面把过程记录下来。 1.   在nginx下创建vhosts目录,用以放置vhost文件。 mkdir vhosts   2.   修改nginx.conf的配置, 在http节点增加下面内容设置,用来包含vhosts里的配置文件 #</div> </li> <li><a href="/article/3064.htm" title="ubuntu添加admin权限的用户账号" target="_blank">ubuntu添加admin权限的用户账号</a> <span class="text-muted">hongtoushizi</span> <a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/useradd/1.htm">useradd</a> <div>ubuntu创建账号的方式通常用到两种:useradd 和adduser . 本人尝试了useradd方法,步骤如下: 1:useradd    使用useradd时,如果后面不加任何参数的话,如:sudo useradd sysadm 创建出来的用户将是默认的三无用户:无home directory ,无密码,无系统shell。 顾应该如下操作:   </div> </li> <li><a href="/article/3191.htm" title="第五章 常用Lua开发库2-JSON库、编码转换、字符串处理" target="_blank">第五章 常用Lua开发库2-JSON库、编码转换、字符串处理</a> <span class="text-muted">jinnianshilongnian</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/lua/1.htm">lua</a> <div>  JSON库   在进行数据传输时JSON格式目前应用广泛,因此从Lua对象与JSON字符串之间相互转换是一个非常常见的功能;目前Lua也有几个JSON库,本人用过cjson、dkjson。其中cjson的语法严格(比如unicode \u0020\u7eaf),要求符合规范否则会解析失败(如\u002),而dkjson相对宽松,当然也可以通过修改cjson的源码来完成</div> </li> <li><a href="/article/3318.htm" title="Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解" target="_blank">Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解</a> <span class="text-muted">yaerfeng1989</span> <a class="tag" taget="_blank" href="/search/timer/1.htm">timer</a><a class="tag" taget="_blank" href="/search/quartz/1.htm">quartz</a><a class="tag" taget="_blank" href="/search/%E5%AE%9A%E6%97%B6%E5%99%A8/1.htm">定时器</a> <div>原创整理不易,转载请注明出处:Spring定时器配置的两种实现方式OpenSymphony Quartz和java Timer详解 代码下载地址:http://www.zuidaima.com/share/1772648445103104.htm 有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz。 1.Java Timer定时 首先继承jav</div> </li> <li><a href="/article/3445.htm" title="Linux下df与du两个命令的差别?" target="_blank">Linux下df与du两个命令的差别?</a> <span class="text-muted">pda158</span> <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a> <div> 一、df显示文件系统的使用情况,与du比較,就是更全盘化。   最经常使用的就是 df -T,显示文件系统的使用情况并显示文件系统的类型。   举比例如以下:   [root@localhost ~]# df -T   Filesystem                   Type &n</div> </li> <li><a href="/article/3572.htm" title="[转]SQLite的工具类 ---- 通过反射把Cursor封装到VO对象" target="_blank">[转]SQLite的工具类 ---- 通过反射把Cursor封装到VO对象</a> <span class="text-muted">ctfzh</span> <a class="tag" taget="_blank" href="/search/VO/1.htm">VO</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/sqlite/1.htm">sqlite</a><a class="tag" taget="_blank" href="/search/%E5%8F%8D%E5%B0%84/1.htm">反射</a><a class="tag" taget="_blank" href="/search/Cursor/1.htm">Cursor</a> <div>在写DAO层时,觉得从Cursor里一个一个的取出字段值再装到VO(值对象)里太麻烦了,就写了一个工具类,用到了反射,可以把查询记录的值装到对应的VO里,也可以生成该VO的List。   使用时需要注意: 考虑到Android的性能问题,VO没有使用Setter和Getter,而是直接用public的属性。 表中的字段名需要和VO的属性名一样,要是不一样就得在查询的SQL中</div> </li> <li><a href="/article/3699.htm" title="该学习笔记用到的Employee表" target="_blank">该学习笔记用到的Employee表</a> <span class="text-muted">vipbooks</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a> <div>    这是我在学习Oracle是用到的Employee表,在该笔记中用到的就是这张表,大家可以用它来学习和练习。 drop table Employee; -- 员工信息表 create table Employee( -- 员工编号 EmpNo number(3) primary key, -- 姓</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>