VUE学习:七.单页应用

sadwind2024-02-29笔记84

前言

SPA 单页面应用(SinglePage Web Application) ,指只有一个主页面的应用(一个 html 页面),一开始只需要加载一次 js、css 的相关资源。所有内容都包含在主页面,对每一个功能模块组件化。单页应用跳转,就是切换相关组件,仅仅刷新局部资源。

  • 创建一个 vue 项目,运行该项目,默认就是使用单页应用的配置。可以通过打包,查看打包文件,发现目录下只有一个 html 文件,不同页面都是通过 js 生成的,典型的单页应用。

    index.html 代码详情










































































































#1.Router 配置

  • 单页内部跳转并不会重新渲染 HTML 文件,其路由可以由前端进行控制,因此我们需要在项目内部编写相应的路由文件,Vue 会解析这些文件中的配置并进行对应的跳转渲染:http://127.0.0.1:8080/vue/#/about








     


     

     









    // router.jsimport Vue from "vue"import Router from "vue-router"import Home from "./views/Home.vue" // 引入 Home 组件import About from "./views/About.vue" // 引入 About 组件Vue.use(Router) // 注册路由export default new Router({
      //❓默认路由模式是 hash 模式,会携带 # 标记,与真实 url 不符,可以改为 history 模式
      routes: [
        {
          path: "/", // ❓如果路由存在二级目录,需要添加 base 属性,否则默认为 "/"
          name: "home",
          component: Home, // ❓页面组件没有进行按需加载,打包时和下面的一起打包成一个js文件,即使没有访问这个页面也会加载
        },
        {
          path: "/about",
          name: "about",
          component: About, // ❓页面组件没有进行按需加载
        },
      ],})
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
  • 以上问题优化:http://127.0.0.1:8080/vue/#/about,但是需要注意页面渲染 404 的问题







     





     




     




    // router.jsimport Vue from "vue"import Router from "vue-router"Vue.use(Router)let base = `${process.env.BASE_URL}` // ✅export default new Router({
      mode: "history", // ✅ 使用history路由
      base: base,
      routes: [
        {
          path: "/",
          name: "home",
          component: () => import("./views/Home.vue"), // ✅ 按需加载组件,打包时会和下面的组件分开成2个js文件,当访问此资源才加载
        },
        {
          path: "/about",
          name: "about",
          component: () => import("./views/About.vue"), //✅ 按需加载组件
        },
      ],})
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    提示

    webpack 在编译时,会静态地解析代码中的 import,同时将模块添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。

    如果你想给拆分出的文件命名,可以尝试一下 webpack 提供的 Magic Comments(魔法注释):

    const Home = () => import(/* webpackChunkName:'home'*/ "./views/Home.vue")
    1

#2.Vuex 配置

  • Vuex 的配置文件

    import Vue from "vue"import Vuex from "vuex"Vue.use(Vuex)export default new Vuex.Store({
      state: {},
      mutations: {},
      actions: {},})
    1
    2
    3
    4
    5
    6
    7
    8

    我们可以通过 actions 异步提交 mutations 去 修改 state 的值并通过 getter 获取

  • 中大型项目中为了后期的拓展性和可维护性,我们可以把它拆分为以下目录:

    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── actions.js        # 根级别的 action
        ├── mutations.js      # 根级别的 mutation
        └── modules
            ├── moduleA.js    # A模块
            └── moduleB.js    # B模块
    1
    2
    3
    4
    5
    6
    7
  • 与单个 store.js 文件不同的是,我们按模块进行了划分,每个模块中都可以包含自己 4 个核心功能。比如模块 A 中:

    /* moduleA.js */const moduleA = {
      state: {
        text: "hello",
      },
      mutations: {
        addText(state, txt) {
          // 这里的 `state` 对象是模块的局部状态
          state.text += txt    },
      },
      actions: {
        setText({ commit }) {
          commit("addText", " world")
        },
      },
      getters: {
        getText(state) {
          return state.text + "!"
        },
      },}export default moduleA
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
  • 上方我们导出 A 模块,并在 index.js 中引入:

    /* index.js */import Vue from "vue"import Vuex from "vuex"import moduleA from "./modules/moduleA"import moduleB from "./modules/moduleB"import { mutations } from "./mutations"import actions from "./actions"Vue.use(Vuex)export default new Vuex.Store({
      state: {
        groups: [1],
      },
      modules: {
        moduleA, // 引入 A 模块
        moduleB, // 引入 B 模块
      },
      actions, // 根级别的 action
      mutations, // 根级别的 mutations
    
      // 根级别的 getters
      getters: {
        getGroups(state) {
          return state.groups    },
      },})
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    这样项目中状态的模块划分就更加清晰,对应模块的状态我们只需要修改相应模块文件即可。

#3.接口配置

  • 在 src 目录下新建 services 文件夹用于统一管理接口文件

    └── src
        └── services
            ├── http.js      # 接口封装
            ├── moduleA.js    # A模块接口
            └── moduleB.js    # B模块接口
    1
    2
    3
    4
    5
  • 为了让接口便于管理,我们同样使用不同的文件来配置不同模块的接口,同时由于接口的调用 ajax 请求代码重复部分较多,我们可以对其进行简单的封装,比如在 http.js 中

    详细代码










































































  • 请求示例

    /* moduleA.js */import Http from "./http"export const getTestData = () => {
      return Http.get(【目标地址】)}
    1
    2
    3
    4
    5
    6
  • 本地启动出现跨域,我们需要在 vue.config.js 中进行 devServer 的配置:

    /* vue.config.js */module.exports = {
        ...
        devServer: {
            // string | Object 代理设置
            proxy: {
                // 接口是 '/repos' 开头的才用代理
                '/repos': {
                    target: 【目标地址】,
                    changeOrigin: true, // 是否改变源地址
                    // pathRewrite: {'^/api': ''}
                }
            },
        }
        ...}
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

#4.公共配置

  • 我们可以在 src 目录下建一个 common 文件夹来存放其配置文件

    └── src
        └── common
            ├── index.js      # 公共配置入口
            ├── validate.js   # 表单验证配置
            └── other.js      # 其他配置
    1
    2
    3
    4
    5
  • 在入口文件中我们可以向外暴露其他功能配置的模块

    /* index.js */import Validate from "./validate"import Other from "./other"export { Validate, Other }
    1
    2
    3
    4
    5

总结

通过对单页应用的认识,相关 Router、Vuex 的配置,服务请求的封装,公共文件的配置,我们可以很清晰地认识到一个标准的单页应用在开发时需要注意的一些常见问题。


relate content

JQUERY 选择器 为啥不能选择NAME呢

语法描述$(this)当前 HTML 元素$("p")所有 <p> 元素$("p.intro")所有 class="intro"...

php有内置函数array_unique可以用来删除数组中的重复值

array_unique -- 移除数组中重复的值array_unique说明array array_unique ( array array )array_unique() 接受 array 作为输...

新的启程:得想点办法 好点子

因为个人原因,想做个网站,利用空余时间,网上收集整理一些资源,放些广告赚点小钱,目前看来很难实现了。申请了好多次广告联盟,都被拒绝了,大概理由就是网站流量不够,内容不多,原创内容少,仔细一想,这还是很...

MYSQL 更新记录 搜索替换字符串

UPDATE icms_article_data     SET body = REPLACE(  &nb...

ICMS使用一些心得 经验

ICMS是一款小众的CMS建站程序,速度、使用都还不错,扩展也方便,可能使用太少,作者最近更新有点慢,文档太少,在使用过程中有很多问题得不到及时解决,主要是查不到什么资料,官方文档太简单。最近在学习S...

ICMS 标签 调节器

模板标签调节器允许在任何以 $ 开头的标签中使用调节器对得到的值进行处理,形式为:modifiers调节器可带参数 参数可以是模板自带调节器,也可以是PHP的函数<!--{$...

Post Reply    

◎Welcome to participate in the discussion.