vue电商项目manager

前期准备工作

材料说明

在api-server中通过使用PowerShell输入npm install安装所有需要的包,再通过node app.js启动服务器,同时也可以直接把txt文件改成bat文件,在里面写入node app.js即可

项目准备-vue-cli创建项目结构

  1. 来到所以在项目的目录中
  2. 通过使用PowerShell输入vue init webpack 项目名构建脚手架项目
  3. 在VScode中通过vue run start
  4. npm i安装项目中的需要的文件
$ vue init webpack exprice --------------------- 这个是那个安装vue脚手架的命令
This will install Vue 2.x version of the template. ---------------------这里说明将要创建一个vue 2.x版本的项目
For Vue 1.x use: vue init webpack#1.0 exprice
? Project name (exprice) ---------------------项目名称
? Project name exprice
? Project description (A Vue.js project) ---------------------项目描述
? Project description A Vue.js project
? Author Datura --------------------- 项目创建者
? Author Datura
? Vue build (Use arrow keys)
? Vue build standalone
? Install vue-router? (Y/n) --------------------- 是否安装Vue路由,也就是以后是spa(但页面应用需要的模块)
? Install vue-router? Yes
? Use ESLint to lint your code? (Y/n) n ---------------------是否启用eslint检测规则,这里个人建议选no
? Use ESLint to lint your code? No
? Setup unit tests with Karma + Mocha? (Y/n)
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? (Y/n)
? Setup e2e tests with Nightwatch? Yes
vue-cli · Generated "exprice".
To get started: --------------------- 这里说明如何启动这个服务
cd exprice
npm run dev

07-关于如何关闭eslint代码规范

在build的webpack.base.conf.js中注释...(config.dev.useEslint ? [createLintingRule()] : []),这句话。别忘记重启服务器,不然不会生效

09-引入element-ui

通过npm i element-ui -S安装elementui。element-ui-2
然后再main.js中调用这个组件,这样这个项目的全局都可以用了,且不用再单独引入。

码云ssh公钥

ssh -keygen -t rsa

11-git版本控制

  1. git init
  2. git add .
  3. git commit -m '名字'
  4. git romote add origin 网址
  5. git push -u origin master(之后再push直接git push 就行)

12-登录-新建分支-配置路由

新建一个分支 专门写登录功能
1. git branch -a查看分支
2. git checkout -b ''创建新分支
3. git checkout 对应分支名 切换到对应的分支上
4. git merge 需要合并的分支合并分支
5. git push origin :要删除的分支的名字删除服务器分支
6. git branch -d 分支名字删除本地服务器的分支
7. git push --set-upstream origin 名字上传分支
创建一个dev-login分支,把登录功能放在里面
注意: 1. commit每完成一个小功能就commit一次
2. push操作master去完成

注意:关于template不能格式化的问题

通过把如下代码放入设置中,然后重启vscode就可以了。点击shift+alt+f就可以了

// 设置格式化vue中的html
      "vetur.format.defaultFormatterOptions": {

   "js-beautify-html": {
     "wrap_attributes": "auto"
   },
      "prettyhtml": {
   "printWidth": 100,
   "singleQuote": false,
   "wrapAttributes": false,
   "sortAttributes": false
 }
    },

项目开始制作

登录项目

13-登录-引入表单组件
  1. 通过使用element-ui的样式代码
14-项目-样式调整

大家都要用的样式要写在main.js文件中

注意:样式高设置为100%的时需要设置html,body{},以及app.vue中的样式也要设置为100%

15-登录-axios插件

axios插件的引入是在main.js中添加如下代码

import axios from 'axios'
Vue.prototype.$axios = axios

axios不是插件,因此想引用的时候和插件的使用一样就用如下方式:
自己制作插件axios以插件的形成添加的话,首先下载axios插件插件,然后再plugins文件 中的http中设置好,最后在main.js通过标准引用组件的代码

import https from '@/plugins/http'
Vue.use(https)
16-项目-发送登录请求
  1. 首先在http。js中添加axios.defaults.baseURL = ''这样就可以通过在所需要的页面进行调用例如this.$http.post(‘login’, this.formData).then(res => {}
  2. 再login.vue引入提示框this.$message.success(msg)其中msg是从后台获取的
18-登录成功,进入home组件
  1. js编程式导航 this.$router.push({name: ‘home’})
  2. App.vue中添加router-view
  3. 在components中新建home.vue组件
  4. 配置index.js路由
19-登录-简化登录代码-async和await

让一部代码ajax看起来更像同步代码
1. 找到异步操作的代码,在前面加上await 然后令const res=await ***,再在距离这个代码最近的方法上加async

20-登录-保存token值

目的:如果用户没有登录->url直接来到home组件
在登录成功时,保存正确的token

// localStorage 这个特性主要是用来作为本地存储来使用的
// 把data.token的数据存储到token中
localStorage.setItem('token', data.token)

首页制作

22-首页-header-分栏

在home.vue中通过element-ui中Layout 布局模板把头部分成24份4-18-2

25-首页-进入组件的权限认证

在home.vue中,通过const token = localStorage.getItem(‘token’)获取之前得到的token的信息,如果有信息就能够在home界面,如果没有就到login界面。
清空token信息使用的是localStorage.clear(),这样就可以清空里面存的信息了

用户列表制作

27-用户列表设置

由于之前使用的是element-ui组件,而这个组件的导航栏组件有router功能,是否使用 vue-router 的模式,启用该模式会在激活导航时以 index 作为 path 进行路由跳转,因此不要忘记设置。

28-用户管理-用户列表-使用element-ui模板制作:面包屑和搜索框-table表格
31-用户管理-用户列表-请求数据-设置请求头
  1. created(){this.getUserList()}
  2. methods:{getUserList(){发送请求}}
  3. 接口文档中,除了登录之外的所有请求都需要进行授权->设置请求头
  4. 找axios中关于请求头设置代码
    const autoToken = localStorage.getItem('token')
    axios.defaults.headers.common['Authorization'] = autoToken
  1. 发送请求
33-用户管理-日期格式处理
  1. 在main.js中制作过滤器,这样全局都可以用
// todo 全局过滤器 - 处理日期
Vue.filter('fdata', (res) => {
  return moment(res).format('YYYY-MM-DD')
})

这种方法已经过时

如果单元格内显示的内容不是字符串(文本),需给被显示的内容外层包裹一个template
不同组件之间是相互独立的,不能直接传值。template内部要用数据 设置slot-scope属性 该属性的值是要用数据create_time的数据源userlist。。slot-scope的值userlist其实就是el-table绑定的数据unserlist。userlist.row->数组中的每一个对象
~~

slot-scope:作用是传值
  <template slot-scope="aa">
  {{aa.row.create_time|fdata}}
  </template>

~~

34-用户管理-用户状态开关

在组件中找到Switch 开关,然后使用slot-scope传递数据

36-用户列表-分页组件Pagination 分页

该接口支持分页 url参数如果有pagenum pagesize表示支持

  1. @size-change 每页显示条数变化时 触发
  2. @current-change 当前页改变时 触发
  3. current-page 设置当前页是几页
40-用户列表-添加用户-显示对话框
  1. 引入Dialog 对话框,
  2. 点击添加用户的按钮->显示对话框this.dialogFormVisibleAdd = true
  3. 配置对话框

关于子传父,父传子,中间人模式,中央总线

注意:父传子通过属性,子传父通过事件

父传子
  1. 子传父可以直接通过属性进行传递
  2. 父传子需要通过事件进行传输
    1. 首先通过组件,在组件里面使用this.$emit(‘事件’,数据),然后再html组件中调用事件,然后设置一个方法,此时这个方法里面包含着数据,再通过在父组件中调用方法就可以获取数据

// 2.
// 在HTML中写的
<navbar @myevent="handEvent"></navbar>

// 1.
// 在js中的组件中写的
 methods:{
  handclick(){
    console.log('11')
    // ! 子传父..这个的意思是监听myevent事件
    // 子组件通过emit传输 2、通过自定义组件传输 
    this.$emit("myevent",1000)
    }
  }

// 3.
// 在根组件中写的
  methods:{
    handEvent(data){
      console.log('父组件',data)
    }
  }
中间人模式
  • 两个子组件之间传递数据的时候,是先把数据传输到父组件,然后再传输到另一子组件,谁需要把数据传出去就用$emit。
  1. 组件A为父组件,BC为子组件,组件A通过fetch把数据从后台拿过来,然后可以直接传递给B组件使用。
  2. B组件里面可以进行:mydata="item"把数据传入到组件里面,然后就可以在组件里面进行操作。
  3. 在B组件里面设置一个this.$emit(’**’, ***)可以把数据传出去
  4. 在B组件上添加事件函数,把数据传输到父组件上。
  5. 在父组件上把数据存储上,然后C组件就可以直接调用里面的数据了
<div id="box">
        <button @click="handleajax">ajax</button>
        <films-item v-for="item in datalist" :key="item.filmId" :mydata="item"
         @myevent="handevent"></films-item>
        <films-detail :filmsdata="filmmyData"></films-detail>

    </div>

    <script>
        Vue.component('filmsItem', {
            props:['mydata'],
            template: `
                <div class='item'>
                    <img :src='mydata.poster'>
                       {{mydata.name}} 
                       <div>
                        <button @click='handclick'>详情</button>
                        </div> 
                </div>
            `,
            methods: {
                handclick() {
                    console.log(this.mydata.synopsis)
                    this.$emit('myevent',this.mydata.synopsis)
                }
            }
        })
/* - ----------------------------------- - */
        Vue.component('filmsDetail',{
            props: ['filmsdata'],
            template:`
                <div class='info'>
                    {{filmsdata}}
                </div>
            `,
        })
        new Vue({
            el: '#box',
            data: {
                datalist: [],
                filmmyData:''
            },
            methods: {
                handleajax() {
                    // ! get请求用的
                    fetch('/sucai/maizuo.json')
                        .then(res => res.json())
                        .then(res => {
                            console.log(res.data.films)
                            this.datalist = res.data.films
                        })
                },
                handevent(data){
                    console.log('父组件定义',data)
                    this.filmmyData=data
                }
            }

        })
    </script>
中央事件总线

中央事件总线指的是在组件B中通过bus. e m i t ( ) 进 行 触 发 获 取 数 据 , 然 后 在 组 件 A 中 通 过 b u s . emit()进行触发获取数据,然后在组件A中通过bus. emit()Abus.on()获取数据 bus. o n 监 听 ∗ ∗ 。 ∗ ∗ b u s . on监听**。**bus. onbus.emit触发

用户列表

41-用户列表-添加用户-发送请求-处理响应
  1. post this.form
  2. 关闭对话框
  3. 清除文本框this.form={}
  4. 更新视图
  5. 提示框

post status === 201 表示添加成功了

42-用户列表-删除功能-打开确认框
  1. 在methods中添加MessageBox 弹框
  2. 点击确定->执行then
  3. 点击取消->执行catch
45-用户;列表-编辑用户-显示对话框

使用的是添加用户同样的模板

  1. 找到编辑按钮@click
  2. 打开对话框
  3. 把之前添加对话框进行赋值 - 性韩国海
46-用户管理-用户列表-编辑数据-显示编辑数据
  1. 点击edit编辑按钮 scope.row获取数据
  2. 在showEditUserDia方法中 this.form = user user其实是scope.row
  3. 用户名 禁用 disabled
46-用户管理-编辑用户-发送请求
  1. 找到对话框确认按钮 -> editUser()->发送请求
  2. this.form.id

先点编辑,再点添加,则添加对话框中就会有数据,因此要在添加按钮点击事件中加上清空事件

47-用户管理-修改用户状态
  1. 找到开关 @change=“changeMgState(bbb.row)”,注意:这个是在组件里面的,因此要查看组件是否支持change事件。
  2. changeMgState(){发送put请求}
 // 请求路径:users/:uId/state/:type
      // 请求方法:put
      const res = await this.$http.put(`users/${user.id}/state/${user.mg_state}`)
48-用户管理-用户列表-分配角色演示
  1. 点击按钮 打开对话框
  2. 对话框中有下拉框
  3. 修改当前用户的角色
  4. 每个角色的权限
49-用户管理-用户列表-分配角色
  1. 点击操作中的按钮 -> 打开对话框
  2. 引入Dialog 对话框下拉框

下拉框的特性:如果select绑定的数据的值和option的value的值一样,此时显示的是该option的label的值

50-用户管理-用户列表-分配角色
<el-select v-model="currRoleId">
              <el-option label="请选择" :value="-1"></el-option>
              <el-option :label="item" :value="index" v-for="(item,index) in 5" :key="index"></el-option>
            </el-select>
51-用户管理-用户列表-分配角色-显示当前角色
  1. 在点击分配角色按钮的时候,通过const rol = await this.$http.get(roles)获得所有角色类型的信息。
  2. 才data()中创建roles用来存储角色类型的数据的信息,通过this.roles = rol.data.data把获取的数据存入roles中。
  3. 角色类型对应的是rid的数据。
// 获取当前角色的id
    const res = await this.$http.get(`users/${user.id}`)
    // 获取当前用户的角色的角色名的id
    this.currRoleId = res.data.data.rid
  1. 在组件中通过遍历显示出每个数据的对应的角色类型
52-用户管理-用户列表-分配角色-修改用户角色
  1. 在分配用户角色的面板中添加setRole点击事件,当点击确定的时候就可以提交修改后的数据
  2. 需要注意的是修改用户的角色是通过修改rid实现的。

async setRole () {
      // 请求路径:users/:id/role
      // 请求方法:put
      const res = await this.$http.put(`users/${this.currUserId}/role`, {
        rid: this.currRoleId
      })
      // console.log(res)

      // 关闭窗口
      this.dialogFormVisibleRole = false
    }

权限管理

55-权限管理-创建分支-功能演示
  1. 权限管理
    1.1 角色列表 - 展开行+属性结构
56-权限管理-权限列表-自定义面包屑组件
  1. 很多组件都用面包屑,因此我们为了代码简洁,要对面包屑进行封装
  2. 新建面包屑.vue文件,制作面包屑组件
  3. 要在各个文件中都能用就在main.js中引用。使用Vue.component(‘myBread.name’, myBread)进行引用。
57-权限管理-权限列表-获取权限列表数据

除了登录之外的所有请求 都需要设置头部信息
type参数值是list 这是后台文档规定的

// 获取token
      const autoToken = localStorage.getItem('token')
      axios.defaults.headers.common['Authorization'] = autoToken
58-权限管理-权限列表-axios拦截器统一设置请求头

除登录信息外的所有请求,都需要设置头部信息
在请求发起之前,要添加头部->看axios文档
请求拦截器 config.header
响应拦截器(还没用)

在http.js中添加拦截器
 // 添加请求拦截器 config就是配置项
  axios.interceptors.request.use(function (config) {
    console.log('拦截器触发')
    console.log(config)
    // 在发送请求之前做些什么 比如添加token,开启加载动画
    if (config.url !== 'login') { // 排除登录界面的token
      const autoToken = localStorage.getItem('token')
      config.headers.common['Authorization'] = autoToken
    }
    return config
  }, function (error) {
  // 对请求错误做些什么
    return Promise.reject(error)
  })
59-权限管理-权限列表-表格展示
  1. 引入Table 表格组件,然后绑定数据rightList
60-权限管理-权限列表-列表显示-层级显示
<el-table-column prop="level" label="层级" width="180">
        <template slot-scope="scope">
          <span v-if="scope.row.level==='0'">一级</span>
          <span v-if="scope.row.level==='1'">二级</span>
          <span v-if="scope.row.level==='2'">三级</span>
        </template>
      </el-table-column>
67-权限管理-角色列表-表格展示-展开行功能-一级权限
  1. 展开行功能把角色的权限分为三级
  2. 页面布局如果是行列问题使用 for循环 或者 v-for循环嵌套el-tag
<el-table-column type="expand" width="100">
  <template slot-scope="scope">
    <el-row v-for="(item1,index) in scope.row.children" :key="index">
      <el-col :span="4">
        <el-tag>{{item1.authName}}</el-tag>
      </el-col>
      <el-col :span="20">
        <el-row>
          <el-col :span="4"></el-col>
          <el-col :span="20"></el-col>
        </el-row>
      </el-col>
    </el-row>
  </template>
</el-table-column>
70-权限管理-角色列表-表格展示-展开行功能-权限代码
 <template slot-scope="scope">
  <el-row v-for="(item1,index) in scope.row.children" :key="index">
    <el-col :span="4">
      <el-tag closable type="success">{{item1.authName}}</el-tag>
      <i class="el-icon-arrow-right"></i>
    </el-col>
    <el-col :span="20">
      <!--el-row为行展示  -->
      <el-row v-for="(item2,index) in item1.children" :key="index">
        <el-col :span="4">
          <el-tag closable type="warning">{{item2.authName}}</el-tag>
          <i class="el-icon-arrow-right"></i>
        </el-col>
        <!-- el-col列展示 -->
        <el-col :span="20">
          <el-tag closable v-for="(item3,index) in item2.children" :key="index">{{item3.authName}}</el-tag>
        </el-col>
      </el-row>
    </el-col>
  </el-row>
  <!-- 无权限的提示 -->
  <span v-if="scope.row.children.length===0">未分配权限</span>
</template>
74-权限管理-角色列表-表格展示-展开行功能-取消权限代码

点击x按钮 取消该角色的权限

  1. 给el-tag加上@close=“delRight(scope.row.id,item2.id)” 事件
  2. delRight (roleId, rightId){发送请求}
  3. const res = await this. h t t p . d e l e t e ( ‘ r o l e s / http.delete(`roles/ http.delete(roles/{roleId}/rights/${rightId}`)
  4. 取消权限的优化使用的是role.children = res.data.data更新children的数据
78-权限管理-角色列表-表格展示-修改权限-配置数据

树形结构 引入element-ui中的Tree 树形控件
data-数据源。
show-checkbox-选择框。
node-key=“id”-每个节点的唯一标识,通常指data数据源中的key名id
default-expanded-keys-默认展开的节点。
default-checked-keys-要选择的节点id
props-配置项{label,children}。label节点的文字标题和children节点的子节点,值都来源于data绑定的数据
注意:属性空间props中会自动向里面循环执行

<el-tree :data="treeList" show-checkbox node-key="treeList.id" :props="{label: 'authName',children: 'children'}">
79-权限管理-角色列表-表格展示-修改权限-树形结构-展开所有项

树组件中default-expand-all展开所有项

80-权限管理-角色列表-表格展示-修改权限-树形结构-显示角色拥有的权限
  1. :default-checked-keys="arrCheck"是获取数据中选中的数据
  2. 通过下面代码遍历后台中有的权限,然后赋值给arrCheck,这样就成功了
  3. 注意:外面两层遍历不写是因为如果写了,那么第一二层的数据就会直接被选中,而没有半选的状态

var arrTemp2 = []
      role.children.forEach((item1) => {
        // arrTemp2.push(item1.id)
        item1.children.forEach((item2) => {
          // arrTemp2.push(item2.id)
          item2.children.forEach((item3) => {
            arrTemp2.push(item3.id)
          })
        })
      })
      this.arrCheck = arrTemp2
81-权限管理-角色列表-表格展示-修改权限-树形结构-分配权限-分析与实现
  1. 点击对话框的确定,发送请求
  2. 给确定按钮添加点击事件,当点击的时候获取到修改权限,但是修改权限需要向后台传递两个数据,一个是角色的ID,另一个是权限的id。
  3. 角色id可以在分配权限按钮的事件中获取,然后存放到data(){}中,这样在确定按钮事件中就可以获取了
  4. 获取到权限的id比较复杂。使用的是js的方法,ref和$refs。
    1. 通过给el-tag添加ref="tree"获取到el-tag节点。
    2. 通过let arr1 = this. r e f s . t r e e . g e t C h e c k e d K e y s ( ) 获 取 全 选 的 数 组 , 这 是 组 件 里 面 的 方 法 , 调 用 这 个 方 法 采 用 的 是 r e f 和 refs.tree.getCheckedKeys()获取全选的数组,这是组件里面的方法,调用这个方法采用的是ref和 refs.tree.getCheckedKeys()refrefs。
    3. 通过let arr2 = this.$refs.tree.getHalfCheckedKeys()获取半选的数组,getHalfCheckedKeys 这是组件里面的方法,
    4. 把获取的两个数据合并let arr = […arr1, …arr2]
  5. 这样所需的都已经完成了,接下来就是传递数据 const res = await this. h t t p . p o s t ( ‘ r o l e s / http.post(`roles/ http.post(roles/{this.currRoleId}/rights`, {rids: arr.join(’,’)})
  6. 更新视图,关闭权限框
82-首页-侧边栏-动态导航
  1. 在home中修改,实现动态导航栏功能
  2. 获取导航栏数据。之后的导航栏的路径就不能随意起名字了。
  // 获取导航数据
    async getMonus () {
      const res = await this.$http.get(`menus`)
      this.menus = res.data.data
      console.log(this.menus)
    }
84-导航守卫
  1. 在home.vue中判断token很麻烦
  2. 使用路由的导航守卫
// 在路由配置生效之前 统一判断token
// 路由/导航 守卫
/*
to:进入到哪个路由去。要去的路由配置
from:从哪个路由离开。当前的路由配置
next:路由的控制参数,常用的有next(true)和next(false)
*/
// !路由守卫
router.beforeEach((to, from, next) => {
  // 如果要去的是登录->next
  // 如果要去的不是登录,就需要判断token,如果有token就next,没有就返回login
  if (to.path === '/login') {
    next()
  } else {
    const token = localStorage.getItem('token')
    if (!token) {
      message.warning('回到登录页')
      router.push({
        name: 'login'
      })
      return
    }
    next()
  }
})
87-商品管理-添加商品-配置路由
  1. 创建goodsAdd.vue用来制作添加商品的功能
88-商品管理-添加商品-步骤条

添加面包屑,警示条,步骤条这三个组件
其中步骤条中的:active="1"表示当前所处的步骤
添加Tabs 标签页,这样能够在侧面进行显示操作

<!-- 进度条 -->
      <el-steps :active="active" finish-status="success" simple style="margin-top: 5px">
        <el-step title="基本信息"></el-step>
        <el-step title="商品参数"></el-step>
        <el-step title="商品属性"></el-step>
        <el-step title="商品图片"></el-step>
        <el-step title="商品内容"></el-step>
      </el-steps>
      <!-- 绑定v-model是为了获取name对应的值 -->
      <el-tabs v-model="active" tab-position="left" style="height: 200px;">
        <el-tab-pane name="1" label="基本信息">基本信息</el-tab-pane>
        <el-tab-pane name="2" label="商品参数">商品参数</el-tab-pane>
        <el-tab-pane name="3" label="商品属性">商品属性</el-tab-pane>
        <el-tab-pane name="4" label="商品图片">商品图片</el-tab-pane>
        <el-tab-pane name="5" label="商品内容">商品内容</el-tab-pane>
      </el-tabs>
90-商品管理-添加商品-基本信息-表单绑定数据
  1. 最外城包裹一个el-form,调整样式overflow:auto
  2. v-model=“form”
  3. form数据的来源 添加商品的网络请求
  4. 基本信息的填写绑定
     <el-form :label-position="right" label-width="80px" :model="form" style="height:400px;overflow:auto;">
        <el-tabs v-model="active" tab-position="left">
          <el-tab-pane name="1" label="基本信息" style="margin-top:10px;">
            <el-form-item label="商品名称">
              <el-input v-model="form.goods_name"></el-input>
            </el-form-item>
            <el-form-item label="商品价格">
              <el-input v-model="form.goods_price"></el-input>
            </el-form-item>
            <el-form-item label="商品重量">
              <el-input v-model="form.type"></el-input>
            </el-form-item>
            <el-form-item label="商品数量">
              <el-input v-model="form.type"></el-input>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane name="2" label="商品参数">商品参数</el-tab-pane>
          <el-tab-pane name="3" label="商品属性">商品属性</el-tab-pane>
          <el-tab-pane name="4" label="商品图片">商品图片</el-tab-pane>
          <el-tab-pane name="5" label="商品内容">商品内容</el-tab-pane>
        </el-tabs>
      </el-form>
商品管理-添加商品-基本信息-级联选择器
 <!-- 级联选择器 -->
<el-cascader  表单元素
  expand-trigger="hover"
  v-model="selectedOptions" 最终选择的label对应的 value会 在selectedOptions数组中
  :options="options" = 数据list[]
  :props="defaultProp" ={label:?,value:,children:?}
  @change="handleChange" 选择改变时触发
></el-cascader>
list:[
  {
    label:'家电',
    value:1,
    childre:{
      label:'a家电',
      value:100,
      childre:[]
    }
  }
]
92-商品管理-添加商品-基本信息-级联选择器-获取分类数据
  1. 写getGoodCate获取三级分类信息const res = await this.$http.get(categories?type=3)
  2. 在created(){}中调用。
options: [],
selectedOptions: [],
defaultProp: {
        label: 'cat_name',
        value: 'cat_id',
        children: 'children'
      }
<el-cascader
  expand-trigger="hover"
  :options="options"
  v-model="selectedOptions"
  :props="defaultProp"
  @change="handleChange"
></el-cascader>

上述中this.options = res.data.data把数据传给option中,数据再通过:props="defaultProp"进行过滤,过滤后的数据传递给selectedOptions

93-商品管理-添加商品-商品参数-级联选择器-获取动态参数数据
  1. 必须先选择三级分类,然后才能获取分类的数据
  2. 为了判断是否选择了三级分类,因此在点击下一项的时候会对三级分类进行检查,通过给el-tag添加tabChange()点击事件,在点击事件中进行监控。
// 点击不同的tab时
async tabChange () {
  // 如果点击第二个tab' 同时三级分类要有值
  if (this.active === '2') {
    if (this.selectedOptions.length !== 3) {
      // 必须要选三级分类
      this.$message.warning('请先选择商品的三级分类')
      return
    }
    // 获取数据
    const res = await this.$http.get(`categories/${this.selectedOptions[2]}/attributes?sel=many`)
    console.log(res)
  }
}
94-商品管理-添加商品-商品参数-复选框组-文档引入
  1. 商品参数->动态参数数据->this.arr
  2. el-form-item+复选框组
  3. v-for遍历
  4. item.attr_vals = item.attr_vals.length === 0 ? [] : item.attr_vals = item.attr_vals.trim().split(’,’)
96-商品管理-添加商品-商品属性-获取静态参数

如果选中了第三个tab,const res = await this. h t t p . g e t ( ‘ c a t e g o r i e s / http.get(`categories/ http.get(categories/{this.selectedOptions[2]}/attributes`, {params: {sel: ‘only’}})获取静态数据

98-99-商品管理-添加商品-图片上传
  1. 在element-UI中找到Upload 上传组件
    1. action:全路径
    2. :on-remove=‘移除触发的方法’
    3. :on-preview=‘’
 <!-- 图片上传 -->
<el-upload
  class="upload-demo"
  action="https://jsonplaceholder.typicode.com/posts/
  :headers="headers"
  :on-preview="handlePreview"
  :on-remove="handleRemove"
  :file-list="fileList"
  list-type="picture"
>
      <!-- 设置头部 -->
      <!-- baseUrl 是axios发送的,此处用的不是axios方式发送的,所以要写全路径 -->
              <!-- 添加headers是因为除了登录界面,其他的请求都要获取token -->
      headers: {
        Authorization: localStorage.getItem('token')
      }
100-商品管理-添加商品-富文本编辑器
  1. 安装富文本编辑器npm i vue-quill-editor --save
    富文本编辑器
  2. 通过代码进行局部注册

找资源可以在npm和vue的资源列表中进行查找

102-商品管理-添加商品-表单数据处理-分类和图片
  1. 在点击添加按钮的事件中添加分类数据的获取,因为获取的分类数据中要用’,隔开,索引进行处理 this.form.good_cat = this.selectedOptions.join(’,’)
  2. 图片的获取就比较麻烦了
    1. 在图片成功的事件中handleSuccess()获取图片的路径
// 图片成功
    handleSuccess (file) {
      console.log('成功', file)
      // 给this.form.pics添加数据
      this.form.pics.push({
        pic: file.data.tmp_path
      })
 2. 删除图片的时候比较麻烦,采用splice(索引,个数)的方式进行删除,首先需要获取到要删除的图片的索引值,然后执行splice进行删除
 // 图片删除
    handleRemove (file) {
      console.log('移除', file)
      // 给this.form.pics删除当前X的图片
      // ! findIndex()遍历 把符合条件的元素的索引进行返回
      let index = this.form.pic.findIndex(item => {
        return item.pic === file.response.data.tmp_path
      })
      this.form.pics.splice(index, 1)
    }
108-商品管理-分类参数-动态参数-删除和添加-发送请求
 async handleClose (attr, id, name, tag) {
      // 删除标签
      attr.splice(this.dynamicTags.indexOf(tag), 1)
      // 发送请求
      let putData = {
        attr_name: name,
        attr_sel: 'many',
        attr_vals: attr.join(',')
      }
      const res = await this.$http.put(`categories/${this.selectedOptions[2]}/attributes/${id}`, putData)
      console.log(res)
    },
120-数据统计-echart文档引入
  1. 下载npm install echarts --save
  2. 导入
  3. 视图 提供一个容器
  4. myechart.init(容器)
  5. 配置选项(配置数据)option
  6. mychart.setOption(option)

项目优化

  1. 生成打包报告
  2. 第三方库启用CDN
  3. element-ui组件按需加载
  4. 路由懒加载
  5. 首页内容定制

可以用vue ui面板进行创作脚手架

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值