Vue基础(二)

一、单页面应用程序

单页面应用程序(SPA):web网站中只有唯一的一个HTML页面

 特点:

  • 仅在该web页面初始化时加载相应的资源
  • 页面一旦加载完成,不会因用户操作进行页面的重新加载或跳转,而是利用JS动态变换html内容,实现页面与用户的交互。

 优点:

   1、良好的交互体验

  • 内容改变不需重新加载整个页面
  • 获取数据通过ajax异步获取
  • 没有页面之间的跳转,不会出现白屏现象

   2、良好的前后端工作分离模式

  • 后端专注提供API接口,更易实现API接口复用
  • 前端专注页面渲染,更利于前端工程化的发展

   3、减轻服务器的渲染压力


缺点:

   1、首屏加载慢

         解决方式:路由懒加载、代码压缩、CDN加速、网络传输压缩

   2、不利于SEO

         解决方式:SSR方式渲染


创建SPA项目的方式:

   1、基于vite创建SPA项目

  • 仅支持vue3
  • 不基于webpack
  • 运行速度快

   2、基于vue-cli创建SPA项目

  • 支持vue2、vue3
  • 基于webpack
  • 运行速度较慢
  • 适合在企业级开发中使用

二、vue-cli的基本使用

步骤:

   1、全局安装(仅需安装一次)

yarn global add @vue/cli

   2、查看vue版本,确认是否安装成功

vue --version

   3、创建项目架子

vue create project-name(项目名 不能用中文)

   4、启动项目

npm run serve

三、vite的基本使用

步骤:

   1、创建项目

npm init vite-project(项目名称)

   2、下载依赖

npm install

  3、启动项目

npm run dev

vite项目的运行流程

通过mian.js把App.vue渲染到index.html的指定区域中

  • APP.vue用来编写待渲染的模版结构,所有要渲染的结构用template标签包裹
  • index.html中要预留一个el区域
  • mian.js把App.vue渲染到index.html的预留区域中

 示例:

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Vue</title>
  </head>
  <body>
    <!-- 预留id为app的el区域 -->
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

 app.vue

<template>
  <!-- 待渲染的模板结构 -->
  <h1>这是<i>APP.vue</i>文件</h1>
</template>

main.js

// 按需导入createAPP函数
import { createApp } from "vue";
// 导入带渲染的App.vue组件
import App from "./App.vue";

// 调用createAPP函数,创建SPA应用实例
// 将APP作为参数传给createApp函数,表示要把APP渲染到index.html页面上
const app = createApp(App);

// 调用mount方法把APP组件的模板结构渲染到指定的el中
app.mount("#app");

四、组件

组件化开发:根据封装的思想,把页面上可重用的部分封装成组件

vue规定组件的后缀名是.vue

 组件封装原则:

  • 组件的DOM结构、Style样式要尽量复用
  • 组件中要展示的数据,尽量由组件的使用者提供

1、vue组件的构成

每个.vue组件都由3部分构成

  • template(组件的模板结构)(必须包含)
  • script(JS)
  • style(样式)

template节点

每个组件对应的模板结构,都需要定义到<template>节点中

<template>
  <!-- 当前组件的DOM结构 -->
</template>

注:

  • <template>为容器标签,只有包裹性质的作用,不会被渲染为真正的DOM元素
  • template节点中允许使用指令
  • vue2版本template内仅支持一个根节点,vue3版本template允许多个根节点

script节点

 script节点中可封装组件的js业务逻辑

<script>
export default {
  // name属性可指定当前组件的名称
  name: "MyAPP",
  // data属性可指定vue组件渲染期间需要用到的数据
  data() {
    return {
      username: "zs",
    };
  },
  //methods属性声明事件处理函数
  methods: {
    addCount() {
      this.count++;
    },
  },
};
</script>

style节点

 script节点中可编写样式代码

<style lang="css">
h1 {
  color: red;
}
</style>

注:

  • lang默认值为css 还有less和scss
  • 设置lang='less'需要运行 npm install less -D

 2、组件的基本使用

组件的引用原则:先注册后使用

注册组件的两种方式:全局注册和局部注册

 全局注册

被全局注册的组件,可以在全局任何一个组件内使用

开发期间使用频率很高,进行全局注册

步骤:

  1. 在main.js中  import 需要被全局注册的组件 from ' '
  2. 调用app.component('组件名称'(短横线或大驼峰),'需要被全局注册的组件')
  3. 直接已标签的形式进行使用

 示例:

 main.js

import { createApp } from "vue";
import App from "./App.vue";

//1.导入需要被全局注册的组件
import Swiper from "./components/Swiper.vue";

const app = createApp(App);

//2.调用app.component()方法全局注册组件
app.component("my-swiper", Swiper);

app.mount("#app");

 App.vue 或其他任何一个组件内

<template>
  <!-- 3.直接已标签的形式进行使用 -->
  <my-swiper></my-swiper>
</template>

局部注册

 被局部注册的组件,只能在当前注册的范围内使用

开发过程中,只有特定情况下会用到,进行局部注册

步骤:

  1. 导入需要被注册的组件
  2. 通过component节点 ,为当前组件注册私有子组件

示例:

App.vue 或其他需注册局部组件的组件内

<template>
  <!-- 3.在页面中使用局部组件 -->
  <my-search></my-search>
</template>
<script>
// 1.导入需要被注册的组件
import Search from "./components/Search.vue";

export default {
  name: "MyAPP",
  data() {
    return {
      username: "zs",
    };
  },
  methods: {
  
  },
// 2.通过component节点 ,为当前组件注册私有子组件
  components: {
    "my-search": Search,
  },
};
</script>

3、组件之间的样式冲突问题

样式冲突原因:

所有组件的DOM结构都是基于唯一的index.html呈现的

每个组件中的样式都会影响整个index.html页面中的DOM元素

解决方法:

  • 分配自定义属性
  • 利用style节点的scoped属性

注:

加上scoped后,如果想让某些样式对子组件生效,可使用deep样式穿透

1、分配自定义属性

为每个组件分配唯一的自定义属性,编写样式时通过属性选择器来控制样式作用域

<template>
  <div class="container" data-v-001>
    <h3 data-v-001>组件</h3>
  </div>
   
</template>


<style>
/* 通过括号"属性选择器",来防止组价样式冲突的问题 */
.container[data-v-001] {
  background-color: red;
}
</style>

示例

App.vue

<template>
  <div data-v-001>
    <h1 data-v-001>这是App.vue组件</h1>

    <p data-v-001>App中的p标签</p>
    <p data-v-001>App中的p标签</p>

    <hr />
    <my-list data-v-001></my-list>
  </div>
</template>

<script>
import MyList from "./List.vue";
export default {
  name: "MyApp",
  components: {
    MyList,
  },
};
</script>

<style lang="less">
// 保证样式只作用于data-v-001节点的组件
p[data-v-001] {
  color: red;
}
</style>
>

List.vue

<template>
  <div data-v-002>
    <h1 data-v-002>这是List.vue组件</h1>

    <p data-v-002>List中的p标签</p>
    <p data-v-002>List中的p标签</p>

    <hr />
  </div>
</template>

<script>
export default {
  name: "MyList",
};
</script>

<style lang="less"></style>

2、利用style节点的scoped属性

加上scope属性后,vue会自动为当前组件的DOM结构样式分配唯一的自定义属性

示例

App.vue

<template>
  <div>
    <h1>这是App.vue组件</h1>

    <p>App中的p标签</p>
    <p>App中的p标签</p>

    <hr />
    <my-list></my-list>
  </div>
</template>

<script>
import MyList from "./List.vue";
export default {
  name: "MyApp",
  components: {
    MyList,
  },
};
</script>
<!-- 加上scoped -->
<style lang="less" scoped>
p {
  color: red;
}
</style>

List.vue

<template>
  <div>
    <h1>这是List.vue组件</h1>

    <p>List中的p标签</p>
    <p>List中的p标签</p>

    <hr />
  </div>
</template>

<script>
export default {
  name: "MyList",
};
</script>

<!-- 加上scoped -->
<style lang="less" scoped></style>

3、deep样式穿透

示例

App.vue

<template>
  <div>
    <h1>这是App.vue组件</h1>
    <p>App中的p标签</p>
 

    <hr />
    <my-list></my-list>
  </div>
</template>

<script>
import MyList from "./List.vue";
export default {
  name: "MyApp",
  components: {
    MyList,
  },
};
</script>

<style lang="less" scoped>
// 使用deep深度选择器
:deep(.title) {
  color: blue;
}
</style>

List.vue

<template>
  <div>
    <!-- 父组件中加了deep属性的.title影响子组件中class为title的样式 -->
    <h1 class="title">这是List.vue组件</h1>
    <hr />
  </div>
</template>

<script>
export default {
  name: "MyList",
};
</script>

<style lang="less" scoped></style>

4、组件的props

定义:组件的自定义属性,使用者可通过props把数据传递到子组件的内部,供子组件内部进行使用。

props作用:父组件通过props向子组件传递数据。

 注:

  • 父组件如果传递了子组件中未声明的props属性,无法被子组件使用

 在组件中声明props

示例

Artice.vue组件

<template>
  <div>
    <h3>标题:{{title}}</h3>
    <h5>作者:{{author}}</h5>
  </div>
</template>

<script>
export default {
  name: 'MyArticle',
  // 外界可以传递指定的数据,到当前的组件中
  props: ['title', 'author']
}
</script>

App.vue

<template>
  <div>
    <h1>这是 App.vue 根组件</h1>
    <hr />
    <!-- 使用组件,并传递数据 -->
    <my-article title="标题" author="作者"></my-article>
  </div>
</template>

<script>
import MyArticle from './Article.vue'

export default {
  name: 'MyApp',
  components: {
    MyArticle,
  },
}
</script>

动态绑定props的值

使用v-bind为组件动态绑定props的值

示例

 Artice.vue组件

<template>
  <div>
    <h3>标题:{{title}}</h3>
    <h5>作者:{{author}}</h5>
  </div>
</template>

<script>
export default {
  name: 'MyArticle',
  props: ['title', 'author']
}
</script>

App.vue

<template>
  <div>
    <h1>这是 App.vue 根组件</h1>
    <hr />
    <my-article :title="info.title" :author="info.author"></my-article>
  </div>
</template>

<script>
import MyArticle from './Article.vue'

export default {
  name: 'MyApp',
  data() {
    return {
      info: {
        title: 'abc',
        author: '123',
      },
    }
  },
  components: {
    MyArticle,
  },
}
</script>

5、Class与Style绑定

动态绑定HTML的Class

 1.可通过三元表达式,为元素动态的绑定类名

 示例

<template>
  <div>
   <!-- 通过三元运算符动态绑定class -->
   <h3 class="thin" :class="isItalic ? 'italic' : ''">MyStyle 组件</h3> 
  </div>
</template>

<script>
export default {
  name: 'MyStyle',
 data() {
    return {
      // 字体是否倾斜
      isItalic: false,
    }
  },
}
</script>

<style lang="less">
// 字体变细
.thin {
  font-weight: 200;
}

// 倾斜字体
.italic {
  font-style: italic;
}

</style>

2.可通过数组的语法格式,为元素动态绑定多个class类名

 示例

<template>
  <div>
    <!--通过数组语法绑定  -->
    <h3 class="thin" :class="[isItalic ? 'italic' : '', isDelete ? 'delete' : '']">MyStyle 组件</h3>
  </div>
</template>

<script>
export default {
  name: 'MyStyle',
  data() {
    return {
      // 字体是否倾斜
      isItalic: false,
      // 是否应用删除效果
      isDelete: false,
    }
  },
}
</script>

<style lang="less">
// 字体变细
.thin {
  font-weight: 200;
}

// 倾斜字体
.italic {
  font-style: italic;
}

.delete {
  text-decoration: line-through;
}
</style>

3.可通过对象语法对数组语法绑定class进行简化

 示例

<template>
  <div>
    <!-- 通过对象 -->
    <h3 class="thin" :class="classObj">MyStyle 组件</h3>
  </div>
</template>

<script>
export default {
  name: 'MyStyle',
  data() {
    return {
      //对象中,属性名是class类名,值是布尔值
      classObj: {
        italic: false,
        delete: false,
      },
    }
  },
}
</script>

<style lang="less">
// 字体变细
.thin {
  font-weight: 200;
}

// 倾斜字体
.italic {
  font-style: italic;
}

.delete {
  text-decoration: line-through;
}
</style>

以对象语法绑定内联style

:style,实际上是JS对象

 示例

<template>
  <div>
    <div :style="{ color: active, fontSize: fsize + 'px', 'background-color': bgcolor }">绑定内联样式
    </div>
  </div>
</template>

<script>
export default {
  name: 'MyStyle',
  data() {
    return {
      // 高亮时的文本颜色
      active: 'red',
      // 文字的大小
      fsize: 30,
      // 背景颜色
      bgcolor: 'pink',
    }
  },
}
</script>

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值