Nuxtjs

news2024/9/27 5:50:00

SSR渲染

SSR:在服务器端将Vue渲染成HTML返回给浏览器

优点

  • 对SEO支持好
  • SPA单页渲染更快

npx create-nuxt-app nuxtDemo

修改开发地址

package.json文件中进行修改

"config":{
	"nuxt":{
		"host":"127.0.0.1",
		"port":"8000"
	}
}

生命周期

请添加图片描述

nuxtServerInit

  • 请求先到达 nuxtServerInit 方法,图中也表明了适用场景是对 store 操作,函数仅在每个服务器端渲染中运行 且运行一次,只能定义在store的主模板当中
  • 定义在store/index.js中
export const actions={
    nuxtServerInit(store,context){
        console.log('nuxtServerInit',store,context);
    }
}

middleware

  • 下来请求到达 middleware ,允许您定义一个自定义函数运行在一个页面或一组页面渲染之前。可以运行在全局,或者某个页面组件之前,不会在components组件内部运行
  • 中间件执行顺序
    nuxt.config.js=>匹配布局=>匹配页面
  • 有三中定义方式
    • nuxt.conig.js中引入middleware/auth.js
// auth.js
export default({store,route,redirect,params,query,req,res})=>{
    console.log('nuxt.config.js',store,route,redirect,params,query,req,res);
}
// nuxt.conig.js
router:{
  middleware:'auth'
},
  • 定义在layout默认组件中
	<template>
    <div>
        <p>默认布局</p>
        <nuxt/>
    </div>
</template>
<script>
    export default{
        // middleware:'auth', // 页面中间级中间件
        middleware(){
            console.log('layout middleware');
        }
    }
</script>
  • 定义在单个页面中
<template>
  <div>
    <div><nuxt-link :to="{name:'about'}">about</nuxt-link></div>
    <div><nuxt-link :to="{name:'news'}">news</nuxt-link></div>
    <div><nuxt-link :to="{name:'test'}">test</nuxt-link></div>
  </div>
</template>

<script>
export default {
  name: 'IndexPage',
  middleware(context){
      console.log('middleware',context);
  },
  // 参数有效性
  validate({params,query}){
    // 校验业务
    console.log('validate');
    return true;
  },
  // 读数据返回给组件
  asyncDate(){
    console.log('asyncDate');
  },
  // 读数据给VUEX
  fetch(){
    console.log('fetch');
  },
  beforeCreate(){
    console.log('beforeCreate');
  },
  created(){
    console.log('created');
  }
}
</script>

asyncData & fetch

接下来达到 asyncData & fetch 方法,asyncData() 适用于在渲染组件前获取异步数据,返回数据后合并到data选项内部,fetch() 适用于在渲染页面前填充 vuex 中维护的数据。会在组件每次加载前被调用(在服务端或切换至目标路由之前),由于是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象

通过axios发送网络请求

  • npm i @nuxtjs/axios
  • nuxt.config.js中进行配置
modules: [
   '@nuxtjs/axios'
 ],
axios:{
	proxy:true, // 开启代理
},

proxy:{
   '/api/':{
     target:"http://localhost:3001", // 代理转发地址
     changeOrigin:true,
     pathRewrite:{
       '^/api':''
     }
   }
 },
  • 发送请求读取 本地或网络数据
<template>
    <div>
        <h3>商品</h3>
        <div><nuxt-link to="/goods/1">商品1</nuxt-link></div>
        <div><nuxt-link to="/goods/1">商品2</nuxt-link></div>
        <!-- <div>{{title}}</div> -->
        <nuxt/>
    </div>
</template>
<script>
export default{
    async asyncData({$axios}){
        let list=await $axios({url:'/data/list.json'}); // 读取本地static/data/list.json中数据
        let list2=await $axios({url:'/api/home'}); // 读取网络http://localhost:3001数据,目前在3000端口里,通过nuxt配置进行代理
        console.log(list);
        return {
            title:list.data
        }
    },
    // async fetch({$axios,store}){
    //     let list=await $axios({url:'/data/list.json'});
    //     store.commit('M_NAME',list)
    //     console.log(list);
    // }
}
</script>

axios配置

  • nuxt.config.js中进行配置,引入axios配置插件
plugins: [
    {
      src:'~/plugins/axios',
      ssr:true, // 服务端
    }
  ],
  • 在plugins文件夹下新建axios.js
export default function({$axios,redirect,route,store}){
    // 基本配置
    $axios.defaults.timeout=3000,
    // 请求拦截
    $axios.onRequest(config=>{
        config.headers.token='';
        return config;
    })
    // 响应拦截
    $axios.onResponse(res=>{
        if(res.data.err===2&&route.fullPath!=='login'){
            redirect('/login?path='+route.fullPath)
        }
        return res;
    })
    // 错误处理
    $axios.onError(error=>{
        return error
    })
}

render

最后进行渲染。将渲染后的页面返回给浏览器,用户在页面进行操作,如果再次请求新的页面,此时只会回到生命周期中的 middlerware 中,而非 nuxtServerInit ,所以如果不同页面间需要操作相同的数据请用 vuex 来维护,render钩子只能定义渲染时的配置,render内部不可以有业务逻辑,也不执行beforeCreate & created

mounted & updated

运行在客户端
注:没有keep-alive 那自然activated、deactivated这两个生命周期也没了

路由

  • nuxt会把page下的自动生成路由
  • 只需要在跳转时通过nuxt-link配置路径
<template>
  <div>
    <div><nuxt-link :to="{name:'about'}">about</nuxt-link></div>
    <div><nuxt-link :to="{name:'news'}">news</nuxt-link></div>
  </div>
</template>

<script>
export default {
  name: 'IndexPage'
}
</script>
  • 路由传参和VueRouter一致
<template>
    <div>
        <!-- <div><nuxt-link to="/news/123">123</nuxt-link></div> -->
        <div><nuxt-link :to="{name:'news-id',params:{id:123}}">123</nuxt-link></div>
    </div>
</template>
  • 在对应page页面可以用_表示参数解析

    • page文件夹
      • goods页面
        • _id.vue
        1. 非动态路由可对跳转路由为/goods/1进行解析,解析结果为id:1
        2. 动态路由:to=“{name:‘goods-id’,params:{id:1}}”,解析结果为id:1
  • 可对参数进行校验,如果参数格式不对则进入到nuxt准备的404页面

<template>
   <div>
    <div>new content</div>
    <div>id:{{$route.params.id}}</div>
    <div><nuxt-link to="/">home</nuxt-link></div>
   </div>
</template>
<script>
    export default{
        validate({params}){
            return /^\d+$/.test(params.id)
        }
    } 
</script>
  • 对路由跳转时添加动画效果
  1. 所有路由配置在全局引入的CSS文件里
	/* 页面进入时,页面离开时 入 */
	.page-enter-active,.page-leave-active{
    transition: opacity 2s;
	}
	/* 页面离开时 退 */
	.page-enter,.page-leave-active{
	    opacity: 0;
	}
  1. 单个路由配置在全局引入的CSS文件里
	.test-enter-active,.test-leave-active{
    transition: all 2s;
    font-size: 12px;
	}
	.test-enter,.test-leave-active{
	    font-size: 40px;
	}
<template>
    <div>test</div>
</template>

<script>
export default {
  name: 'TestPage',
  transition:'test', // 对应的页面进行相应配置
}
</script>

路由守卫

  • 前置路由守卫
  1. 全局守卫:nuxt.config指向middleware,layouts定义中间件
  2. 组件独享守卫:middleware
  3. 插件全局后置守卫
  • 后置路由守卫
  1. 使用vue的beforeRouterLeave钩子
  2. 插件全局后置守卫

默认模板和默认布局

默认模板

  • 在项目根目录下,新建一个app.html文件,nuxt默认它是一个默认模板
<!DOCTYPE html>
<html lang="en">
<head>
    {{HEAD}}
</head>
<body>
    <p>默认模板</p>
    {{APP}}
</body>
</html>
  • 在项目根目录下建一个layouts文件夹,里面新建一个default.vue
<template>
    <div>
        <p>默认布局</p>
        <nuxt/>
    </div>
</template>

错误页面和个性meta

错误页面

  • 在项目根目录下建一个layouts文件夹,里面新建一个error.vue

个性meta

  • nuxt可在每个页面对head进行单独设置
<template>
   <div>
    <div>new content</div>
    <div>id:{{$route.params.id}}</div>
    <div><nuxt-link to="/">home</nuxt-link></div>
   </div>
</template>
<script>
    export default{
        validate({params}){
            return /^\d+$/.test(params.id)
        },
        data(){
            return {
                title:this.$route.params.title
            }
        },
        head(){
            return {
                title:this.title,
                meta:[
                    {hid:"不覆盖",name:'new1',content:'测试页面'}
                ]
            }
        }
    } 
</script>

loading页面

  • 在进行路由跳转时可以给一些提示,也就是loading
  • 在nuxt.config.js中进行配置
  // 自定义loading效果
  // loading:{color:'#399',heigth:'3px'},
  loading:'~/components/loading.vue'
  • components新建loading.vue
<template>
    <div v-if="loading">loading....</div>
</template>
<script>
export default{
    data:()=>({
        loading:false,
    }),
    methods:{
        start(){
            this.loading=true;
        },
        finish(){
            this.loading=false;
        }
    }
}
</script>

vuex

模块方式

  • 在nuxt中集成了vuex
  • store目录下每个js文件都会被转换称为状态树,当然index是根模块

模块数据管理

  • 主模块
// 主模块
// state
export const state=()=>({
    data1:false,
})
export const mutations={
    M_UPDATE_DATE1(state,payload){
        state.data1=payload
    }
}
// actions
export const actions={
    nuxtServerInit(store,context){
        // console.log('nuxtServerInit',store,context);
    }
}
// getters
export const getters={
    getData1(state){
        return state?'真':'假'
    }
}
  • home模块
export const state=()=>({
    home1:false,
    test:'',
})
export const mutations={
    M_UPDATE_HOME1(state,payload){
        state.home1=payload.home1
    },
    M_UPDATE_TEST(state,payload){
        state.test=payload.test
    }
}
export const actions={
    A_UPDATE_HOME({commit,state},payload){
        // 可以做异步处理
        commit('M_UPDATE_HOME1',{home1:true})
    },
    A_UPDATE_TEST({commit,state},payload){
        console.log(payload);
        commit('M_UPDATE_TEST',payload)
    }
}
  • 也面中使用
<template>
  <div>
    <div><button @click="changClick">测试home中数据</button></div>
 </div>
</template>

<script>
export default {
  name: 'IndexPage',
  methods:{
    changClick(){
      this.$store.dispatch('home/A_UPDATE_TEST',{test:'test'});
      this.$store.commit('home/M_UPDATE_HOME1',{home1:true})
    }
  }
}
</script>
<style scoped>
.app-header-active{
  color: red;
  background-color: pink;
}
</style>

vuex状态持久化管理

  • npm i cookie-universal-nuxt
  • nuxt.config.js中配置
 modules: [
    '@nuxtjs/axios',
    'cookie-universal-nuxt'
  ],
  // 注册后,在全局上下文对象中多了个$cookies
  • 在登陆页面,在登陆成功后同步数据到cookie和vuex
<template>
    <div>
        <button @click="login">登录</button>
    </div>
</template>
<script>
export default {
    name:'login',
    methods:{
        login(){
            this.$cookies.set('user',{name:'jack'});
            this.$store.commit('M_UPDATE_USERINFO',{name:'jack'})
        }
    }
}
</script>
  • 强刷时,nuxtServerInit中将cookie中数据同步带vuex中
// 主模块
// state
export const state=()=>({
    data1:false,
})
export const mutations={
    M_UPDATE_DATE1(state,payload){
        state.data1=payload
    }
}
// actions
export const actions={
	// 同步数据
    nuxtServerInit(store,{app:{$cookies}}){
        let user =$cookies.get('user')?$cookies.get('user'):{err:1,token:'',name:''};
        store.commit('user/M_UPDATE_USERINFO',user)
    }
}
// getters
export const getters={
    getData1(state){
        return state?'真':'假'
    }
}

引入ElementUI组件库

  • nuxt.config.js中ElementUI以插件方式引入
export default {
  // Global page headers: https://go.nuxtjs.dev/config-head
  head: {
    title: 'nuxtDemo',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },


  // Global CSS: https://go.nuxtjs.dev/config-css
  css: [
    '~/asstes/css.css',
    'element-ui/lib/theme-chalk/index.css'
  ],

  // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
  plugins: [
    {
      src:'~/plugins/axios',
      ssr:true, // 服务端
    },
    {
      src:'~/plugins/element-ui',
      ssr:true,
    }
  ],

  // Auto import components: https://go.nuxtjs.dev/config-components
  components: true,

  // Modules: https://go.nuxtjs.dev/config-modules
  modules: [
    '@nuxtjs/axios',
    'cookie-universal-nuxt'
  ],

  axios:{
    proxy:true, // 开启代理
  },

  proxy:{
    '/api/':{
      target:"http://localhost:3001", // 代理转发地址
      changeOrigin:true,
      pathRewrite:{
        '^/api':''
      }
    }
  },

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
    transpile:[/^element-ui/],
  }
}
  • 在plugins中新建element-ui.js
import Vue from 'vue';

// 整体引入
import ElementUI from 'element-ui';
Vue.use(ElementUI);

// 按需引入
// import {Button} from 'element-ui';
// Vue.use(Button);
  • 页面中使用
<template>
  <div>
    <div><el-button type="primary">EL按钮</el-button></div>
 </div>
</template>

<script>
export default {
  name: 'IndexPage',
}
</script>

全局方法,过滤器, 全局指令,全局组件

全局方法

  • nuxt.config.js中配置
export default {
  plugins: [
    {
    src:'~/plugins/mixins'
    }
  ],
}
  • plugins文件夹下新建mixins
// 全局方法
import Vue from 'vue';
const show=()=>console.log('全局方法');
Vue.prototype.$show=show; // 服务端钩子不可以用
  • 在页面中通过this.$show()调用

过滤器

  • nuxt.config.js中配置
  • assets/js新建filters.js文件
export function fillzero(n){
    return n<10?'0'+n:n+'';
}
export const date=time=>{
    let d = new Date();
    d.setTime(time);
    const year=d.getFullYear();
    const month=d.getMonth()+1;
    const date=d.getDate();
    return `${year}${month}${date}`
}
  • plugins文件夹下mixins中写入
// 全局方法
import Vue from 'vue';
const show=()=>console.log('全局方法');
Vue.prototype.$show=show; // 服务端钩子不可以用

// 全局过滤器
import * as filters from '../asstes/js/filters';
Object.keys(filters).forEach(key=>Vue.filter(key,filters[key]))
  • 页面中使用
<template>
    <div>
        <div>time:{{time|date}}</div>
    </div>
</template>
<script>
export default{
    data(){
        return {
            time:new Date(),
        }
    }
}
</script>

全局指令

  • nuxt.config.js中配置
  • assets/js新建directives.js文件
function direc1(el,binding,vnode){
    console.log('自定义指令');
}
export default {
    bind(el,binding,vnode){
        direc1(el,binding,vnode)
    }
}
  • plugins文件夹下mixins中写入
// 全局方法
import Vue from 'vue';
const show=()=>console.log('全局方法');
Vue.prototype.$show=show; // 服务端钩子不可以用

// 全局过滤器
import * as filters from '../asstes/js/filters';
Object.keys(filters).forEach(key=>Vue.filter(key,filters[key]))

// 自定义指令
import direc1 from '../asstes/js/directives';
Vue.directive('direc1',direc1)
  • 在页面中按正常指令使用
<template>
  <div>
    <div v-direc1>自定义指令</div>
 </div>
</template>

<script>
export default {
  name: 'IndexPage',
}
</script>

全局组件

  • nuxt.config.js中配置
  • components/global新建globalTest.vue文件
<template>
    <div>全局组件测试</div>
</template>
  • plugins文件夹下mixins中写入
// 全局方法
import Vue from 'vue';
const show=()=>console.log('全局方法');
Vue.prototype.$show=show; // 服务端钩子不可以用

// 全局过滤器
import * as filters from '../asstes/js/filters';
Object.keys(filters).forEach(key=>Vue.filter(key,filters[key]))

// 自定义指令
import direc1 from '../asstes/js/directives';
Vue.directive('direc1',direc1)

// 全局组件
import globalTest from '../components/global/globalTest';
Vue.component('globalTest',globalTest)
  • 页面中按组件正常使用,并且不需要再次引入
<template>
    <div>
        <GlobalTest/>
    </div>
</template>
<script>

export default{
}
</script>

资源指向

static

  • static中资源不会经过处理,直接搬到资源环境下,映射到资源根目录下
  • 可以通过绝对路径拿到static下资源
<img src='/img.test.png'/>

assets

  • assets下资源会被处理
  • 可以通过相对路径拿到assets下资源
<img src='../assets/img.test.png'/>
<img src='~assets/img.test2.png'/>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/354471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

朋友当上项目测试组长了,我真的羡慕了

最近我发现一个神奇的事情&#xff0c;我一个朋友居然已经当上了测试项目组长&#xff0c;据我所知他去年还是在深圳的一家创业公司做苦逼的测试狗&#xff0c;短短8个月&#xff0c;到底发生了什么&#xff1f; 于是我立刻私聊他八卦一番。 原来他所在的公司最近正在裁员&am…

01_Docker 简介

01_Docker 简介 文章目录01_Docker 简介1.1 Docker 简介1.2 Docker 组件1.2.1 Docker 客户端和服务区1.2.2 Docker 镜像1.2.3 Registry1.2.4 Docker 容器参考资料https://www.runoob.com/docker/ubuntu-docker-install.html 1.1 Docker 简介 Docker 是一个能够把开发的应用程…

HTML+CSS+JavaScript学习笔记~ 从入门到精通!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、HTML1. 什么是HTML&#xff1f;一个完整的页面&#xff1a;<!DOCTYPE> 声明中文编码2.HTML基础①标签头部元素标题段落注释水平线文本格式化②属性3.H…

SOFA Weekly|开源人、本周贡献 issue 精选

SOFA WEEKLY | 每周精选 筛选每周精华问答&#xff0c;同步开源进展欢迎留言互动&#xff5e;SOFAStack&#xff08;Scalable Open Financial Architecture Stack&#xff09;是蚂蚁集团自主研发的金融级云原生架构&#xff0c;包含了构建金融级云原生架构所需的各个组件&#…

Docker安装Tomcat、mysql、redis

目录 前言 一、安装Tomcat 二、安装mysql &#xff08;一&#xff09;简单版 &#xff08;二&#xff09;实战版 三、安装redis 前言 镜像可以先去Docker Hub Container Image Library | App Containerization 左上角搜&#xff0c;然后点进入可以看到具体的命令&#…

网络协议(TCP/IP)

目录一、网络分层模型二、OSI模型三、网络传输原理四、TCP/IP1、TCP/IP 原理2、TCP 三次握手/四次挥手3、Http协议和TCP/IP的区别五、HTTP原理六、HTTPS原理七、CDN原理一、网络分层模型 互联网的本质就是一系列的网络协议&#xff0c;最早由ISO国际组织定义为7层网络参考模型…

【JS】数组常用方法总结-功能、参数、返回值

数组常用方法总结-功能、参数、返回值 用简单的js示例 运行在线工具&#xff1a;链接: 菜鸟工具 菜鸟工具示意图&#xff1a; ![在这里插入图片描述](https://img-blog.csdnimg.cn/de8589eb1acf42abb0347d8a3a3bbdfa.png 1.会改变原有数组方法 &#xff08;1&#xff09;pu…

(考研湖科大教书匠计算机网络)第五章传输层-第三节:TCP和UDP对比

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;TCP和UDP概述二&#xff1a;TCP和UDP对比本节对应视频如下 【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】&#xff1a;TCP和UD…

ShowCase 专治开发的「我自测好了」

背景 开发提测时信心十足的说我自测过了肯定没问题&#xff0c;结果分分钟打脸&#xff0c;测试在测试环境一测就发现xx「功能」不可用、xx「流程」阻塞 产品验收在测试之后&#xff0c;导致验收的时候可能出现与设计不一致&#xff0c;造成返工成本和风险加大 1.开发自测质量…

常用聚类算法分析

1. 什么是聚类 1.1. 聚类的定义 聚类(Clustering)是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇&#xff0c;使得同一个簇内的数据对象的相似性尽可能大&#xff0c;同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起…

Kubernetes 1.18学习笔记

文章目录一、Kubernetes 概述和架构1、kubernetes 基本介绍2、Kubernetes 功能3、Kubernetes 架构组件4、Kubernetes 核心概念5、Kubernetes 工作原理二、Kubernetes 集群搭建1、系统环境准备1.1 安装要求1.2 系统初始化2、客户端工具kubeadm搭建2.1 安装步骤2.2 安装组件2.3 集…

MongoDB数据存储格式

前言 之前分享了MongoDB的基本命名和视图等信息&#xff0c;本文分享一下MongoDB的数据存储类型&#xff0c;使用方式。基础的MongoDB信息就学习完啦&#xff0c;之后会继续分享MongoDB进阶的一些东西。 MongoDB数据存储格式前言1 文件结构1.2 字段名称2 点符号2.2 嵌入式文件…

Stream流式处理

Stream流的三类方法 获取Stream&#xff1a;流创建一条流水线,并把数据放到流水线上准备。 中间方法&#xff1a;流水线上的操作一次操作完毕之后,还可以继续进行其他操作。 终结方法&#xff1a;一个Stream流只能有一个终结方法是流水线上的最后一个操作。 生成Stream流的…

基于SSM框架的RBAC权限系统设计与 实现

基于SSM框架的RBAC权限系统设计与 实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景…

网络设备驱动框架

1.框架 1&#xff09;网络协议接口层 向网络层协议提供统一的数据包收发接口&#xff0c;不论上层协议是ARP&#xff0c;还是IP&#xff0c;都通过dev_queue_xmit()函数发送数据&#xff0c;并通过netif_rx()函数接收数据。这一层的存在&#xff0c;使得上层协议独立于具体的设…

【总结】vim教程与详细命令总结,该来的躲不掉啊晕

B站|公众号&#xff1a;啥都会一点的研究生 目录写在前面vim的工作模式普通模式编辑模式命令模式命令大全&#xff0c;最详细&#xff08;建议收藏&#xff09;光标的移动插入模式 - 插入/追加文本编辑文本选择文本&#xff08;可视化模式&#xff09;可视化模式命令剪切, 复制…

【Selenium学习】Selenium 中特殊元素操作

1.鼠标定位操作鼠标悬停&#xff0c;即当光标与其名称表示的元素重叠时触发的事件&#xff0c;在 Selenium 中将键盘鼠标操作封装在 Action Chains 类中。Action Chains 类的主要应用场景为单击鼠标、双击鼠标、鼠标拖曳等。部分常用的方法使用分类如下&#xff1a;• click(on…

过滤器与拦截器

文章目录一、前言1、概述2、过滤器与拦截器异同2.1 简介2.2 异同2.3 总结3、Filters vs HandlerInterceptors二、过滤器1、概述2、生命周期2.1 生命周期概述2.2 基于函数回调实现原理3、自定义过滤器两种实现方式3.1 WebFilter注解注册3.2 过滤器&#xff08;配置类注册过滤器&…

vue2vue3常用语法(持续更新)

一、基础1. 指令指令描述v-if判断v-else-if判断后剩下的v-else判断后剩下的v-html渲染html文本格式v-text渲染文本v-for循环v-showdisplay&#xff1a;none/block切换v-model双向绑定v-bind(缩写&#xff1a;:)动态绑定v-on(缩写&#xff1a;)绑定dom事件(如点击事件)v-cloak解…

WMS AMS【Android Framework进阶】

1.简介 可以毫不夸张的说&#xff0c;android的framework层主要是由WMS、AMS还有View所构成&#xff0c;这三个模块穿插交互在整个framework中&#xff0c;掌握了它们之间的关系和每一个逻辑步骤&#xff0c;你对framework的了解至少有百分之五十 AMS是Android中最核心的服务…