前端及开发文章及欣赏

Vue3.0脚手架+typescript+vuex

seo达人

谈一谈vue3.0和2.0的不同及其改变,还有vue3.0脚手架的搭建



步骤:



             先卸载vue2.0的脚手架:npm  uninstall  vue-cli -g,全局卸载



            安装vue3.0的脚手架: npm  install  -g  @vue/cli,全局安装



 



入口:https://blog.csdn.net/jb_7113/article/details/89928402         基础一



           https://blog.csdn.net/jb_7113/article/details/89948215         基础二

————————————————

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

Vue 3.0 前瞻,体验 Vue Function API

seo达人

概述

Vue 2.x 及以前的高阶组件的组织形式或多或少都会面临一些问题,特别是在需要处理重复逻辑的项目中,一旦开发者组织项目结构组织得不好,组件代码极有可能被人诟病为“胶水代码”。而在 Vue 2.x 及之前的版本,解决此类问题的办法大致是下面的方案:



mixin

函数式组件

slots

笔者维护的项目也需要处理大量复用逻辑,在这之前,笔者一直尝试使用mixin的方式来实现组件的复用。有些问题也一直会对开发者和维护者造成困惑,如一个组件同时mixin多个组件,很难分清对应的属性或方法写在哪个mixin里。其次,mixin的命名空间冲突也可能造成问题。难以保证不同的mixin不用到同一个属性名。为此,官方团队提出函数式写法的意见征求稿,也就是RFC:Function-based component API。使用函数式的写法,可以做到更灵活地复用组件,开发者在组织高阶组件时,不必在组件组织上考虑复用,可以更好地把精力集中在功能本身的开发上。



注:本文只是笔者使用vue-function-api提前体验 Vue Function API ,而这个 API 只是 Vue 3.0 的 RFC,而并非与最终 Vue 3.x API 一致。发布后可能有不一致的地方。



在 Vue 2.x 中使用

要想提前在Vue 2.x中体验 Vue Function API ,需要引入vue-function-api,基本引入方式如下:



import Vue from 'vue';

import { plugin as VueFunctionApiPlugin } from 'vue-function-api';

 

Vue.use(VueFunctionApiPlugin);

基本组件示例

先来看一个基本的例子:



<template>

    <div>

        <span>count is {{ count }}</span>

        <span>plusOne is {{ plusOne }}</span>

        <button @click="increment">count++</button>

    </div>

</template>

 

<script>

import Vue from 'vue';

import { value, computed, watch, onMounted } from 'vue-function-api';

 

export default {

    setup(props, context) {

        // reactive state

        const count = value(0);

        // computed state

        const plusOne = computed(() => count.value + 1);

        // method

        const increment = () => {

            count.value++;

        };

        // watch

        watch(

            () => count.value 2,

            val => {

                console.log(`count
2 is ${val});<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br /> &nbsp; &nbsp; &nbsp; &nbsp; );<br /> &nbsp; &nbsp; &nbsp; &nbsp; // lifecycle<br /> &nbsp; &nbsp; &nbsp; &nbsp; onMounted(() =&gt; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(mounted);<br /> &nbsp; &nbsp; &nbsp; &nbsp; });<br /> &nbsp; &nbsp; &nbsp; &nbsp; // expose bindings on render context<br /> &nbsp; &nbsp; &nbsp; &nbsp; return {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count,<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; plusOne,<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; increment,<br /> &nbsp; &nbsp; &nbsp; &nbsp; };<br /> &nbsp; &nbsp; },<br /> };<br /> &lt;/script&gt;<br /> 详解<br /> setup<br /> setup函数是Vue Function API 构建的函数式写法的主逻辑,当组件被创建时,就会被调用,函数接受两个参数,分别是父级组件传入的props和当前组件的上下文context。看下面这个例子,可以知道在context中可以获取到下列属性值<br /> <br /> const MyComponent = {<br /> &nbsp; &nbsp; props: {<br /> &nbsp; &nbsp; &nbsp; &nbsp; name: String<br /> &nbsp; &nbsp; },<br /> &nbsp; &nbsp; setup(props, context) {<br /> &nbsp; &nbsp; &nbsp; &nbsp; console.log(props.name);<br /> &nbsp; &nbsp; &nbsp; &nbsp; // context.attrs<br /> &nbsp; &nbsp; &nbsp; &nbsp; // context.slots<br /> &nbsp; &nbsp; &nbsp; &nbsp; // context.refs<br /> &nbsp; &nbsp; &nbsp; &nbsp; // context.emit<br /> &nbsp; &nbsp; &nbsp; &nbsp; // context.parent<br /> &nbsp; &nbsp; &nbsp; &nbsp; // context.root<br /> &nbsp; &nbsp; }<br /> }<br /> value &amp; state<br /> value函数创建一个包装对象,它包含一个响应式属性value:<br /> <br /> <br /> <br /> 那么为何要使用value呢,因为在JavaScript中,基本类型并没有引用,为了保证属性是响应式的,只能借助包装对象来实现,这样做的好处是组件状态会以引用的方式保存下来,从而可以被在setup中调用的不同的模块的函数以参数的形式传递,既能复用逻辑,又能方便地实现响应式。<br /> <br /> 直接获取包装对象的值必须使用.value,但是,如果包装对象作为另一个响应式对象的属性,Vue内部会通过proxy来自动展开包装对象。同时,在模板渲染的上下文中,也会被自动展开。<br /> <br /> import { state, value } from 'vue-function-api';<br /> const MyComponent = {<br /> &nbsp; &nbsp; setup() {<br /> &nbsp; &nbsp; &nbsp; &nbsp; const count = value(0);<br /> &nbsp; &nbsp; &nbsp; &nbsp; const obj = state({<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count,<br /> &nbsp; &nbsp; &nbsp; &nbsp; });<br /> &nbsp; &nbsp; &nbsp; &nbsp; console.log(obj.count) // 作为另一个响应式对象的属性,会被自动展开<br /> &nbsp;<br /> &nbsp; &nbsp; &nbsp; &nbsp; obj.count++ // 作为另一个响应式对象的属性,会被自动展开<br /> &nbsp; &nbsp; &nbsp; &nbsp; count.value++ // 直接获取响应式对象,必须使用.value<br /> &nbsp;<br /> &nbsp; &nbsp; &nbsp; &nbsp; return {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count,<br /> &nbsp; &nbsp; &nbsp; &nbsp; };<br /> &nbsp; &nbsp; },<br /> &nbsp; &nbsp; template:<button @click="count++">{{ count }}</button>,<br /> };<br /> 如果某一个状态不需要在不同函数中被响应式修改,可以通过state创建响应式对象,这个state创建的响应式对象并不是包装对象,不需要使用.value来取值。<br /> <br /> watch &amp; computed<br /> watch和computed的基本概念与 Vue 2.x 的watch和computed一致,watch可以用于追踪状态变化来执行一些后续操作,computed用于计算属性,用于依赖属性发生变化进行重新计算。<br /> <br /> computed返回一个只读的包装对象,和普通包装对象一样可以被setup函数返回,这样就可以在模板上下文中使用computed属性。可以接受两个参数,第一个参数返回当前的计算属性值,当传递第二个参数时,computed是可写的。<br /> <br /> import { value, computed } from 'vue-function-api';<br /> &nbsp;<br /> const count = value(0);<br /> const countPlusOne = computed(() =&gt; count.value + 1);<br /> &nbsp;<br /> console.log(countPlusOne.value); // 1<br /> &nbsp;<br /> count.value++;<br /> console.log(countPlusOne.value); // 2<br /> &nbsp;<br /> // 可写的计算属性值<br /> const writableComputed = computed(<br /> &nbsp; &nbsp; // read<br /> &nbsp; &nbsp; () =&gt; count.value + 1,<br /> &nbsp; &nbsp; // write<br /> &nbsp; &nbsp; val =&gt; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; count.value = val - 1;<br /> &nbsp; &nbsp; },<br /> );<br /> watch第一个参数和computed类似,返回被监听的包装对象属性值,不过另外需要传递两个参数:第二个参数是回调函数,当数据源发生变化时触发回调函数,第三个参数是options。其默认行为与 Vue 2.x 有所不同:<br /> <br /> lazy:是否会在组件创建时就调用一次回调函数,与 Vue 2.x 相反,lazy默认是false,默认会在组件创建时调用一次。<br /> deep:与 Vue 2.x 的 deep 一致<br /> flush:有三个可选值,分别为 'post'(在渲染后,即nextTick后才调用回调函数),'pre'(在渲染前,即nextTick前调用回调函数),'sync'(同步触发)。默认值为'post'。<br /> // double 是一个计算包装对象<br /> const double = computed(() =&gt; count.value * 2);<br /> &nbsp;<br /> watch(double, value =&gt; {<br /> &nbsp; &nbsp; console.log('double the count is: ', value);<br /> }); // -&gt; double the count is: 0<br /> &nbsp;<br /> count.value++; // -&gt; double the count is: 2<br /> 当watch多个被包装对象属性时,参数均可以通过数组的方式进行传递,同时,与 Vue 2.x 的vm.$watch一样,watch返回取消监听的函数:<br /> <br /> const stop = watch(<br /> &nbsp; &nbsp; [valueA, () =&gt; valueB.value],<br /> &nbsp; &nbsp; ([a, b], [prevA, prevB]) =&gt; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; console.log(a is: ${a});<br /> &nbsp; &nbsp; &nbsp; &nbsp; console.log(b is: ${b});<br /> &nbsp; &nbsp; }<br /> );<br /> &nbsp;<br /> stop();<br /> 注意:在RFC:Function-based component API初稿中,有提到effect-cleanup,是用于清理一些特殊情况的副作用的,目前已经在提案中被取消了。<br /> <br /> 生命周期<br /> 所有现有的生命周期都有对应的钩子函数,通过onXXX的形式创建,但有一点不同的是,destoryed钩子函数需要使用unmounted代替:<br /> <br /> import { onMounted, onUpdated, onUnmounted } from 'vue-function-api';<br /> &nbsp;<br /> const MyComponent = {<br /> &nbsp; &nbsp; setup() {<br /> &nbsp; &nbsp; &nbsp; &nbsp; onMounted(() =&gt; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('mounted!');<br /> &nbsp; &nbsp; &nbsp; &nbsp; });<br /> &nbsp; &nbsp; &nbsp; &nbsp; onUpdated(() =&gt; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('updated!');<br /> &nbsp; &nbsp; &nbsp; &nbsp; });<br /> &nbsp; &nbsp; &nbsp; &nbsp; // destroyed 调整为 unmounted<br /> &nbsp; &nbsp; &nbsp; &nbsp; onUnmounted(() =&gt; {<br /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log('unmounted!');<br /> &nbsp; &nbsp; &nbsp; &nbsp; });<br /> &nbsp; &nbsp; },<br /> };<br /> 一些思考<br /> 上面的详解部分,主要抽取的是 Vue Function API 的常见部分,并非RFC:Function-based component API的全部,例如其中的依赖注入,TypeScript类型推导等优势,在这里,由于篇幅有限,想要了解更多的朋友,可以点开RFC:Function-based component API查看。个人也在Function-based component API讨论区看到了更多地一些意见:<br /> <br /> 由于底层设计,在setup取不到组件实例this的问题,这个问题在笔者尝试体验时也遇到了,期待正式发布的 Vue 3.x 能够改进这个问题。<br /> <br /> 对于基本类型的值必须使用包装对象的问题:在 RFC 讨论区,为了同时保证TypeScript类型推导、复用性和保留Vue的数据监听,包装属性必须使用.value来取值是讨论最激烈的<br /> <br /> 关于包装对象value和state方法命名不清晰可能导致开发者误导等问题,已经在Amendment proposal to Function-based Component API这个提议中展开了讨论:<br /> <br /> setup() {<br /> &nbsp; &nbsp; const state = reactive({<br /> &nbsp; &nbsp; &nbsp; &nbsp; count: 0,<br /> &nbsp; &nbsp; });<br /> &nbsp;<br /> &nbsp; &nbsp; const double = computed(() =&gt; state.count * 2);<br /> &nbsp;<br /> &nbsp; &nbsp; function increment() {<br /> &nbsp; &nbsp; &nbsp; &nbsp; state.count++;<br /> &nbsp; &nbsp; }<br /> &nbsp;<br /> &nbsp; &nbsp; return {<br /> &nbsp; &nbsp; &nbsp; &nbsp; ...toBindings(state), // retains reactivity on mutations made tostate`

        double,

        increment,

    };

}

 



引入reactive API 和 binding API,其中reactive API 类似于 state API , binding API 类似于 value API。

之前使用的方法名state在 Vue 2.x 中可能被用作组件状态对象,导致变量命名空间的冲突问题,团队认为将state API 更名为 reactive 更为优雅。开发者能够写出const state = ... ,然后通过state.xxxx这种方式来获取组件状态,这样也相对而言自然一些。

value方法用于封装基本类型时,确实会出现不够优雅的.value的情况,开发者可能会在直接对包装对象取值时忘记使用.value,修正方案提出的 reactive API,其含义是创建响应式对象,初始化状态state就使用reactive创建,可保留每项属性的getter和setter,这么做既满足类型推导,也可以保留响应式引用,从而可在不同模块中共享状态值的引用。

但reactive可能导致下面的问题,需要引入binding API。 解决,如使用reactive创建的响应式对象,对其使用拓展运算符...时,则会丢失对象的getter和setter,提供toBindings方法能够保留状态的响应式。

当然,目前 Vue Function API 还处在讨论阶段,Vue 3.0 还处在开发阶段,还是期待下半年 Vue 3.0 的初版问世吧,希望能给我们带来更多的惊喜。


前端学习与工作中常用网站推荐

seo达人

一.视频学习网站

1.慕课网(我的最爱,里面有很多免费的视频)



2.腾讯课堂 



。。。



当然还有很多其他的视频学习网站,但我觉得就这两个就够质够量了。



二.前端免费模板下载

1.html5tricks



有很多有趣的小程序



2.源码之家 



各类模板灰常之多,不过也有很多广告



3.代码家园



整个网站看起来舒服,广告很少



4.模板之家



广告较多



5.魔客吧



有些要money



6.站长之家



。。。



模板网站就推荐这些吧,差不多够用了。当然,我们下载这些模板的目的不是为了抄袭,而是为了参考学习。(手动滑稽:) )



三.图片图标logo素材

1.标志在线



免费设计logo



2.阿里巴巴矢量图标



图标特别多,而且基本上都是免费的



3.iconmonstr



免费图标下载



4.懒人图库



素材很多,不知道要不要钱



5.loading.io



看名字就知道是下什么的了吧



6.preloaders



进度条下载,有些要钱还是dollar,不过也有很多免费的



。。。



好吧,就这些。



四.其他

1.JS格式化



如果你的编辑器不支持格式化js代码的话可以试试



2.css代码兼容



css代码复制上去,自动会帮你生成兼容的css代码,是不是很厉害!不过兼容IE几我也不太清楚,你们自己去看看吧



3.配色



这是给你网站配色的,有兴趣的可以了解下



4.html、css、js压缩,js多文件合并



es6代码需先转es5再压缩,当然,也可以使用fis3构建压缩html,css,js;fis3还可以将图片转成webp格式(ios有兼容问题)



5.图片压缩



基本上是无损压缩,效果很不错



6.图片转换



转webp格式图片



7.雪碧图 (似乎访问不了了)



选中雪碧图中的图片,自动生成css代码。如:background: url('imgs/example.png') no-repeat -433px -51px;width: 33px;height: 33px;



8.html在线编辑工具



可以在线运行html代码



9.rgb,rgba,十六进制等颜色相互转换



10.HTML特殊字符编码对照表



11.改图宝



修改图片尺寸,生成二维码,生成印章,图片加水印...



。。。



 



最后,再推荐一些比较好的书



《css世界》、《ES6标准入门》阮一峰、《JavaScript权威指南》、《JavaScript高级程序设计》(红皮书)、《你不知道的JavaScript 上中下册》

————————————————


el-table + el-form实现可编辑表格字段验证

seo达人

表格输入信息很常见,因此表格的验证也很必要,el-form提供了输入框验证.可以和表格结合起来用,使用效果
 
 
HTML:
<div class="table_box">
  <el-button type="primary" class="submit_btn" @click="addTable">添加</el-button> <!-- 如果不想展示错误提示信息,可以加上show-message参数 --> <el-form :model="productRuleForm" ref="productRuleForm" :rules="productRuleForm.rules" :show-message="false">
    <el-table
      :data="productRuleForm.tableData" border
      style="width: 100%">
      <el-table-column
        prop="date" label="日期" width="180">
        <template slot-scope="scope"> <!-- prop的规则: 在普通的form表单中是一个对象,prop是对象的属性. 表格是由多个对象组成的数组,在写prop是需要根据索引给值.这里的tableData就相当于对象的属性 !-->
        <!-- rules也要单独给 --> <el-form-item :prop="'tableData.' + scope.$index + '.date'"
            :rules='productRuleForm.rules.date'>
            <el-date-picker
              v-model="scope.row.date" value-format="yyyy-MM-dd" placeholder="选择日期">
            </el-date-picker>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column
        prop="name" label="姓名" width="180">
        <template slot-scope="scope">
          <el-form-item
            :prop="'tableData.' + scope.$index + '.name'" :rules='productRuleForm.rules.name'>
            <el-input v-model="scope.row.name"></el-input>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column
        prop="phone" label="电话">
        <template slot-scope="scope">
          <el-form-item
            :prop="'tableData.' + scope.$index + '.phone'" :rules='productRuleForm.rules.phone'>
            <el-input v-model="scope.row.phone"></el-input>
          </el-form-item>
        </template>
      </el-table-column>
      <el-table-column
        prop="address" label="地址">
        <template slot-scope="scope">
          <el-form-item
            :prop="'tableData.' + scope.$index + '.address'" :rules='productRuleForm.rules.address'>
            <el-input v-model="scope.row.address"></el-input>
          </el-form-item>
        </template>
      </el-table-column>
    </el-table>
  </el-form>
  <el-button type="primary" class="submit_btn" @click="submit">提交</el-button>
</div>

 


        

 

js:

data () { return {
      productRuleForm: {
        tableData: [{
          date: '',
          name: '',
          phone: '',
          address: '' }],
        rules: {
          date: [{ required: true, message: '请选择日期', trigger: 'change' }],
          name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
          phone: [{ required: true, message: '请输入电话号码', trigger: 'blur' }],
          address: [{ required: true, message: '请输入地址', trigger: 'blur' }]
        }
      }
    }
  },
 methods: { // 添加一行  addTable () { this.productRuleForm.tableData.push({
        date: '',
        name: '',
        phone: '',
        address: '' })
    }, // 提交数据  submit () { this.$refs['productRuleForm'].validate((valid) => { if (valid) {

        }
      })
    } 
            

}

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

element ui在table中放入input且实现验证

seo达人

<template>

  <div class="app-container" style="overflow: auto;">

    <el-table

      :data="list"

      size="small"

      element-loading-text="Loading"

      border

      highlight-current-row

    >

      <el-table-column label="会员账号">

        <template slot-scope="scope">

          <el-form :model="scope.row" :rules="rules">

            <el-form-item prop="login">

              <el-input v-show="true" v-model="scope.row.login" placeholder="请输入会员账号"/>

            </el-form-item>

          </el-form>

        </template>

      </el-table-column>

      <el-table-column label="真实姓名">

        <template slot-scope="scope">

          <el-form :model="scope.row" :rules="rules">

            <el-form-item prop="real_name">

              <el-input v-show="true" v-model="scope.row.real_name" placeholder="请输入真实姓名"/>

            </el-form-item>

          </el-form>

        </template>

      </el-table-column>

      <el-table-column label="会员昵称">

        <template slot-scope="scope">

          <el-form :model="scope.row" :rules="rules">

            <el-form-item prop="nickname">

              <el-input v-show="true" v-model="scope.row.nickname" placeholder="请输入会员昵称"/>

            </el-form-item>

          </el-form>

        </template>

      </el-table-column>

      <el-table-column label="会员手机">

        <template slot-scope="scope">

          <el-form :model="scope.row" :rules="rules">

            <el-form-item prop="mobile">

              <el-input v-show="true" v-model="scope.row.mobile" placeholder="请输入手机号码"/>

            </el-form-item>

          </el-form>

        </template>

      </el-table-column>

      <el-table-column label="操作">

        <template slot-scope="scope">

          <el-form ref="scope.row" :model="scope.row">

            <el-form-item>

              <el-button @click="handleSubmit(scope.$index,scope.row)">重试</el-button>

            </el-form-item>

          </el-form>

        </template>

      </el-table-column>

    </el-table>

  </div>

</template>

<script>

import { retry } from '@/api/table'

import { validateName } from '@/utils/validate'

import { validateMobile } from '@/utils/validate'

 

export default {

  data() {

    // validator

    const validateNameInput = (rule, value, callback) => {

      if (!value) {

        return callback(new Error('此项必填!'))

      } else {

        callback()

      }

    }

    const validateMobileInput = (rule, value, callback) => {

      if (!value) {

        return callback(new Error('手机号码必填!'))

      } else if (!validateMobile(value)) {

        return callback(new Error('请填写正确的手机号码格式!'))

      } else {

        callback()

      }

    }

 

    return {

      list: [],

      // input框失焦校验

      rules: {

        nickname: [{ validator: validateNameInput, trigger: 'blur' }],

        real_name: [{ validator: validateNameInput, trigger: 'blur' }],

        mobile: [{ validator: validateMobileInput, trigger: 'blur' }],

        login: [{ validator: validateNameInput, trigger: 'blur' }]

      }

    }

  },

  created() {

    this.fetchData()

  },

  methods: {

    fetchData() {

      const errorData = JSON.parse(this.$route.query.errorData)

      this.list = JSON.parse(errorData)

    },

    handleSubmit(index, row) {

      // 提交校验

      if (validateName(row.login) && validateName(row.real_name) && validateName(row.nickname) && validateMobile(row.mobile)) {

       //数据提交和错误catch

    }

  }

}

</script>

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

Vue一些注意点

seo达人

1.Method与计算属性computed的区别

区别在于method每次都执行函数,而computed基于依赖缓存,只要相关值不变,那么就不必再执行函数。



下面,注意Date不是响应式依赖:



computed: {

  now: function () {

    return Date.now()

  }

}

所以使用计算属性



2.v-if与v-show

v-if 是真实的条件渲染,因为它会确保条件块在切换当中适当地销毁与重建条件块内的事件监听器和子组件。



v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。



相比之下, v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。



一般来说, v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换使用 v-show 较好,如果在运行时条件不大可能改变则使用 v-if 较好。



令,v-show不支持template语法。



3.v-for

可以v-for="item in items"也可以of



还有可选第二参数作为前项的索引:



<li v-for="(item, index) in items">

也可以用模板渲染父节点或模板,来渲染多个子块。



<ul id="repeat-object" class="demo">

     <li v-for="value in object">

       {{ value }}

     </li>

  </ul>

new Vue({

       el: '#repeat-object',

       data: {

       object: [

        {FirstName: 'John'},

        {LastName: 'Doe'},

        {Age: 30}

      ]

    }

  })

写成这样,输出:



{ "FirstName": "John" }

{ "LastName": "Doe" }

{ "Age": 30 }

将object从数组变为如下:



object: {



FirstName: 'John',



LastName: 'Doe',



Age: 30



}



那么输出:



John

Doe

30

此时直接指向的是值了。



还有三参数:v-for="(value, key, index) in object"

还可以用整数,输出10个数字:



<div id="haha">

  <span v-for="n in 10">{{ n }}</span>

</div>

var t=1,n=0;

new Vue({

 el: '#haha',

 data: {

 object: {

 n:n+t

  }

 }

})

很好的例子

4.一些数组方法

push():在末尾添加一个或多个元素,并返回新长度

pop():删除并返回最后一个元素

shift():删除并返回第一个元素

unshift():数组开头添加一个或多个元素,并返回新长度

splice():删除或替换元素,返回被删除元素。splice(index,number,new ele),用new ele 替换index开始的number个元素

sort()

reverse()





5.类似v-on:click(含参)的注意点

<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>

methods: {

  warn: function (message, event) {

    // 现在我们可以访问原生事件对象

    if (event) event.preventDefault()

    alert(message)

  }

}

如上,可以传入原生DOM对象。

阻止冒泡还有其他方法,即在v-on上使用事件修饰符。常见事件修饰符有:

<!-- 阻止单击事件冒泡 -->

<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->

<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联  -->

<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->

<form v-on:submit.prevent></form>

<!-- 添加事件侦听器时使用事件捕获模式 -->

<div v-on:click.capture="doThis">...</div>

<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->

<div v-on:click.self="doThat">...</div>

<!-- 只会触发一次点击 -->

<a v-on:click.once="doThis"></a>

有事件修饰符,还有键盘修饰符。

<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->

<input v-on:keyup.13="submit">

<input v-on:keyup.enter="submit">

又新增了按键修饰符,和组合键修饰:

<!-- Alt + C -->

<input @keyup.alt.67="clear">

<!-- Ctrl + Click -->

<div @click.ctrl="doSomething">Do something</div>

6.神奇的v-model

神奇之处在于会根据控件形式自动选取方法更新元素。

例子

<div id="che">

      <select v-model="sele"  multiple>

         <option v-for="op in ops" v-bind:value="op.index">{{op.va}}</option>

         

      </select>

      <span>{{sele}}</span>

    </div>

new Vue({

          el: '#che',

          data: {

            sele: [],

            ops:[

                {index:1,va:"s"},

                {index:2,va:"ss"},

                {index:3,va:"ssr"}

            ]

          }

        })

若option里绑定value,则会将value值按所选中的放在数组sele开头。

若没有绑定value,会将{{op.va}}当做value。若写为{{op.index}}则将index当做value。



蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

Sass开发注意点

seo达人

避免选择器嵌套:

选择器嵌套最大的问题是将使最终的代码难以阅读。开发者需要花费巨大精力计算不同缩进级别下的选择器具体的表现效果。

选择器越具体则声明语句越冗长,而且对最近选择器的引用(&)也越频繁。在某些时候,出现混淆选择器路径和探索下一级选择器的错误率很高,这非常不值得。



混合宏

在 Sass 中通过 @mixin 关键词声明了一个混合宏,那么在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏。



@mixin border-radius{

  -webkit-border-radius: 3px;

  border-radius: 3px;

}



.box {

  @include border-radius;

  margin-bottom: 5px;

}



.btn {

  @include border-radius;

}



继承 @extend

在 Sass 中也具有继承一说,也是继承类中的样式代码块。在 Sass 中是通过关键词 “@extend”来继承已存在的类样式块,从而实现代码的继承。如下所示:



//SCSS

.btn {

  border: 1px solid #ccc;

  padding: 6px 10px;

  font-size: 14px;

}



.btn-primary {

  background-color: #f36;

  color: #fff;

  @extend .btn;

}



.btn-second {

  background-color: orange;

  color: #fff;

  @extend .btn;

}



编译后



//CSS

.btn, .btn-primary, .btn-second {

  border: 1px solid #ccc;

  padding: 6px 10px;

  font-size: 14px;

}



.btn-primary {

  background-color: #f36;

  color: #fff;

}



.btn-second {

  background-clor: orange;

  color: #fff;

}



占位符 %

Sass 中的占位符 %placeholder 功能是一个很强大,很实用的一个功能,这也是我非常喜欢的功能。他可以取代以前 CSS 中的基类造成的代码冗余的情形。因为 %placeholder 声明的代码,如果不被 @extend 调用的话,不会产生任何代码。



//SCSS

%mt5 {

  margin-top: 5px;

}

%pt5{

  padding-top: 5px;

}



.btn {

  @extend %mt5;

  @extend %pt5;

}



.block {

  @extend %mt5;



  span {

    @extend %pt5;

  }

}



编译后(代码相同的会自动整合)



//CSS

.btn, .block {

  margin-top: 5px;

}



.btn, .block span {

  padding-top: 5px;

}





蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

关于Vue中的slot的理解

seo达人

今天在做vue项目的时候,遇到一个问题就是slot插槽的概念。这突然让我想起用过类似于element-ui前端框架时,用他们组件的时候接触过slot,如下图: 







这是element-ui对话框的api,当时我记得我百度过,就是这样写就ok了,当时也没深究。



<el-dialog :visible.sync="dialogVisible" width="30%" :before-close="handleClose">

  <span slot="title">

    我是对话框标题

  </span>

  <!-- 这边写对话框的内容 -->

  <span>我是对话框内容</span>

  <span slot="footer" class="dialog-footer">

    我是对话框footer

  </span>

</el-dialog>

效果是这样:







今天研究了,我就查看了源码:







百度的发现这边有两个概念:



1.单个插槽也叫匿名插槽



slot不带name,如下:



<slot></slot>

一个子组件只有一个匿名插槽,就好比对话框的内容没有被含有slot="xx"属性的标签包裹,那么就会替换掉匿名插槽



2.具名插槽



slot 有name,如下



<slot name='xx'></slot>

具名插槽就可以有多个,就好比对话框含有slot='header'属性的标签会替换掉子组件<slot name='header'></slot>


JavaScript杂记(杂而又杂)

seo达人

JavaScript杂记

JavaScript可以直接写入 HTML 输出流

JavaScript 能够直接写入 HTML 输出流中:



之间的代码行包含了 JavaScript: 您可以在 HTML 文档中放入不限数量的脚本。 脚本可位于 HTML 的 或 部分中,或者同时存在于两个部分中。 通常的做法是把函数放入 部分中,或者放在页面底部。这样就可以把它们安置到同一处位置,不会干扰页面的内容。 6. 外部的 JavaScript 也可以把脚本保存到外部文件中。外部文件通常包含被多个网页使用的代码。 外部 JavaScript 文件的文件扩展名是 .js。 如需使用外部文件,请在

这个程序写的不好,因为它没有触法程序,不能体现JS的作用

使用 document.write() 方法将内容写到 HTML 文档中。

使用 innerHTML 写入到 HTML 元素。

使用 console.log() 写入到浏览器的控制台。

console.log() 方法能够让你看到你在页面中的输出内容,让你更容易调试javascript;与alert相比,console不会打断你页面的操作,console里面的内容非常丰富,你可以在控制台输入 console。

您知道吗?

Note 程序中调试是测试,查找及减少bug(错误)的过程。

8. JavaScript 数据类型

JavaScript 有多种数据类型:数字,字符串,数组,对象等等:



var length = 16; // Number 通过数字字面量赋值

var points = x * 10; // Number 通过表达式字面量赋值

var lastName = “Johnson”; // String 通过字符串字面量赋值

var cars = [“Saab”, “Volvo”, “BMW”]; // Array 通过数组字面量赋值

var person = {firstName:“John”, lastName:“Doe”}; // Object 通过对象字面量赋值

9. Value = undefined

在计算机程序中,经常会声明无值的变量。未使用值来声明的变量,其值实际上是 undefined。



在执行过以下语句后,变量 carname 的值将是 undefined:



var carname;

10. Undefined 和 Null

Undefined 这个值表示变量不含有值。



可以通过将变量的值设置为 null 来清空变量。

11. 声明变量类型

当您声明新变量时,可以使用关键词 “new” 来声明其类型:



var carname=new String;

var x= new Number;

var y= new Boolean;

var cars= new Array;

var person= new Object;



JavaScript 变量均为对象。当您声明一个变量时,就创建了一个新的对象。



JavaScript函数

在JavaScript中,函数即对象,可以随意地被程序操控,函数可以嵌套在其他函数中定义,这样可以访问它们被定义时所处的作用域中的任何变量。

函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块。

<1>JavaScript 函数语法

函数就是包裹在花括号中的代码块,前面使用了关键词 function:



function functionname()

{

执行代码

}



当调用该函数时,会执行函数内的代码。



可以在某事件发生时直接调用函数(比如当用户点击按钮时),并且可由 JavaScript 在任何位置进行调用。



lamp JavaScript 对大小写敏感。关键词 function 必须是小写的,并且必须以与函数名称相同的大小写来调用函数。

提示:function 中的花括号是必需的,即使函数体内只包含一条语句,仍然必须使用花括号将其括起来。



<2>带有返回值的函数

有时,我们会希望函数将值返回调用它的地方。



通过使用 return 语句就可以实现。



在使用 return 语句时,函数会停止执行,并返回指定的值。

<3>在您仅仅希望退出函数时 ,也可使用 return 语句。返回值是可选的:



function myFunction(a,b)

{

if (a>b)

{

return;

}

x=a+b

}

如果 a 大于 b,则上面的代码将退出函数,并不会计算 a 和 b 的总和。



<3>局部 JavaScript 变量

在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内访问它。(该变量的作用域是局部的)。

您可以在不同的函数中使用名称相同的局部变量,因为只有声明过该变量的函数能识别出该变量。

只要函数运行完毕,本地变量就会被删除。

局部变量比同名全局变量的优先级高,所以局部变量会隐藏同名的全局变量。



全局 JavaScript 变量

在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。



JavaScript 变量的生存期

JavaScript 变量的生命期从它们被声明的时间开始。

局部变量会在函数运行以后被删除。

全局变量会在页面关闭后被删除。



向未声明的 JavaScript 变量分配值

如果您把值赋给尚未声明的变量,该变量将被自动作为全局变量声明。

这条语句:

carname=“Volvo”;

将声明一个全局变量 carname,即使它在函数内执行。

13. JavaScript 作用域

作用域是可访问变量的集合。



在JavaScript中,能够定义全局作用域或者局部作用域。



HTML 中的全局变量

在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。

实例

//此处可使用 window.carName



function myFunction() {

carName = “Volvo”;

}



你的全局变量,或者函数,可以覆盖 window 对象的变量或者函数。

局部变量,包括 window 对象可以覆盖全局变量和函数。

也就是说全局变量可以覆盖全局变量,局部可以在局部作用域里面覆盖全局变量



JavaScript事件

JavaScript 事件

事件是可以被 JavaScript 侦测到的行为。

HTML 事件是发生在 HTML 元素上的事情。



当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件。

HTML 事件

HTML 事件可以是浏览器行为,也可以是用户行为。

HTML 网页中的每个元素都可以产生某些可以触发 JavaScript 函数的事件。

以下是 HTML 事件的实例:

HTML 页面完成加载

HTML input 字段改变时

HTML 按钮被点击

通常,当事件发生时,你可以做些事情。

在事件触发时 JavaScript 可以执行一些代码。

HTML 元素中可以添加事件属性,使用 JavaScript 代码来添加 HTML 元素。

单引号:



双引号:

常见的HTML事件

下面是一些常见的HTML事件的列表:

事件 描述

onchange HTML 元素改变

onclick 用户点击 HTML 元素

onmouseover 用户在一个HTML元素上移动鼠标

onmouseout 用户从一个HTML元素上移开鼠标

onkeydown 用户按下键盘按键

onload 浏览器已完成页面的加载

15. JavaScript 字符串

JavaScript 字符串用于存储和处理文本。



字符串长度

可以使用内置属性 length 来计算字符串的长度:



字符串属性和方法

原始值字符串,如 “John”, 没有属性和方法(因为他们不是对象)。

原始值可以使用 JavaScript 的属性和方法,因为 JavaScript 在执行方法和属性时可以把原始值当作对象。

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

调整浏览器分辨率的插件下载方法

seo达人

前端开发在开发过程中经常会被UI小姐姐要求开发的各个页面都按照她的理想效果显示,所以就需要前端经常调整自己的浏览器分辨率,而今天笔者给大家带来的就是谷歌调整浏览器分辨率的插件下载配置方法:



点击不同的分辨率,浏览器就会开始切换了。



接下来笔者给大家分享如何下载和配置这个插件:

下载地址:https://me.csdn.net/download/weixin_43606158



或者关注笔者后加笔者QQ/微信笔者私聊发你:1336791007



下载后请先在谷歌浏览器上方输入 chrome://extensions/ 进入到谷歌的拓展程序。



而后将下载后的文件移动到谷歌拓展程序界面上。





PS如果出现程序包无效:“CRX_HEADER_INVALID”。这个提示,请看下方的解决办法链接。





解决 程序包无效:“CRX_HEADER_INVALID” 方法的链接:https://blog.csdn.net/weixin_43606158/article/details/97517104

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档