• 珠峰vue笔记


    vue 是MVVM框架

    0.p2 mvvm是双向数据绑定的框架:vue本身实现了数据和视图的相互监听影响
    mvc是单向数据绑定个,数据更改可以渲染视图,但是视图更改没有更改数据,需要我们自己在控制层基于change事件实现数据的更改(React)

    1.p3 增加对象的键值对
    vm.obj={...obj,
    name:'珠峰培训'
    }

    vm.$set(vm.obj,'name','珠峰培训')

    并不是所有的数据更改最后都会通知视图重新渲染
    初始化数据是一个对象,对象中没有xxx键值对,后期新增的键值对是不会让视图重新渲染的,解决方法:
    一,最好在初始化数据的时候,就把视图需要的数据提前声明好(可以使空值,但是要有这个属性)原理:只有在data中初始化过的属性才有GET/SET属性
    二,不要修改某个属性名,而是把对象的值整体替换(指向新的堆内存)
    三,可以基于vm.$set内置方法修改数据:vm.$set(obj,key,value)

    在胡子语法中丙丁的数据值是对象类型,会基于JSON.stringfy把其编译为字符串再呈现出来(而不是直接toString处理的)

    2.p3 如果数据是一个数组,我们修改数据基于ARR[N]=xxx或者ARR.length--等操作方法,是无法让视图重新渲染的,需要基于:
    push/pop等内置的方法
    重新把ARR的值重写(指向新的堆内存)
    vm.$set

    3.p4 v-once:绑定的数据是一次行的。后面无论怎么改变,试图都不会重新渲染
    v-if :如果对于的值是true,当前元素会显示在结构中,如果是false,当前元素会在结构中移除(dom的增加和删除)
    v-show :和v-if类似,只不过它是控制元素像是的显示
    在频繁的切换过程中,v-if 明显要比v-show要低一些

    p5 es6 新增for of 循环
    1.获取的不是属性名是属性值
    2.不会遍历原型上共有的属性方法
    3.只能遍历可被迭代的数据类型(Symbol.ineratoer):Array、String 、Arguments、NodeList、Set、Map等,但是普通对象时不可被迭代的数据,所以不能用for of循环
    for in
    可以遍历数组也可以遍历对象
    优先遍历属性名为数字的,
    会把属性类型上自定义的属性方法遍历到
    let arr = [10,20,30,40]
    Object.prototype.AA =123
    for(let key in obj){
    if(!obj .hasOwnProperty(key)) break;
    console.log(key)
    }

    p7 购物车案列 全选和非全选

    4.p8 filters只能用在v-bind 和{{}}中,filters 没有挂载到vue的实例中

    5.p9 computed会挂载到vue实例中,它存储的值是对应方法返回的结果(getter函数处理的结果)
    第一次结果获取后,会把这个结果缓存下来
    真实项目中:我们一般用一个计算属性和某些响应式数据进行关联,响应式数据发生改变,计算属性的getter函数会重新执行,否则使用的是上次计算出来的缓存结果

    vm.$forceUpdate()强制更新视图的重新渲染

    p7 p10 购物车全选和非全选案例 computed setter

    6.p11 watch当需要在数据变化时执行异步或开销较大的操作时应用监听器
    watch监听响应式数据改变(watch中监听的响应式数据必须在data中初始化)和computed中的setter类似,只不过computed是自己单独设计的计算属性(不能和data中的冲突),而watch只能监听data中有的属性
    购物车全选和非全选案列 watch

    p12 vue 绑定class ,style
    p13 选项卡案列
    p14 计算器案例
    products.map()
    reduce
    获取总价格
    totalPrice(){
    return this.productList.reduce((accumulator.item)=>{
    return accumultor + item.count*item.price
    },0)
    }
    获取最大单价
    maxPrice(){
    let arr= this.productList.filter(item=>{
    return item.count>=1
    }).map(item=>{
    return item.price
    })
    return arr.length === 0 ? 0 : Math.max(...arr)
    }


    7.p15 beforeCreate 创建vue实例之前
    created 创建实例成功(一般在这里实现数据的异步请求)
    beforeMount 渲染dom之前(加载组件第一次渲染)
    Mounted 渲染dom完成(加载组件第一次渲染)
    beforeUpdate重新渲染之前(数据更新等操作控制DOM重新渲染)
    update重新渲染完成
    beforeDestroy销毁之前
    destroyed销毁完成

    vm.$mount("#app")
    8.p16 this.$refs对象 只有在mounted才能获取这些元素

    9.p17购物商品多项选择列表案例
    删除其中一个筛选条件
    this.data = this.data.filter(item=>{
    return item.type!==type
    })
    点击选项添加条件
    handleSelect(type,name){
    let flag = this.data.some(item=>parseInt(item.type)===parseInt(type))
    if(flag){
    this.data = this.data.map(item=>{
    if(parseInt(item.type)===parseInt(type)){
    item.name = name
    }
    return item
    })
    }else{
    this.data.push({
    type,
    name
    })
    }
    }

    排序
    this.data.sort((A,B)=>{
    return A.type-B.type
    })

    10 p18
    全局组件:无需单独引用或者配置,直接在大组件中调取全局组件即可
    Vue.component(componentName,options)
    Vue.component('my-button',{
    template:`<button>按钮组件<button>`
    data:{},
    created(){

    }
    })

    组件命名规则
    kebab-case:横线作为分隔符 只能 基于kebab方法调取
    PasalCase:单词首字母大写 也是基于debab方法调取(如果在template中可以使用pasalCase方式调用)
    调取组件的时候,会把所有组件的单词渲染为小写字母(我们命名的时候除PasalCase模式外,我们都要把组件名设置为小写,调取组件的时候可以使大写也可以使小写(最后都是按照小写渲染的))

    调取组件
    单闭合:不符合w3c规范,调取完成后,后面的视图不识别(避免使用)
    双闭合:可以设置除组件规定内容外的其余内容(slot插槽)

    Vue.component('MyButton',{
    //必须设置template 或者render函数,来规定当前组件的渲染视图
    template:`<button>组件中的按钮</button>`
    })
    template:
    必须设置template 或者render函数,来规定当前组件的渲染视图
    每个组件只能有一个根元素
    模板字符串方式
    template标记方式
    slot插槽处理

    data必须是一个函数,包装不同组件之间的数据互相不干扰(返回的对象中初始化数据)

    11. p20
    局部组件
    const MyButton={
    template: `<button>局部button</button>`,
    data(){
    return{

    }
    }
    }

    let vm=Vue({
    data:{

    },
    components:{
    MyButton,
    'mybutton':MyButton
    }
    })
    12.p21
    vue porps 父传子数据
    props:{
    title:"",
    required:true,
    default:'默认值',
    validator(){
    自定义验证规则 val传递的属性值 在函数中,根据自己的规则,返回true和false来验证传递的值是否符合规则
    }
    }

    13.p22
    vue单向数据流
    14.p23
    $emit()
    15.p24 投票系统案例
    $on()

    16.p25
    基于ref实现父子组件信息通信
    ref如果在普通的dom元素上使用,引用指向的就是dom元素,如果用在子组件上,引用就指向组件实例,基于此可以快速获取和操作子组件中的数据
    $parent和$children示获取组件和子组件的实例,只不过$children是一个数组集合,需要我们记住组件顺序才可以

    17.p26
    provide 和inject 绑定并不是响应式的,这是刻意为之的,然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的

    基于provide 和inject实现祖先与后代的通信
    这些数据存储在this._provided:可以使对象也可以使闭包的方式,闭包方式。闭包的方式好处是“它会在实例上的信息都挂载完成后再处理”
    provide(){
    return{
    num:0,
    change:this.change
    }
    }
    methods:{
    change(){
    type==='support'?this._provided.num
    this.$forceUpdate()
    }
    }

    inject:['change']

    18.p27-p29
    轮播图

    19.p30
    defineProperty()
    object.defineProperty(obj,;name;,{
    get(){

    }
    set(){

    }
    value:'',
    confirguable:true,//属性时否可被删除
    enumerable:true //是否为可枚举属性
    writable:true//是否当前属性可被修改

    })

    vue内置的observer/defineRetive函数,会帮我们把所有在DATA中初始化的属性都GETTER/SETTER了(递归处理)

    Array本身被Getter/Setter了,但是里面的每一项都没有被处理,所以基于Arr【index】=xxx修改值不能通知视图重新渲染
    vue对于数组这样处理的:把数组中的一些内置方法进行重写
    push/pop/unshift/shift/splice/reverse/sort,
    当我们调取这些方法的时候,vue会帮我们刷新视图

    $set不仅仅是用来修改数据,而且可以把被修改的属性基于defineProperty进行getter/setter
    this.$set(this.obj,'name','名字')

    20.p31
    v-model 实现原理

    22.p32
    webpack
    webpack 安装
    为了防止全局安装出现的版本冲突,我们一般把webpack安装在本地项目
    yarn add webpack webpack-cli -D
    npm i webpack webpack-cli --save-dev

    从npm5.2 版本后,提供了一个命令:npx ,基于这个命令可以执行本地安装的模块
    npx webpack 基于npx执行了webpack命令,而这个命令就是实现打包部署的
    找到node_modules/.bin
    要求我们得有webpack.cmd 的文件
    执行webpack.cmd

    也可以从webpack.json 中配置可执行的脚本
    “scripts”:{
    "build":"webpack",
    }
    npm run build /yarn build

    基础打包语法
    src:存储项目开发的源文件
    dist:打包后的文件目录
    从第四代版本开始,可以支持零配置

    23.p33
    webpack配置文件
    自定义基础配置(webpack 是基于node js 写的。所以用common.js规则)
    webpack.config.js 或者 webpackfile.js
    在这个文件中设置我们自定义的打包规则
    1,所有的规则都写在module.exports={}中

    let path = require('path')

    module.exports ={
    //配置环境 production和devlopment
    mode:'production',
    //入口
    entry:'./src/index-my.js',
    //出口
    output:{
    //输出的文件名
    filename:'bundle.min.js'
    //输出的目录必须是绝对路径
    path:path.resolve(__dirname,'build')
    }
    }

    指定webpack的配置文件 打包
    npx webpack --config webpack.config.development


    shift+alt+F 代码格式化

    24 p34
    webpack -dev-server
    webpack-dev-server --config xxx.js (特点:服务器启动后,默认是不关闭的,当我们修改src中的文件时,它会自动进行编译,然后自动刷新浏览器)

    let path = require('path')
    module.exports ={
    mode:'production',
    entry:'./src/index-my.js',
    output:{
    filename:'bundle.min.js'
    path:path.resolve(__dirname,'build')
    }
    devServer:{
    prot: 3000, //创建服务指定的端口号
    progress: true // 显示打包的速度
    contentBase:'./build'//指定当前服务处理资源的目录
    open: true //编译完会自动打开浏览器
    }
    }

    npx webpack-dev-server --config webpack.config.development.js

    25 p35
    html-webpack-plugin

    let path = require('path')
    let HtmlWebpackPlugin = requrie('html-webpack-plugin') //每一个导入进来的插件都是一个类 new HtmlWebpackPlugin({})
    module.exports ={
    mode:'production',
    entry:'./src/index-my.js',
    output:{
    //让每一次生成的文件名都带着hash值
    filename:'bundle.min.[hash].js'
    path:path.resolve(__dirname,'build')
    }
    devServer:{
    prot: 3000, //创建服务指定的端口号
    propress: true // 显示打包的速度
    contentBase:'./build'//指定当前服务处理资源的目录
    open: true //编译完会自动打开浏览器
    },
    //使用插件
    plugins:[
    new HtmlWebpackPlugin({
    //不指定模板会按照默认模板创建一个HTML页面,当然真实项目中一般都是把自己写好的HTML进行编译
    template:'./src/index.html',
    //输出的文件名
    filename:'index.html',
    //让我们引入的js后面加上hash戳(清除缓存),但在真实项目中我们一般都是每一次编译生成不同的js文件引入
    hash:true,
    //控制压缩html
    minify:{
    collapseWhitespace: true,
    removeComments:true,
    removeAttributeQuotes:true,
    removeEmptyAttributes:true
    }

    })
    ]
    }

    27. p36
    加载其loader
    使用加载器loaer来处理css规则

    处理css 时需要在js引用文件中导入css
    requrie('./css/index.css')

    let path = require('path')
    let HtmlWebpackPlugin = requrie('html-webpack-plugin')
    module.exports ={
    mode:'production',
    entry:'./src/index-my.js',
    output:{
    //让每一次生成的文件名都带着hash值
    filename:'bundle.min.[hash].js'
    path:path.resolve(__dirname,'build')
    }
    devServer:{
    prot: 3000, //创建服务指定的端口号
    propress: true // 显示打包的速度
    contentBase:'./build'//指定当前服务处理资源的目录
    open: true //编译完会自动打开浏览器
    },
    //使用插件
    plugins:[
    new HtmlWebpackPlugin({
    template:'./src/index.html',
    filename:'index.html',
    hash:true,
    minify:{
    collapseWhitespace: true,
    removeComments:true,
    removeAttributeQuotes:true,
    removeEmptyAttributes:true
    }

    })
    ],
    //使用加载器loader 处理规则
    module:{
    rules:[{
    test:/\.(css|less)$/, //基于正则区配处理那些文件
    use:[ //控制使用的规则,有顺序,从右到左执行
    "style-loader", //把编译的css插入到页面的Head中(内嵌式样式)
    "css-loader", //@import/url()这种语法的
    "postcss-loaer", //设置前缀
    或者
    {
    loader:'postcss-loader',
    options:{
    ident:'postcss',
    plugins:[
    require('autoprefixer')
    ]
    }
    },
    {
    loader:'less-loader',
    options:{

    }
    }
    ]
    }]
    }
    }

    post-css 需要一个autoprefixer
    新建一个post.config.js文件
    module.export ={
    plugins:[
    require('autoprefixer')
    ]
    }

    在package.json中配置
    “browserslist”:[
    ">1%",
    "last 2 versions"
    ]

    28 p37
    css抽离
    mini-css-extract-plugin

    let path = require('path')
    let HtmlWebpackPlugin = requrie('html-webpack-plugin')

    let MiniCssExtractPlugin = require("mini-css-extract-plugin")
    let OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
    let UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin")

    module.exports ={
    mode:'production',
    entry:'./src/index-my.js',
    output:{
    //让每一次生成的文件名都带着hash值
    filename:'bundle.min.[hash].js'
    path:path.resolve(__dirname,'build')
    }
    devServer:{
    prot: 3000, //创建服务指定的端口号
    propress: true // 显示打包的速度
    contentBase:'./build'//指定当前服务处理资源的目录
    open: true //编译完会自动打开浏览器
    },
    //配置优化规则
    optimization:{
    //压缩优化
    minimizer:[
    //压缩css(产生问题:js压缩不在执行自己默认的压缩方式了,也走的是这个插件从而导致无法压缩)
    new OptimizeCssAssetsWebpackPlugin(),
    new UglifyjsWebpackPlugin({
    cache: true, //是否使用缓存
    parallel: true, //是否是并发编译
    courceMap: true //启动源码映射(方便调试)
    })
    ]
    },

    //使用插件
    plugins:[
    new HtmlWebpackPlugin({
    template:'./src/index.html',
    filename:'index.html',
    hash:true,
    minify:{
    collapseWhitespace: true,
    removeComments:true,
    removeAttributeQuotes:true,
    removeEmptyAttributes:true
    }

    }),

    //引用的css处理
    new MiniCssExtractPlugin({
    filename:"main.min.css", //指定输出文件

    })
    ],
    内嵌css处理
    //使用加载器loader 处理规则
    module:{
    rules:[{
    test:/\.(css|less)$/, //基于正则区配处理那些文件
    use:[ //控制使用的规则,有顺序,从右到左执行

    MiniCssExtractPlugin.loader, //把抽离的css文件外联到html文件中

    "style-loader", //把编译的css插入到页面的Head中(内嵌式样式)
    "css-loader", //@import/url()这种语法的
    "postcss-loaer", //设置前缀
    或者
    {
    loader:'postcss-loader',
    options:{
    ident:'postcss',
    plugins:[
    require('autoprefixer')
    ]
    }
    },
    {
    loader:'less-loader',
    options:{

    }
    }
    ]
    }]
    }
    }

    29 p38
    基于babel实现es6的转换和ESLint语法检测

    css抽离
    mini-css-extract-plugin

    let path = require('path')
    let HtmlWebpackPlugin = requrie('html-webpack-plugin')

    let MiniCssExtractPlugin = require("mini-css-extract-plugin")
    let OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
    let UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin")

    module.exports ={
    mode:'production',
    entry:["@babel/polyfill",'./src/index-my.js'],
    output:{
    filename:'bundle.min.[hash].js'
    path:path.resolve(__dirname,'build')
    }
    devServer:{
    prot: 3000,
    propress: true
    contentBase:'./build'
    open: true
    },
    //配置优化规则
    optimization:{
    minimizer:[

    new OptimizeCssAssetsWebpackPlugin(),
    new UglifyjsWebpackPlugin({
    cache: true,
    parallel: true,
    courceMap: true
    })
    ]
    },
    //使用插件
    plugins:[
    new HtmlWebpackPlugin({
    template:'./src/index.html',
    filename:'index.html',
    hash:true,
    minify:{
    collapseWhitespace: true,
    removeComments:true,
    removeAttributeQuotes:true,
    removeEmptyAttributes:true
    }

    }),
    new MiniCssExtractPlugin({
    filename:"main.min.css",

    })
    ],
    //使用加载器loader 处理规则
    module:{
    rules:[
    {
    test:/\.(css|less)$/,
    use:[
    MiniCssExtractPlugin.loader,
    "style-loader",
    "css-loader",
    "postcss-loaer",
    或者
    {
    loader:'postcss-loader',
    options:{
    ident:'postcss',
    plugins:[
    require('autoprefixer')
    ]
    }
    },
    {
    loader:'less-loader',
    options:{
    }
    }
    ]
    },
    {
    test:/\.js$/i,
    use:[
    {
    loader:'babel-loader',
    options:{

    //基于BABEL的语法解析包(es6->es5)
    presets:['@babel/preset-env'],

    //使用插件处理es6的特殊语法
    plugins:[
    ["@babel/plugin-proposal-decorators",{"legacy":true}],
    ["@babel/plugin-proposal-class-properties",{"loose": true}],
    "@babel/plugin-transform-runtime",
    ]
    }
    },
    "eslint-loader" //添加eslink loader
    按照官方文档生成一个eslintrc.json

    ],
    //指定js的编译目录(忽略哪些目录)
    exclude:/node_modules/,
    include:path.resolve(__dirname,'src')
    },
    ]
    }
    }

    babel 中的插件polyfill和runtime
    @babel/polyfill 和@babel/runtime 需安装到生产环境下,先导入require()或者在entry:["@babel/polyfill",'./src/index-my.js']中加入

    eslink
    添加"eslint-loader"
    生成eslintrc.json


    30 p39
    在vscode中开启es7中类的装饰器,项目根目录中设置jsconfig.json,再重启vscode
    {
    "compilerOptions":{
    "experimentalDecorators": true
    }
    }

    处理jquery
    暴露全局loader

    expose-loader -D
    //内联加载器
    import jquery from 'expose-loader?$!query'(每个模块都要引入,麻烦)
    //在每个模块中都可以使用,不用引用
    let webpack = require('webpack')
    module.exports ={
    plugins:[
    //在每个模块中都注入$
    new webpack.ProvidePlugin({
    "$":'jquery'
    })
    ]
    }

    图片的处理
    html中的图片
    rules:[
    {
    //图片处理
    test:/\.(png|jpg|jpeg|gif|ico|webp|bmp)$/i,
    //use:['file-loader']或者url-loader(url-loader可以使用base64的格式)
    use:[
    {
    loader:'url-loader',
    options:{
    //图片小于200kb 直接给base64
    limit:200*1024
    }
    }
    ]
    },
    {
    //处理html中导入的图片
    test:/\.(html|htm|xml)$/i,
    use:[
    "html-withimg-loader"
    ]
    }
    ]

    js中相对路径在webpack打包时,无法打包图片无法显示需要先把图片导入进来 ,绝对地址不需要
    webpak打包,在js中使用图片 ,需要先把图片导入进来,然后再使用 两种方法
    import img from './stati/psb.jpg'
    let img = require('./static/psb.jpg')

    分目录打包
    module.exports = {
    output:{
    filename:'js/bundle.min.[hash].js'
    path:path.resolve(__dirname,'build')
    //编译后引用资源地址前面设置前面设置前缀
    publicPath:'./'
    },
    plugins:[
    new MiniCssExtractPlugin({
    filename:'css/main.css'
    })
    ],
    module:{
    rules:[
    {
    test:/\.(png|jpg|jpeg|gif|ico|webp|bmp)$/i,
    use:[
    {
    loader:'url-lader',
    options:{
    //控制打包图片所在目录
    outputPath:'images'
    }
    }
    ]
    },
    ]
    }
    }

    31 p40 webpack配置实例
    let path =require('path')
    let HtmlWebpackPlugin = require('html-webpack-plugin')
    let MiniCssExtractPlugin = require("mini-css-extract-plugin")
    let OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
    let UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin")

    module.exoprts = {
    mode:'production',
    entry:'./src/index.js',
    output:{
    filename:'bundle.min.[hash].js',
    path:path.resolve(__dirname,'dist')
    },
    devServer:{
    port:3000,
    contentBase:"./dist",
    progress: true,
    open:true
    },
    //压缩css
    optimization:{
    minimizer:{
    new MiniCssExtractPlugin({

    }),
    new UglifyjsWebpackPlugin({
    cache:true,
    parallel:true,
    sourceMap:true
    })
    }

    },
    plugins:[
    new HtmlWebpackPlugin({
    template:"./src/banner.html",
    filename:'index.html',
    }) ,
    MiniCssExtractPlugin ({
    filename:"bundle.min.[hash].css",

    })
    ],
    modules:[
    rules:[
    {
    test:/.\(css|less)$/i,
    use:[
    //内嵌式用style-loader,抽离时用MinCssExtractPlugin.loader
    MinCssExtractPlugin.loader(用MiniCssExtractPlugin时用)或者("style-loader"),
    "css-loader",
    {
    loader:"postcss-loader",
    options:{
    indent:"postcss",
    plugins:[require("autofixer")]
    }
    },
    "less-loader"
    ],
    },
    {
    test:/.\js$/i,
    exclude:/node_modules/,
    include:path.resolve(__dirname,'src'),
    use:[
    {
    loader:'babel-loader',
    option:{
    presets:["@babel/preset-env"],
    plugins:[
    "@babel/plugin-transform-runtime"
    ]
    }
    }
    ]
    },
    {
    test:/\.(png|jpg|jpeg|gif|ico|webp|bmp)$/i,
    //use:['file-loader'],url-loader可以处理base64或者
    use:[
    {
    loader:'url-lader',
    options:{
    limit:200*1024,
    outputPath:'images'
    }
    }
    ]
    },
    {
    //处理html中的图片
    test:/\.(html|htm|xml)$/i,
    use:[
    "html-withimg-loader"
    ]
    }
    ]
    ]

    }

    postcss中不兼容前缀时
    在package.json中配置
    “browserslist”:[
    ">1%",
    "last 2 versions"
    ]

    32.p41
    脚手架
    1.安装脚手架(一般安装在全局)
    npm install @vue/cli -g 或者 yarn global add @vue/cli

    2.创建工程化项目
    vue create 项目名称

    3.vue inspect 查看配置

    项目目录
    crc 存储项目开发的源文件
    main.sj 打包编译的入口文件
    app.vue 项目页面的入口文件
    components 存储当前项目的公共组件
    xx.vue
    assets 一般存放项目中需要引入的静态资源文件
    xxx.png
    xxx.css

    public
    index.html 当前项目的主页面(最后把所有在src中写入的内容通过webpack/vue编译渲染后,最后都会呈现在index.html的#app容器中)
    xxx.xx.虽然把代码或资源都放在src中,但是有时候,某些资源也可能需要单独在index.html就引用了

    直接在html中引入资源的时候最好都设置为<%=BASE_URL %>这种方式,因为资源写的webpack会帮我们进行编译处理

    33.p42 webpack配置
    vue inpect 查看当前默认的webpack配置信息
    vue create 创建一个项目
    vue add[plugin]在当前项目中安装插件

    修改默认的webpack配置
    需要在根目录中设置vue.cofig.js
    module.exports ={
    publicPath:process.env.NODE_ENV ==="production"?"http://www.zhufengpeixun.cn/":'/',
    //自定义一个目录名称,把生成的js/css/图片等静态资源放到这个目录中
    assetsDir:'assets',
    //关闭生产环境下的资源映射(生产环境下不在创建xxx.js.map文件)
    productionSourceMap:false,
    //设置一些webpack配置项,用这些配置项和默认的配置项合并https://github.com/survivejs/webpack-merge
    configureWebpack:{
    plugins:[]
    }
    //直接修改内置的webpack配置项
    chainWebpack:config=>{
    //原始配置信息对象
    config.module
    .rule('images')
    .use('url-loader')
    .lodaer('url-loader')
    .tap(options=>{
    optioms.limit=200*1024;
    return options;
    })
    }
    }

    //修改webpack-dev-server配置(尤其是跨域代理)
    devServer:{
    proxy:{
    //请求地址 /user/add
    //代理地址 http://api.zhufengpeixun.cn/user/add
    "/":{
    changeOrigin:true,
    traget:"http://api.zhufengpeixun.cn"
    }
    }
    },
    //多余1核cpu时,启动并行压缩
    parallel:{
    parallel: require('os').cpus().length>1
    }
    //第三方插件配置
    pluginOptions:{

    }

    33.p43
    vuex状态管理模式
    实现组件之间通信的方法
    1.props 父->子
    2.$on/$emit 子<->父 拥有共同父亲的兄弟 隔代处理
    3.$parent($children|$refs)
    4.provide/inject 隔代处理
    5.listeners/$attrs
    $attrs:获取的是父组件传递进来的属性信息(排除掉在props中注册过的,排除class/style等)都是基于v-bind绑定的属性或者直接静态属性
    $listeners: 获取的是父组件传递进来的事件信息 基于$xxx=“xxx”处理的

    34.p44
    vuex
    store = new Vuex.store({
    state:{

    },
    mutations:{
    example(state,payload){
    //state 容器中储存的状态信息,payload是commit执行的时候传递进来的参数
    //this.$store.commit('example',2000)
    },

    },

    //这些方法首先异步获取需要的数据,然后再基于commit触发Mutations中的方法,从而改变state
    actions:{
    exampleAtion(context({commit}),payload){
    //this.$store.dispath('exampleAction','参数')
    //context.commit
    setTimeout(()=>{
    context.commit('example',1000)
    //commit('example',1000)
    },1000)
    }
    },

    //getters储存的方式等价于computed计算属性,监听当前容器中state的计算属性
    getters:{

    }


    })

    35.p45 vuex能处理任何情况下的组件信息通信
    前提:spa单页面(实现的是同一个页面中,各组件的信息通信)
    vuex:vue中实现公共状态管理的插件

    import logger from 'vuex/dist/lodder' vuex
    export default new Vuex.store({
    state:{
    },
    mutations:{
    },
    actions:{
    },
    getters:{
    },
    //使用logger中间插件能够详细
    plugins:[lodder()]


    })

    36.p46 如果页面不刷新 父组件中的子组件date中的数据不会更新
    因为data中的数据在created中创建,date在update中不会更改
    this.$nextTick(()=>{

    })

    37.p47
    //遍历stroe容器中的state,获取到的结果是一个新对象
    mapState(['votelist',"message"])=>{votelist:xxx,message:xxx}
    import {mapState,mapGetters,mapMuataions,mapActions} from 'vuex'

    mapState(["votelist","message"])=>{votelist:xxx,message:xxx}
    相当于
    function mapState(arr){
    let obj={},
    arr.forEach(item=>{
    obj[item]=this.$stor.state[item]
    })
    return obj
    }

    function mapMutation(arr){
    let obj={},
    arr.forEach(item=>{
    obj[item]=function(...args){
    this.$store.commit(item,...args)
    }
    })
    return obj
    }

    export defautl{
    computed:{
    ...mapState({
    supNum:state=>state.voteList.supNum,
    oppNum:state=>state.voteList.oppNum,
    }),//=>{supNum:function(){},oppNum:xxx}
    ...mapGetters(["ratio"]),
    ...mapMutations(["supHandle"]),
    ...mapActions({
    oppHandle:'opposeAction'
    })
    }
    }

    38.p48
    模块化管理vuex
    //person.js 个人模块中的状态管理
    export default{
    namespaced:true,
    state:{
    name:'珠峰培训',
    baseInfo:{
    email:'1111@qq.com',
    phone:'111111',
    }
    },
    getters:{
    queryBase(state){
    return '${state.name}的邮箱是:$state.baseInfo.email'
    }
    },
    mutations:{
    changeName(state,payload){
    state.name=payload
    }
    },
    actions:{
    actionDemo(context,payload){
    //context.state 当前模块私有的状态
    //context.rootState整个store中的状态
    }
    }
    }

    //product.js //产品板块中的公共状态管理
    export default{
    namespaced:true,
    state:{
    name:'前端开发',
    baseInfo:{
    time:"5 month"
    }
    },
    getters:{
    queryBase(state){
    return '${state.name}课程的周期是:$state.baseInfo.time'
    }
    },
    mutations:{
    changeName(state,payload){
    state.name=payload
    }
    }
    }

    //index.js //modules 把每一个模块中的State Actions都合并
    import Person from './person'
    import Product from './product'
    Vue.use(Vuex)
    export default new Vuex.store({
    //把每个模块中的State,Actions都进行合并
    modules:{
    Preson,
    Product
    },
    //各个模块中公共的方法和状态
    state:{
    isLogin:true
    },
    mutations:{
    changeName(state,payload){
    state.isLogin= payload
    }
    }
    })

    state会按照各个板块进行区分 state={
    Person:{...},Product:{...},isLogin:true
    }
    但是GETTERS/MUTATIONS/Actions默认不会进行模块区分,默认是全部合并在一起,这样会导致冲突
    解决方案:每个模块设置namespaced:true,这样最后虽然也是把每个模块中的方法合并在一起了,但是会以模块的名字作为前缀,并进行标识和区分mutations={'Persion/changeName':function(){}}

    调用:
    this.$store.getters["Person/queryBase"]
    this.$store.commit('Person/changeName','姓名')

    export default{
    computed:{
    ...mapState({
    name: state=>{
    //state是全局的
    return state.Person.name
    }
    })
    }
    }

    export default{
    computed:{
    ...mapState('Person',{
    name: state=>{
    //state是Person下的
    return state.name
    }
    })
    }
    }



    合并模块分开调用
    store
    index.js
    import Product from './product/'
    export default vuex.store({
    //把每个模块中的state-actions都进行合并
    //1.state会按照各个板块进行区分
    modules:{
    Person,
    Product
    },
    //公共状态方法
    state:{
    insLogin:true
    }
    })
    person.js
    export default{
    namespaced:true,
    state:{
    name:{

    }
    },
    mutations:{
    changeName(state,payload){
    state.name=payload
    }
    },
    getters:{
    queryBase(state){

    }
    }

    }
    Product.js
    export default{
    namespaced:true,
    state:{
    name:"前端就业开发班"
    }
    }

    import {createNamespaceHelpers} from "vuex"
    let {mapstate,mapMutations}= cretaeNampspaceHelpers("Product")
    export default{
    computed:{
    ...mapState(['name'])
    },
    methodes:{
    ...mapMutations(['changeName'])
    },
    mounted(){
    setTimeout({
    this.changeName("调用this.changeName")
    },1000)
    }
    }

    抽离名称
    store.types.js
    export const PRODUCR_MUTATION_CHANGTE_NAME="PRODUCR_MUTATION_CHANGTE_NAME"

    import * as types from ',/store-types.js'
    调用
    export default{
    getters:{
    [types.PRODUCR_MUTATION_CHANGTE_NAME]
    }
    mounted(){
    setTimeout({
    this[types.PRODUCR_MUTATION_CHANGTE_NAME]("调用this.changeName")
    },1000)
    }
    }

    39.p49
    todo案例

    40.p50 本地存储
    localStorage
    1.存储的信息都是字符串,每次还需要不断解析处理
    2.永久性存储,页面刷新也不会消失
    3.存储的限制

    41.p51 api 单独写入一个文件
    新建src->api->index.js
    如果项目是基于axios来完成请求处理的,此处我们需要做的就是对axios进行默认的全局配置:如果我们是基于fetch来处理的此处也是对fetch的二次封装
    import axios from 'axios';
    axios.defaults.baseURL= 'http://127.0.0.1:8888';
    axios.defualts.withCredentials = true;
    axios.defaults.headers['Content-Type']='application/x-www-form-urlencoded';
    axios.defaults.transformRequest=function(data){
    if(!date) return date;
    let result =``;
    for (let attr in data){
    if(!data.hasOwnProperty(attr)) treak;
    result += `&${attr}=${data[attr]}`;
    }
    return result.substring(1);
    }

    axios.interceptors.response.use(function onFulfilled(response){
    return response.data;
    },function onRejected(reason){
    return Promise.reject(reason);
    })

    axios.defaults.validateStatus= function(status){
    return /^(2|3)\d{2}$/.test(status)
    }

    export default axios;

    新建src->api->task.js
    import axios from './index';
    /*
    *queryTask:获取任务列表信息
    */
    function queryTask(state=0){
    axios.get('/getTaskList',{
    params:{
    limit:1000,
    page:1,
    state
    }
    })
    }
    export default {
    queryTask
    }

    42.p51 获取数据缓存到vuex中
    模块化store
    新建store-task.js
    import {queryTask} from '../api/task'
    export default {
    namespaced:true,
    state:{
    //存储所有任务信息的状态
    taskList:null
    },
    getters:{},
    mutations:{
    //更新任务列表
    updateTaskLIst(state,payload){
    state.taskList=payload;
    }
    },
    actions:{
    //从服务器获取数据,获取成功后通知mutations中的方法执行
    updateTaskList(context){
    let commitName = 'updateTaskList';
    queryTask().then(result=>{
    if(parseInt(result.code)===0){
    context.commit(commitName,result.list)
    return
    }
    return Promise.reject();
    }).catch(reason=>{
    //默认存储的是Null,代表还未从服务器获取过数据,如果获取失败,我们让其为空数组,虽然还是没有数据,但是至少证明我们尝试过获取 操作
    context.commit(commitName,[])
    });
    }
    }
    }

    将模块的task.js合并到store->index.js中
    import Vue from 'vue';
    import Vuex from 'vuex';
    import logger from 'vuex/dist/logger';
    import tast from './task'

    Vue.use (Vuex);
    export default new Vuex.Store({
    modules:{
    task
    },
    plugins:[logger()]
    })

    43.p52
    api

    新建src->api->task.js
    import axios from './index';
    /*
    *queryTask:获取任务列表信息
    */
    export function queryTask(state=0){
    axios.get('/getTaskList',{
    params:{
    limit:1000,
    page:1,
    state
    }
    })
    }
    /*
    *addTask增加任务信息
    */
    export function addTask(task,time){
    return axios.get('/addTask',{
    task,
    time
    })
    }

    44.p53
    ElementUI table 表格
    列表页面切换

    45.p54
    table列表中的删除和完成功能
    slot-scope

    46.p55 vueRouter

    47.p56 hash模式和history模式
    location.href,
    history.pushState(state,title,url|?xxx=xxx)

    48.p57
    vur-router配置路由
    新建router.js
    import Vue from 'vue'
    import VueRouter from 'vur-router'
    import Home from './home'

    Vue.use(VueRouter)
    export default new VueRouter({
    //设置路由模式:hash/history
    mode:'hash',
    routes:[
    {
    path:'/',
    redirect:'/home'
    //component:Home
    },
    {
    path:'/custom',
    name:custom,//命名路由
    component:'/custom/list',
    children:[
    {
    path:'/custom/list/:lx',//=>动态路由(把需要传递的参数作为路由地址的一部分)
    name:customList
    component:CustomList
    },
    {
    path:'/handle',//=>可以简写,但是不能写斜杠,否则默认为是根目录下访问
    name:customHandle
    component:CustomHandle
    },
    ]
    },
    ]
    })

    49.p58
    基于地址path跳转,
    <router-link to="/custom/list?lx=my"></router-link>
    <router-link :to="{path:'/custom/list',query:{lx:'my'}}"></router-link> path方式跳转不能基于params传参,只能通过query问号传参

    命名路由跳转
    <router-link :to="{name:customList}"></router-link>
    <router-link :to="{name:customList,query:{lx:'my'}}"></router-link>问号传参会显示在地址栏中
    <router-link :to="{name:customList,params:{lx:'my'}}"></router-link>直接传递参数不会显示在地址栏中

    动态路由,路由跳转的地址是动态处理的
    children:[
    {
    path:'/custom/list/:lx',//=>动态路由(把需要传递的参数作为路由地址的一部分)
    name:customList
    component:CustomList
    },
    ]
    动态路由跳转(路由跳转的地址是动态处理的)
    path:'/custom/list/:lx' =>动态路由
    <router-link to="/custom/list/lx"></router-link>
    获取(当前地址下刷新页面,params中的信息也不会显示)
    this.$router.currentRoute.params={lx:'my'}

    query和params的区别
    共同点,基于router-link或者this.$router.push跳转的时候,传递的参数可以在渲染组件中获取到
    一,
    query传递的信息可以在地址栏中显示,
    params传递的信息不能在地址栏中显示
    二,
    query在当前地址下刷新,依然可以基于this.$router.currentRoute.query获取到
    params在当前地址下刷新浏览器,params中的信息就清空了
    this.$router
    go(n)回退或者前进N步
    back()=>go(-1)
    forward()=>go(-1)
    push():跳到指定的路由,实现路由切换

    50.p59
    this.$route ===this.$router.currentRoute
    命名视图
    <view></view>
    <view name="name2"></view>
    components:{
    default:Home,
    name2:My
    }

    import Vue from 'vue'
    import VueRouter from 'vur-router'
    import Home from './home'

    Vue.use(VueRouter)
    export default new VueRouter({
    //设置路由模式:hash/history
    mode:'hash',
    routes:[
    {
    path:'/',
    redirect:'/home'
    components:{
    default:Home,
    name2:My
    }
    },
    ]

    component:()=>{
    return import (',/pages/Home')
    }

    总结: component:可以使一个组件
    components{}可以使对象(命名视图)
    component:函数只有路由去陪成功才引入和加载当前模块,也可以在函数中做点事,列如权限效验

    一般在路由列表最后加一个匹配
    {
    path:'*',
    redirect:'/'
    //component:Error
    }

    每一次路由的跳转和切换,都是把之前渲染的组件销毁(destoryed)},重新渲染新组件(before-created =>data)

    51.p59
    导航守卫(路由权限效验)
    全局守卫(不管路由区配哪个地址,哪个组件都会触发)
    router.beforeEach((to,from,next)=>{
    //to:将要跳转的到的路由对象
    //from:从哪个路由来,存储的也是这个路由对象
    console.log('===全局before each')
    next()
    })

    router.beforeResolve((to,from)=>{

    next()
    })

    router.afterEach((to,from)=>{
    //to:将要跳转的到的路由对象
    //from:从哪个路由来,存储的也是这个路由对象
    console.log()
    next()
    })

    路由独有守卫
    beforeEnter(to,from,next){
    next()
    }

    组件独有守卫
    beforeRouteEnter(to,from,next){
    next()
    }
    beforeRouteUpdate(to,from,next){
    next()
    }
    beforeRouteLeave(to,from,next){
    next()
    }

    const router =new VueRouter({

    })


    export default router

    52.p60
    配置多页面入口
    vue.config.js
    modules.exports={
    pages:{
    login:{
    entry:'src/login.js',
    template:'public/login.html'
    },
    index:{
    entry:'src/main.js',
    templage:'public/index.html'
    }
    }
    }

    登录页面
    1.表单验证,(防止sql或者特殊字符的注入:防XSS攻击)
    2.密码的MD5加密(POST请求)
    3.向服务器发送请求
    4.接受服务器返回的结果
    失败: 直接做一个提示
    成功: 可以把登录状态或者权限信息存储到本地(localStorage)

    app.vue(vue-router实现SPA)
    1.从服务器重新获取登录状态和权限
    未登录:给予提示,然后跳转到登录页
    已登录,把登录状态和权限存储到vuex中(一般用vuex代替本地存储的内容)
    2.各个板块渲染的时候,首先从vuex中获取权限信息,根据获取的结果做权限效验

    用户名,手机,邮箱验证
    import * as API from './api/login'
    checkAccount(){
    let argArr=[用户名正则,手机正则,邮箱正则,]
    return argArr.some(item=>{
    return item.test(this.account)
    })
    }

    checkPassWord(){
    return /^\w{6,16}$/.test(this.password)
    }

    import md5 from 'blueimp-md5'
    handleLogin(){
    //1.防止xss攻击,先做表单效验
    if(!this.checkAccount()||!this.checkPassWord()){
    this.$message.error("")
    return
    }
    //2.把状态中的密码进行MD5加密(不能修改原始状态,因为一定修改,视图里的也会被修改)
    let password=md5(this.password)

    //3.发送给服务器进行效验
    API.handleLogin(this.account,this.password)
    .then(power=>{
    this.$alert("登录成功","系统提示",{
    callback:action=>{
    location.href= location.origin//默认找index.html
    }
    })
    })
    .catch(reson=>{
    this.$alert("账号密码不区配","系统提示")
    })
    }

    新建api
    api->login
    import axios from './index'
    export function handleLogin(account,password){
    return axios.post('/user/login',{
    account,
    password
    }).then(result=>{
    if(parseInt(result.code===0)){
    return result.power
    }
    return Promise.reject(result.codeText)
    })
    }

    53.p61
    hash路由和history的区别
    history模式下,浏览器刷新后找不到页面会报错,服务器要有个对404页面请求的支持,对404页面特殊处理。

    router.js
    import Vue from 'vue';
    import VueRouter from 'vue-router',
    import Custom from './pages/Custom.vue';
    import CustomList from './pages/custom/CustomList.vue'
    import CustomHandle from './pages/custom/CustomHandle.vue'
    imort Systen from './pages/system.vue'
    Vue.use(VueRouter)
    const router= new VueRouter({
    mode:'hash'
    routes:[
    {
    path:'/',
    director:'/custom',
    },
    {
    path:'custom',
    name:'/custom',
    component:Custom,
    children:[
    {
    path:'/custom',
    redirect:{
    path:'/custom/list',
    query:{
    type:2
    }
    }
    },
    {
    path:'list',
    name:'customList',
    component:CustomList
    },
    {
    path:'Handle/:customId',
    name:'customHandle',
    component:CustomHandle
    },


    ]
    },
    {
    path:'system',
    name:'/system',
    component:System
    },
    {
    path:'*',
    director:'/custom',
    },
    ]
    })
    export default router

    判断一级导航的切换显示
    多次插入同一条路由会报错, 可以进行判断
    activeIndex(){
    let url= location.href.includes;
    if(url.includes('/custom')) return "1"
    if(url.includes('/system')) return "2"
    }

    changeRouter(){
    let arr =['/custom/list?type=my',
    '/custom/list?type=all',
    '/custom/handle'
    ]

    index = parseInt(index);
    if(location.href.includes(arr[index-1])) return
    this.$router.push(arr[index-1])
    }

    54.p62 首页登录验证
    在api->login.js
    export function checkLogin(){
    return axios.get('/usre/login').then(result=>{
    if(parseInt(result.code)===0){
    return true;
    }
    return Promise.reject(false);
    })
    }
    //获取用户权限
    export function queryPwoer(){
    return axios.get('/user/power').then(result=>{
    if(parseInt(result.code)===0){
    return result.power
    }
    return Promise.reject(result.codeText)
    })
    }

    在store->store-types.js
    宏观管控store中的方法名
    export const CHECK_IS_LOGIN= 'CHECK_IS_LOGIN';
    export const QUERY_POWER="QUERY_POWER";

    在store->index.js
    import Vue from 'vue';
    import Vuex from 'vuex';
    import logger from 'vuex/dist/logger';

    import * as types from './store-types'
    import {queryPower} from '../api/login'
    Vue.use(Vuex)

    export default new Vuex.Store({
    modules:{

    }
    state:{
    isLogin:false,
    power:''
    },
    mutations:{
    [types.CHECK_IS_LOGIN](state,isLogin=true){
    state.isLogin= isLogin
    },
    [types.QUERY_POWER](state,power){
    state.power = power
    }
    },
    actions:{
    [types.QUERY_POWER](context){
    queryPower().then(power=>{
    context.commit(types.QUERY_POWER,power)
    })
    }
    }
    plugins:[logger()]
    })

    main.js中
    import Vue from 'vue'
    import App from './App.vue'
    import store from './store/index'
    import router from './router'
    import * as types from './store/store-types.js'
    import { checkLogin} from './api/login'
    检测是否登录,只有保证是登录状态,才让其继续渲染组件等
    checkLogin().then(result=>{
    //把登录状态存储到Vuex中
    store.commit(stypes.CHECK_IS_lOGIN,true);
    store.dispatch(types.QUERY_POWER);
    //渲染组件
    new Vue({
    router,
    store,
    render: h=>h(APP)
    }).$mount('#app');
    }).catch(reson=>{
    Vue,prototype.$alert('只有登录的用户才能访问系统',系统提示,{
    callback:action=>P{
    location.href=location.origin+'/login.html'
    }
    })
    })

    router.js
    import Vue from 'vue';
    import VueRouter from 'vue-router',
    import Custom from './pages/Custom.vue';
    import CustomList from './pages/custom/CustomList.vue'
    import CustomHandle from './pages/custom/CustomHandle.vue'
    imort Systen from './pages/system.vue'
    Vue.use(VueRouter)
    const router= new VueRouter({
    mode:'hash'
    routes:[
    {
    path:'/',
    director:'/custom',
    },
    {
    path:'custom',
    name:'/custom',
    component:Custom,
    children:[
    {
    path:'/custom',
    redirect:{
    path:'/custom/list',
    query:{
    type:2
    }
    }
    },
    {
    path:'list',
    name:'customList',
    component:CustomList
    },
    {
    path:'Handle/:customId',
    name:'customHandle',
    component:CustomHandle
    },


    ]
    },
    {
    path:'system',
    name:'/system',
    component:System
    },
    {
    path:'*',
    director:'/custom',
    },
    ]
    })

    router.beforeEach((to,from,next)=>{
    next();
    })
    export default router

    55.p63


    多页面登录逻辑
    储存到vuex中

    登录成功:储存到本地
    1.把登录状态储存到本地(还可以把权限储存到本地)
    2.跳转到首页
    进入到首页,登录状态和权限都可以从本地获取即可
    减少和服务器的交互频率
    不能及时和服务器同步(当然也可以每次刷新页面,都从服务器获取一份放到本地)
    本地信息容易被修改或干掉 不安全

    登录逻辑
    单页面引用
    index.html(包含了登录模块)
    vuex中给初始状态
    isLogin:false
    power;''
    刷新页面第一件是,从服务器获取登录状态和权限,存储到vuex中(异步)
    每当进入到组件的时候,都去从vuex中获取登录状态,从而让其显示某个组件

    56.p63
    权限效验可能出现的情况
    1.点击某一个按钮实现路由跳转,此时我们需要效验是否有权限访问当前的组件,如果没有,我们做提示或者禁止跳转
    =>beforeEach每次路由跳转必然会执行它,所以我们需要判断,只有访问某个地址我们做对应的权限效验
    =>beforeEnter
    2.点击某个按钮实现某个功能,如果不管权限是否有,都可以点击,我们可以在点击的时候验证权限有误,从而给予响应的提示
    3.没有权限我们让功能消失 vue通常用自定义指令来完成

    import store from './store/index'
    const router= new VueRouter({
    mode:'hash'
    routes:[
    {
    path:'/',
    director:'/custom',
    },
    {
    path:'custom',
    name:'/custom',
    component:Custom,

    {
    path:'system',
    name:'/system',
    component:System,
    //系统设置的权限效验
    beforeEnter(to,from,next){
    let power= store.state.power;
    if(/(userhandle|departhandle)/.test(power)){
    next()
    return
    Vue.prototype.$alert('无权限访问此模块','系统提示')
    }
    }
    },
    {
    path:'*',
    director:'/custom',
    },
    ]
    })

    router.beforeEach((to,from,next)=>{
    next();
    })
    export default router

    自定义指令:v-power

    <el-memu-item v-power="departcustomer|allcustomer">
    在main.js
    vue.directive('power',{
    inserted(el,binding){
    setTimeout(__=>{
    let arrVal=binding.value.split('|'),
    power=store.state.power,
    flag= false;
    flag =arrVal.some(item=>{
    return power.includes(item)
    })
    !flag?el.parentNode.removeChild(el):null
    },0)
    },

    })

    57.p66
    存储所有客户信息和我的客户信息的首页

    宏观管理统一命名
    store->store-types.js
    export const CUSTOM_QUERY_LIST='CUSTOM_QUERY_LIST'

    新建api->custom.js
    import axios frm './index',
    export function queryCustomList(options){
    let params={
    lx:'all',
    type:'',
    search:'',
    page:1,
    limit:10
    };
    params =Object.assign(params,options)
    return axios.get('/customer/list',{
    params
    }).then(result=>{
    if(parseInt(result.code)===0){
    return result
    }
    return Promise.reject(result.codeText)
    })
    }

    新建store->custom.js
    import * as types from './stor-styoes.js'
    import {queryCustomList} from '../api/custom'
    export defatult{
    namespaced:true,
    state:{
    myList:null,
    allList:null,
    },
    mutations:{
    [types.CUSTOM_QUERY_LIST](state,payload){
    //=>payload={result:{},lx:my|all}
    let {lx='my',result={}}=payload
    lx==="my" ? state.myList=result : state.allList=result
    }
    },
    actions:{
    [types.CUSTOM_QUERY_LIST](context,lx='my'){
    queryCustomList({
    lx
    }).then(result){
    context.commit(types.CUSTOM_QUERY_LIST,{
    result
    lx
    })
    }.catch(()=>{

    })
    }
    },

    }

    store->index.js
    import custom from './custom'
    Vue.use(Vuex)
    export default new Vuex.store({
    modules:{
    custom
    }
    })

    custom.js
    import * as types from '../../store/store-types'
    export defautl{
    data(){
    return{}
    },
    computed:{
    result(){
    return this.queryResult()
    }
    },
    methods:{
    queryResult(){
    let {myList,allList} = this.$store.state.custom
    let lx=this.$route.query.type||'my',
    result = lx==="my"? myList : allList
    return result
    }
    },
    created(){
    //获取问号传递参数的信息
    let result = this.queryResult()
    if(result === null){
    this.$store.dispatch("custom/"+types.CUSTOM_QUERY_LIST,result)
    }

    }
    }

    58.p67
    customList.vue
    import {queryCustomList} from '../../api/custom'
    export default{
    data(){
    return {
    type:"',
    search:'',
    limit:10,
    page:1,
    }
    },
    methods:{
    queryDate(){
    queryCustomList({
    lx:this.$route.query.lx||'my',
    type:this.type,
    search:this.search,
    limit:this.limit,
    page:this.page
    }).then(result=>{
    this.result=result
    })
    }
    }
    }

    watch:{
    ["$store.state.custom.alLIst"](val){
    this.result=val
    },
    ["$store.state.custom.allList"](val){
    this.result=val
    },
    ["$storet"](all){
    this.onceVuex()
    },
    }

  • 相关阅读:
    IDEA——使用JavaScript Debugger调试代码
    CSS——通过CSS实现展示更多选项和收起
    Antd——表单使用自定义正则进行校验
    GitHub——如何切换默认分支
    Taro——安装和使用
    webpack——You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
    SSH——ssh: rejected: administratively prohibited (open failed)
    VUE——三元表达式动态渲染样式
    Windows——80端口被系统占用
    NPM——BASIC realm="Sonatype Nexus
  • 原文地址:https://www.cnblogs.com/bydzhangxiaowei/p/16530841.html
Copyright © 2020-2023  润新知