Vue系列-01 Vue3 从入门到实战:组件开发、路由与状态管理全解析

起步

  • 安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 安装vue-cli3
* npm install -g @vue/cli
* npm install -g @vue/cli-service-global
  • 新建项目:
* vue create vue-buy
  • 选择配置
* Babel 代码转义
* Linter 代码风格
* 测试
  • 运行:
* npm run serve
  • 项目结构
    在这里插入图片描述
  • VS-Code常用快捷键:
1)快速复制一行:shift+alt+↓
2)格式化代码:shift+alt+F
3)快速生产vue单文件框架代码:vbase
4)快速导入:vimport
5)快速移动:alt+↓
  • npm 淘宝镜像设置
* npm install -g cnpm --registry=https://registry.npm.taobao.org
* npm config set registry https://registry.npm.taobao.org  
* # 配置后可通过下面方式来验证是否成功
* npm config get registry

在这里插入图片描述

声明式渲染

纯浏览器端体验

Test file:01-hello.html

<div id="app">{
  
  { message }}</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
     
     
	el: '#app',
	data: {
     
     
		message: 'Hello, Vue!'
	}
});
</script>

单文件组件

.vue是vue单文件组件,一个文件就是一个组件,由template、script和style三个标签构成,分别是html、js和css的内容部分
Test file:02-single.vue

<template>
  <div id="app">
    {
  
  {message}}
  </div>
</template>
<script>
  export default {
     
     
    data(){
     
     
      return {
     
     
        message: 'single vue'
      }
    }
  }
</script>
<style scoped>
  #app{
     
     
    color: red;
  }
</style>

启动运行:cd到02-single.vue文件所在目录运行命令:
vue serve 02-single.vue 即可运行该文件,并且支持热部署哟!

快速创建项目

  • 创建项目的命令:vue create vue-cart
  • cd vue-cart
  • 启动命令:npm run serve
    在这里插入图片描述

vue.config.js

项目根目录可以新建 vue.config.js 来进行扩展配置:

module.exports = {
   
   
  baseUrl: process.env.NODE_ENV === 'production'
    ? '//your_url'
    : '/',
  outputDir: 'dist',
  assetsDir: 'static',
  filenameHashing: true,
  // When building in multi-pages mode, the webpack config will contain different plugins
  // (there will be multiple instances of html-webpack-plugin and preload-webpack-plugin).
  // Make sure to run vue inspect if you are trying to modify the options for those plugins.
  pages: {
   
   
    index: {
   
   
      // entry for the pages
      entry: 'src/pages/index/index.js',
      // the source template
      template: 'src/pages/index/index.html',
      // output as dist/index.html
      filename: 'index.html',
      // when using title option,
      // template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title>
      title: '首页',
      // chunks to include on this pages, by default includes
      // extracted common chunks and vendor chunks.
      chunks: ['chunk-vendors', 'chunk-common', 'index']
    }
    // when using the entry-only string format,
    // template is inferred to be `public/subpage.html`
    // and falls back to `public/index.html` if not found.
    // Output filename is inferred to be `subpage.html`.
    // subpage: ''
  },
  // eslint-loader 是否在保存的时候检查
  lintOnSave: true,
  // 是否使用包含运行时编译器的Vue核心的构建
  runtimeCompiler: false,
  // 默认情况下 babel-loader 忽略其中的所有文件 node_modules
  transpileDependencies: [],
  // 生产环境 sourceMap
  productionSourceMap: false,
  // cors 相关 https://jakearchibald.com/2017/es-modules-in-browsers/#always-cors
  // corsUseCredentials: false,
  // webpack 配置,键值对象时会合并配置,为方法时会改写配置
  // https://cli.vuejs.org/guide/webpack.html#simple-configuration
  configureWebpack: (config) => {
   
   
  },
  // webpack 链接 API,用于生成和修改 webapck 配置
  // https://github.com/mozilla-neutrino/webpack-chain
  chainWebpack: (config) => {
   
   
    // 因为是多页面,所以取消 chunks,每个页面只对应一个单独的 JS / CSS
    config.optimization
      .splitChunks({
   
   
        cacheGroups: {
   
   }
      });
    // 'src/lib' 目录下为外部库文件,不参与 eslint 检测
    config.module
      .rule('eslint')
      .exclude
      .add('/Users/maybexia/Downloads/FE/community_built-in/src/lib')
      .end()
  },

  // 配置高于chainWebpack中关于 css loader 的配置
  css: {
   
   
    // 是否开启支持 foo.module.css 样式
    modules: false,
    // 是否使用 css 分离插件 ExtractTextPlugin,采用独立样式文件载入,不采用 <style> 方式内联至 html 文件中
    extract: true,
    // 是否构建样式地图,false 将提高构建速度
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {
   
   
      css: {
   
   
        // options here will be passed to css-loader
      },
      postcss: {
   
   
        // options here will be passed to postcss-loader
      }
    }
  },
  // All options for webpack-dev-server are supported
  // https://webpack.js.org/configuration/dev-server/
  devServer: {
   
   
    open: true,
    host: '127.0.0.1',
    port: 3000,
    https: false,
    hotOnly: false,
    proxy: null,
    before: app => {
   
   
    }
  },
  // 构建时开启多进程处理 babel 编译
  parallel: require('os').cpus().length > 1,
  // https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
  pwa: {
   
   },
  // 第三方插件配置
  pluginOptions: {
   
   }
};

条件与循环

<!-- 条件语句 -->
<h1 v-if="showMsg">{
  
  { msg }}</h1>
<!-- 循环语句 -->
<ul>
  <li v-for="good in goods" :key="good.id">
    <span>{
  
  {good.text}}</span>
    <span>¥{
  
  {good.price}}</span>
  </li>
</ul>
<!-- 这里用 v-for 循环时推荐绑定key,原因是在对数组中间进行插入操作时,可以提升渲染性能 -->

事件处理

<!-- 用户输入,事件处理 -->
<p>
  text:<input type="text" v-model="inputText">
  price:<input type="text" v-model="inputPrice">
  <button @click="addGood">加购物车</button>
</p>
<script>
methods: {
     
     
  addGood(){
     
     
    this.goods.push({
     
     
      text: this.inputText,
      price: this.inputPrice
    });
    this.inputText = '';
    this.inputPrice = '';
  }
}
</script>

组件化

新建Cart.vue购物车组件

组件引入与注册到components

import Cart from './components/Cart.vue'
export default {
   
   
  name: 'app',
  components: {
   
   
    Cart
  }
}

父子组件通过props属性传值

<cart :name="name" :cart="cart"></cart>
props: ['name', 'cart']
// 属性校验
props: {
   
   
	name: {
   
   type: String, required: true},
	cart: {
   
   type: Array}
}

样式和class绑定

<tr v-for="(c, index) in cart" :key="c.id" :class="{active: c.active}">
<style scoped>
  .active{
     
     
    color: green;
    font-weight: bold;
  }
</style>

计算属性

需要额外加工data中数据的时候使用

computed: {
   
   
  activeCount(){
   
   
    return this.cart.filter(v=>v.active).length;
  },
  count(){
   
   
    return this.cart.length;
  },
  total(){
   
   
    let num = 0;
    this.cart.forEach(c => {
   
   
      if(c.active){
   
   
        num += c.price * c.count;
      }
    });
    return num;
  }
}

事件总线

// 修改Vue原型
Vue.prototype.$bus = new Vue();
// App.vue中发送事件
this.$bus.$emit('addCart', good);
// Cart.vue中监听事件
created(){
   
   
  this.$bus.$on('addCart', good => {
   
   
    const ret = this.cart.find(v => v.id === good.id);
    if(ret){
   
   // 购物车里已有该商品
      ret.count += 1;
    }else{
   
   
      this.cart.push({
   
   
        ...good, // 属性展开运算符
        count: 1,
        active: true
      });
    }
  });
}

Cart组件

<template>
  <div>
    <p>{
  
  {name}}</p>
    <table border="1" >
      <tr>
        <th>#</th><th>课程名</th><th>单价</th><th>数量</th><th>价格</th>
      </tr>
      <tr v-for="(c, index) in cart" :key="c.id" :class="{active: c.active}">
        <td>
          <input type="checkbox" v-model="c.active">
        </td>
        <td>{
  
  {c.text}}</td><td>{
  
  {c.price}}</td>
        <td>
          <button @click="desc(c, c.count, index)">-</button>
          {
  
  {c.count}}
          <button @click="incr(c)">+</button>
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值