Vue 重构有赞商城

Vue.js 重构移动端有赞商场

代码链接:GitHub

预览链接:Git Pages

本项目的开发让我了解并学习到以下几点:

1.在真实的开发工作环境与流程,一些项目结构的处理,让其更容易维护

2.数据接口的封装与切换,与上下游更好地协作

3.webpack 配置参数的一些原理和技巧

4.在前端开发过程中 mock 数据,更好地进行测试

5.更全面地了解 Vue / vue-router / vuex 等

6.在项目开发过程使用了一些库:qs / Swiper / mint-ui / ...

7.把静态页面使用 Vue 重构

实现功能:

首页 展示轮播图和商品列表

分类页 展示不同商品的推介列表

商品详情页 显示商品信息(包括价格、图片、详情等),可增加商品数量并加入购物车

购物车 可增加商品数量,对商品可删除、批量删除,价格实时演算

个人页面 可管理个人收收货地址(包括删除、增加、修改、设为默认地址等)

页面渲染流程:

API 拿到数据 -> 渲染页面

没有真实数据的情况下 -> Mock 数据 -> 使用 API 拿到数据 -> 渲染页面

页面重构:

把原 HTML 的内容放进对应的 Vue 组件中,引入 CSS,确定样式,再获取数据,渲染页面。

接下来归纳整理一下开发过程中学习到的知识点和踩的坑。



项目构建方面处理:在使用 vue-cli 构建项目后对目录结构和 webpack 配置做一个调整。

多页面应用调整

基于 vue-cli 把单页面应用搭建成多页面应用:

  • 修改目录结构
  • 修改 webpack 配置

commit

参考:

基于vue-cli搭建一个多页面应用

基于vue-cli重构多页面脚手架


webpack

build/webpack.base.conf.js 中的 resolve 可以设置路径或模块的别名:

  ......
  resolve: {
    extensions: [‘.js‘, ‘.vue‘, ‘.json‘],
    alias: {
      ‘vue$‘: ‘vue/dist/vue.esm.js‘,
      ‘@‘: resolve(‘src‘),
      ‘components‘: ‘@/components‘,
      ‘pages‘: ‘@/pages‘,
      ‘js‘: ‘@/modules/js‘,
      ‘css‘: ‘@/modules/css‘,
      ‘sass‘: ‘@/modules/sass‘,
      ‘imgs‘: ‘@/modules/imgs‘
    }
  }
  ......

在其他地方引用:

import Hello from ‘components/Hello‘

参考:[webpack resolve]


首页

<!-- DNS预解析 -->
<link rel="dns-prefetch" href="https://dn-kdt-img.qbox.me/">
<link rel="dns-prefetch" href="https://img.yzcdn.cn/">
<link rel="dns-prefetch" href="https://b.yzcdn.cn/">
<link rel="dns-prefetch" href="https://su.yzcdn.cn/">
<link rel="dns-prefetch" href="https://h5.youzan.com/v2/">
<link rel="dns-prefetch" href="https://h5.youzan.com/">

能够减少用户点击链接时的延迟。

  • mock 数据接口的处理

在真实开发环境中,前端需要通过 API 接口获取数据,从而把数据渲染在页面上,那么可以这样写:

// api.js
// 开发环境和真实环境的切换
let url = {
    hotLists:‘/index/hotLists‘,
    banner:‘/index/banner‘
}
let host =  ‘http://rap2api.taobao.org/app/mock/7058‘
for (let key in url){
    if(url.hasOwnProperty(key)){
        url[key] = host + url[key]
    }
}
export default url

先使用 mock 数据的接口获取数据,进行开发和测试,在与后端对接的时候再替换真实的数据接口。

  • mint-ui

问题 使用命令 npm i mint-ui -S 安装了 mint-ui 后,在 babelrc 中做了相应的配置,引用后报错,提示找不到模块:

解决办法:npm start 重启服务器。

  • Infinite scroll

使用 mint-ui 的 Infinite scroll,使页面的推荐商品列表下拉到底部时可以自动获取并加载数据,实现无限滚动。

commit

  • 轮播组件

使用 Swiper 实现首页轮播组件:

1.在首页组件中,在 created 阶段获取 banner 的数据

2.通过 props 传递数据给 swipe 组件

3.swiper 接收数据,渲染到模板中,完成轮播

但是其中要注意数据获取和生命周期的问题:

因为 swipe 组件中的 Swiper 插件依赖于 dom 节点,而 dom 节点是在 mounted 时被挂载的,这也就要求了在 swipe 组件中,当生命周期来到 mounted 的时候,他必须拿到数据,才能使 Swiper 组件拿到 dom 节点,操作轮播;当父组件中通过(异步)获取到 banner 的数据并传递给 swipe 组件时,可以在父组件中做如下设置:

<!-- index.html -->
<swipe :lists=‘bannerLists‘ v-if=‘bannerLists‘></swipe>

只有在 bannerLists 数据不为 null 的时候,这个 swipe 的组件才可以显示,这也就保证了数据可以正常传递, Swiper 也可以在 mounted 的时候拿到 dom 节点。

问题 使用 npm run dev 打开 http://localhost:8080/#/ 调试代码时,总是一刷新就进入 debugger 状态:

解决办法:

1.打开 source 面板,把 Any XHR 勾选去掉

2.paused on exception


URL跳转

从分类页跳转到列表页:

1.传递参数及跳转

// category.js
toSearch(list){
    location.href = `search.html?keyword=${list.name}$id=${list.id}`
}

2.使用 qs 读取url参数:

// search.js
import qs from ‘qs‘

let {keyword,id} = qs.parse(location.search.substr(1))

mixin

混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。

把一些公用的函数/方法抽离出来,放进 mixin.js:

// mixin.js
import Foot from ‘components/Foot.vue‘
let mixin = {
    filters:{
        number(price){
            return price = price.toFixed(2)
        }
    },
    components:{
        Foot,
    },
}
export default mixin

在组件中引用 mixin:

import mixin from ‘js/mixin‘
new Vue({
    ...
    mixins:[mixin]
    ...
})

这样就可以直接在组件中对函数/方法进行复用了。


velocity

使用 velocity 实现「回到顶部」动画过渡:

安装:npm i velocity-animate

引用:import Velocity from ‘velocity-animate‘

使用:

new Vue({
    ...
    methods:{
        toTop(){
            // 第一个参数:动作元素 第二个参数:动作事件
            Velocity(document.body,‘scroll‘,{duration:1000})
        }
    }
})

touchmove

问题:使用 touchmove 监听页面:

<div class="container with-top-search" style="min-height: 667px;" @touchmove=‘move‘>...</div>

根据距离页面顶部距离的大小,确定某个元素是否展现:

data:{
    toShow:false
},
move(){
    if(document.documentElement.scrollTop > 100){
        console.log(1)
        this.toShow = true
    }else{
        console.log(2)
        this.toShow = false
    }
},

页面划动是有效的,但是结果一直取不到 document.body.scrollTop 的值。

解决方法:使用 document.documentElement.scrollTop

由于在不同情况下,document.body.scrollTop与document.documentElement.scrollTop都有可能取不到值

参考文章:https://segmentfault.com/a/1190000008065472


详情页

  • 轮播组件共用

在项目首页中,有一个图片轮播组件,用于展示一个具体商品,点击会跳转到不同的页面;

而在详情页中,也有一个商品图片轮播,项目需要这个组件继续沿用首页的轮播组件,但是他的图片、点击后跳转、通过 API 所获取的数据结构均和首页轮播组件不同,这时候该怎么处理传入轮播组件的数据:

1.首先应该分析一下轮播组件需要接收的数据:一个数组,数组里包含 N 个对象,包含键 clickUrl(值为点击图片后跳转的的url)和键 img(值为图片url)

2.对 API 获取的将要传入的数据做一层处理,让轮播组件只接收一种统一的格式:

new Vue({
    el:‘#app‘,
    data:{
        details:null,
        detailTab,
        currentTab:0,
        dealList:null,
        bannerLists:null
    },
    created(){
        this.getDetails()
    },
    methods:{
        getDetails(){
            axios.get(url.details,{id}).then(res=>{
                // 通过API获取的原数据 details
                this.details = res.data.data
                // 需要传入组件的数据 bannerLists
                this.bannerLists = []
                this.details.imgs.forEach(item => {

                    // 把 bannerLists 数组中的值改为对象
                    this.bannerLists.push({
                        clickUrl:‘‘,
                        img:item
                    })
                })
            })
        },
    },
})

最后再把数据传递给轮播组件:<swipe :lists=‘bannerLists‘ v-if=‘bannerLists‘></swipe>


购物车

当线上接口平台连接不稳定的时候,可以使用 mockjs 模拟 mock 数据。

安装:npm i mockjs

引入:

import Mock from ‘mockjs‘

let Random = Mock.Random

let data = Mock.mock({
    ‘cartList|3‘:[{
        ‘goodsList|1-5‘:[{
            id:Random.int(10000,100000),
            img:Mock.mock(‘@Img(90x90,@color)‘)
        }]
    }]
})

console.log(data)

  • $refs

场景:在购物车页面,向左划动商品栏时出现相关操作按钮(增减商品数量,删除);向右划动恢复原状。

在元素上绑定 touchstart 和 touchend 事件,并设置 ref 值用于获取需要操作的商品节点:

<li class="block-item block-item-cart "
    v-for="(good,goodIndex) in shop.goodsList"
    :class="{editing:shop.editing}"
    :ref="‘goods-‘+ shopIndex + ‘-‘ + goodIndex"
    @touchstart="start($event,good)"
    @touchend="end($event,shopIndex,good,goodIndex)">...</li>

配合 velocity ,根据划动距离操作节点:

methods:{
    ...
    start(e,good){
        // 拿到初始值的坐标
        good.startX = e.changedTouches[0].clientX
    },
    end(e,shopIndex,good,goodIndex){
        // 拿到结束值的坐标
        let endX = e.changedTouches[0].clientX
        let left = ‘0‘
        if(good.startX - endX > 100){
            left = ‘-60px‘
        }
        if(endX - good.startX > 100){
            left = ‘0px‘
        }
        // 使用 velocity 操作节点
        Velocity(this.$refs[`goods-${shopIndex}-${goodIndex}`],
            {left})
    }
    ...
}

问题:当商品列表中的某款商品被删除后,某些样式会继续残留在该列表的下一款商品中,如:

问题原因: 商品列表使用了 v-for 来渲染,而v-for 模式使用“就地复用”策略,简单理解就是会复用原有的dom结构,尽量减少dom重排来提高性能,当商品删除后,列表中的剩余商品就会复用被删除商品的 dom 结构,所以会产生这种现象。

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。

解决方法:

1.在删除了商品后,重新操作节点,返回原来的位置(还原dom)。this.$refs[`goods-${shopIndex}-${goodIndex}`][0].style.left = ‘0px‘

2.给遍历的节点设置一个唯一的 key 属性:

<li v-for="(good,goodIndex) in shop.goodsList" :key="good.id"></li>

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的唯一 id。

  • 封装请求接口

在真实开发过程中,对请求接口进行封装,方便调用。

// fetch.js
import url from ‘js/api.js‘
import axios from ‘axios‘

function fetch(method=‘get‘,url, data) {
    return new Promise((resolve, reject) => {
        axios({method, url, data}).then(res => {
            let status = res.data.status
            if (status === 200) {
                resolve(res)
            }
            if (status === 300) {
                location.href = ‘login.html‘
                resolve(res)
            }
        }).catch(err => {
            reject(err)
        })
    })
}
export default fetch
  • 封装购物车操作

在具体场景中,把对于数据请求的操作放在 Service 中,在别的地方调用的时候传参即可:

// cartService.js
import url from ‘js/api.js‘
import fetch from ‘./fetch.js‘

class Cart {
    // 增加商品数量
    static add(id){
        return fetch(‘post‘,url.cartAdd,{
            id,
            number:1
        })
    }
    // 减少商品数量
    static reduce(id){
        return fetch(‘post‘,url.cartReduce,{
            id,
            number:1
        })
    }
    // 删除商品
    static remove(id){
        return fetch(‘post‘,url.cartRemove,{id})
    }
}
export default Cart

这样就可以省略很多步骤,也让流程更为清晰:

import Cart from ‘js/cartService.js‘
add(good){
    // axios.post(url.cartAdd,{
    //     id:good.id,
    //     number:1
    // }).then(res=>{
    //     good.number++
    // })
    Cart.add(good.id).then(res=>{
        good.number++
    })
},

个人页面

路由管理 / 嵌套路由:

在「会员页面」下有「我的设置」和「收货地址管理」,「收货地址管理」下有子路由「地址列表」和「新增/编辑地址」,进入「收货地址管理」默认重定向到「收货地址列表」:

import Vue from ‘vue‘
import Router from ‘vue-router‘
Vue.use(Router)
let routes = [
    {
        // 默认显示页面
        path:‘/‘,
        components:require(‘./components/member.vue‘)
    },
    {
        // 收货地址管理
        path:‘/address‘,
        components:require(‘./components/address.vue‘),
        children:[
            {
                path:‘‘,
                redirect:‘all‘
            },
            {
                // 地址列表
                path:‘all‘,
                components:require(‘./components/all.vue‘)
            },
            {
                // 新增/编辑地址
                path:‘form‘,
                components:require(‘./components/form.vue‘)
            }
        ]
    }
]
let router = new Router({
    routes
})
new Vue({
    el:‘#app‘,
    router
})
  • 组件共用

因为「新增地址」和「编辑地址」所用的组件时同一个,所以就要在进入组件的路由参数上做一些设置,让组件可以区分用户是需要「新增地址」还是「编辑地址」。

1.首先完善路由信息,增加 name 字段:

{
    path:‘form‘,
    name:‘form‘,
    components:require(‘./components/form.vue‘)
}

2.根据不同的需求,路由跳转携带不同的参数:

// 新增地址 type 为 add
<router-link :to="{name:‘form‘,query:{type:‘add‘}}" >新增地址</router-link>

// 编辑地址 type 为 edit,同时接收一个实例参数:选择需要修改的地址信息
<a @click="toEdit(list)"></a>
toEdit(list){
    this.$router.push({name:‘form‘,query:{
        type:‘edit‘,
        instance:list
    }})
}

3.同时给组件设置一些初始值,用于 v-model 绑定数据,提交修改:

export default {
    data(){
        return {
            name:‘‘,
            tel:‘‘,
            provinceValue:-1,
            cityValue:-1,
            districtValue:-1,
            address:‘‘,
            id:‘‘,
            type:‘‘,
            instance:‘‘
        }
    },
    created() {
        let query = this.$route.query
        this.type = query.type
        this.instance = query.instance
        if(this.type === ‘edit‘){
            let ad = this.instance
            this.provinceValue = parseInt(ad.provinceValue)
            this.name = ad.name
            this.tel = ad.tel
            this.address = ad.address
            this.id = ad.id
        }
    },
}

接着根据需求渲染数据即可。


状态管理(Vuex)

在「个人地址管理页面」中使用 vuex 管理状态和数据:

1.首先创建 store,其中包含一些初始值的设置、获取数据的方法、更改状态和数据的方法

// vuex/index.js
import Vue from ‘vue‘
import Vuex from ‘vuex‘
import Address from ‘js/addressService.js‘
Vue.use(Vuex)
const store = new Vuex.Store({
    state:{
        lists:null
    },
    mutations:{
        init(state,lists){
            state.lists = lists
        }
    },
    actions:{
        getLists({commit}){
            Address.list().then(res=>{
                // this.lists = res.data.lists
                store.commit(‘init‘,res.data.lists)
              })
        }
    }
})
export default store

2.注入 Vue 实例:

import Vue from ‘vue‘
import router from ‘./router/index.js‘
import store from ‘./vuex‘
import ‘./member.css‘

new Vue({
    el:‘#app‘,
    router,
    store
})

3.先在 created 阶段执行this.$store.dispatch(‘getLists‘),更新数据到 state,然后通过 computed 拿到 state 中的 数据,在组件中渲染数据渲染:

created() {
    // Address.list().then(res=>{
    //   this.lists = res.data.lists
    // })
    this.$store.dispatch(‘getLists‘)
},
computed:{
    lists(){
    return this.$store.state.lists
    }
}

深度监听/深拷贝

需求:在使用 vuex 管理状态和数据的过程中,有一些对于数据列表的增删改的操作,每当完成这些操作后页面需要跳转到某个页面。

方法:使用 watch 监听数据列表,一旦监测到数据列表增减,则跳转。

在实际过程中,数据的增减确实是可以引发跳转行为,但是列表中(列表项是对象)某个属性的更改则不会引发跳转。

解决方法:

1.对数据列表进行深度监听

为了发现对象内部值的变化,可以在选项参数中指定 deep: true 。注意监听数组的变动不需要这么做。

watch:{
    lists:{
        handle(){
            this.$router.go(-1)
        },
        deep:true
    },
}

在设置了深度监听后,发现问题还是没有得到解决,那是因为监听对象是从 state 得到的 lists,当在 mutations 里对这个 lists 的成员进行其属性的某些操作的时候,依然没有监听到属性值的改变。

所以,需要对这个 lists 进行深拷贝,当拷贝对象完成对数据的处理后,再把他赋值给 state.lists:

2.对监听对象进行深拷贝

// vuex/index.js
update(state,instance){
    // 通过 instance 的 id 找到
    let lists = JSON.parse(JSON.stringify(state.lists))
    let index = lists.findIndex(item =>{
        return item.id === instance.id
    })
    lists[index] = instance
    state.lists = lists
},

热重载

vuex 配合 webpack 实现热重载功能,提高开发效率(前提:state/mutations/actions 被做为模块引入 store):

比如配置了 mutations 的热重载,你添加新的 mutations 方法的时候就不会刷新页面,而是加载一段新的js,不配页面就会刷新

/ store.js
import Vue from ‘vue‘
import Vuex from ‘vuex‘
import mutations from ‘./mutations‘
import moduleA from ‘./modules/a‘

Vue.use(Vuex)

const state = { ... }

const store = new Vuex.Store({
  state,
  mutations,
  modules: {
    a: moduleA
  }
})

if (module.hot) {
  // 使 action 和 mutation 成为可热重载模块
  module.hot.accept([‘./mutations‘, ‘./modules/a‘], () => {
    // 获取更新后的模块
    // 因为 babel 6 的模块编译格式问题,这里需要加上 `.default`
    const newMutations = require(‘./mutations‘).default
    const newModuleA = require(‘./modules/a‘).default
    // 加载新模块
    store.hotUpdate({
      mutations: newMutations,
      modules: {
        a: newModuleA
      }
    })
  })
}

部署

在将项目部署到 Git Pages 的时候,出现了一个问题:

原因是 GitPages 是 HTTPS 页面的,而调用接口获取数据的 API 是 HTTP 的,HTTPS 页面里动态的引入 HTTP 资源,比如引入一个js文件,会被直接block掉的.在 HTTPS 页面里通过 AJAX 的方式请求 HTTP 资源,也会被直接block掉的。

搜索了一下资料,按照 stackoverflow 的答案,给 index.html 的 head 加上了一个 meta 标签,意思是自动将http的不安全请求升级为https:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

产生了两个结果:

1.本地调试获取不到 index.js:

2.GitPages 中的接口转换成了 HTTPS,但是接口没有对应的 https 资源,于事无补:

所以只能买一个域名,然后配置 http 的协议,再解析到 Git Pages 上。

  • Git Pages 配置 http 域名

参考:

GitHub 绑定域名

segmentfault 绑定域名

GitHub 绑定域名

原文地址:https://www.cnblogs.com/No-harm/p/9942838.html

时间: 2024-11-09 10:11:29

Vue 重构有赞商城的相关文章

angularApi网站用vue重构

最近在博客园上看到不少关于vue的文章但感觉都是在简单原生写法上,真正vue在实际开发中的优点组件化,spa应用,路由好像都没涉及到,我在学angular1的时候发现没有中文版的api,于是本人不才弄了angular api网站方便大家学习和查询,刚好在学vue就用vue重构下这个网站,我会将我重构的所有步骤写下来,当然这个是实际开发中的步骤,可能对package.json 的讲解不那么仔细. 开发环境:node6.2 webstrom2016 vue2.0 vue-cli 第一步安装node,

webpack构建vue项目(配置篇)

最近公司要求用vue重构项目,还涉及到模块化开发,于是乎,我专门花了几天的时间研究了一下webpack这个目前来看比较热门的模块加载兼打包工具,发现上手并不是很容易,现将总结的一些有关配置的心得分享出来,欢迎大神来拍砖... 一.新建一个项目目录,cd /d 定位进去,然后输入npm init,会提示你填写一些项目的信息,一直回车默认就好了,或者直接执行npm init -y 直接跳过,这样就在项目目录下生成了一个package.json文件. 二.接下来就是通过npm安装项目依赖项,命令行输入

qt qml 利用xmlhttprequest 调用有赞api

最近朋友在有赞商城上面开了一个店铺,因为有实体店,一般卖商品后送货上门,但是打票时候老是人工用world文档人工复制黏贴订单打印小票, 所以就找我帮忙做一个软件专门打印小票的,就研究起来调用有赞第三方api来着,本篇主要介绍如何用qml中的xmlhttprequest来实现http请求协议,就以调用有赞商城api的查询订单接口为例:kdt.trades.sold.get: function searchTrades(startDate,endDate){ tradesModel.clear();

Vue.js中,如何自己维护路由跳转记录?

在Vue的项目中,如果我们想要做返回.回退操作时,一般会调用router.go(n)这个api,但是实际操作中,使用这个api有风险,就是会让用户跳出当前应用,因为它记录的是浏览器的访问记录,而不是你当前应用的访问记录,这是非常可怕的事情. 解决方案就是,我们自己来维护一份history跳转记录. 案例与使用场景 代码地址:https://github.com/dora-zc/mini-vue-mall 这是一个基于Vue.js的小型商城案例,应用场景: 自己实现一个Vue插件src/utils

关于vue ui组件

一.vue ui  组件 1: vue 当前很火前端框架vue 针对PC用户 pc 端与移动端区别 (1)屏幕宽度:992px > (2)操作方式:鼠标 事件   手指:触碰操作 -饿了么:基于VUE框架开发移动端组件库 Mint-UI -MUI :开源团队 MUI http://dev.dcloud.net.cn/mui/ -滴滴: 2: vue ui  组件mint-ui安装与使用 方式一:学习环境下载安装 下载mint-ui js/css/font 方式二:生产环境下载安装(脚手架) 下载

VUE2.0+VUE-Router做一个图片上传预览的组件

之前发了一篇关于自己看待前端组件化的文章,但是由于学习和实践的业务逻辑差异,所以自己练习的一些demo逻辑比较简单,打算用vue重构现在公司做的项目,所以在一些小的功能页面上使用vue来做的,现在写的这个是项目中用户反馈功能而来的,收获还是挺多的. 收获:dom操作=>数据操作       router的使用       组件的使用,具体总结放在尾部. 功能:1.上传图片 2.显示缩略图 3.可以删除 4.可以重新选择文件 先上成品图(主要抽取图片这块),自己在家主要做的功能,样式就不计较了.

别人的工作台系列二

12.别人的工作台系列~ 华为杭州办事处,本人室友,毕业一直蹲华为,收入很神秘,这些年咱在外面蹦跶了好几个公司还不如这哥们工资高!在华为基本没什么休假,以前一起住的时候基本看不到他人,走的比我早,我睡了还没回,辛苦就华为人能理解.常年在电信移动的场地办公,难得回下文三,由于信息安全的原因屏幕也没拍 13.别人的工作台系列~  近日大多it公司的工作台,略显单调,今换个口味.高中同窗,如今给央视打工,平时爱好各种烧钱玩意,如穷三代的单反,当我还不懂摄影时就用尼康金圈毒害我. 这套设备叫Autode

微信公众号运营人员必备的软件工具网站合集

每一个微信运营者都需要一些微信运营辅助的软件.工具.网站等,比如文章排版网站,图片处理软件,运营交流学习网站等.为了让大家运营微信公众号更轻松,小编精心为大家收集整理了如下软件工具网站合集,方便微信运营者及时保存收藏查阅. 图文.排版.微场景编辑器     秀多多:xiudodo.com     易企秀:eqxiu.com     秀米:xiumi.us     易企微:www.e7wei.com     易点编辑器:wxedit.yead.net     兔展(场景):www.rabbitpr

微商城免费时代结束,三巨头的贴身肉搏?

5月15日有赞CEO白鸦正式宣布,有赞将对新商家收费,每个有赞的新店铺在享受7天免费试用期之后,需缴纳4800元/年的服务费才能继续使用.并且在当天举办的有赞春季沙龙上白鸦称对于老商户暂不收费,但未来肯定会收费,只是怎么收还有待商定. 5月20日,移动营销服务商点点客立即推出与有赞商家版功能相差无几的点点客小店,且承诺永久免费,颇有挑衅之意. 有赞免费背后的鱼缸理论,收费是计划而非无奈 天底下没有免费的午餐,任何违背商业本质的免费模式都是耍流氓,任何一种免费模式背后都应该有支撑企业长期运作的变现