澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

澳门新浦京娱乐场网站:完整实现代码,插件开

vuejs 初体验— Chrome 插件开发实录

2017/05/16 · JavaScript · Chrome, vuejs

原文出处: janilychen   

一、入门

欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~

下载安装搭建环境

  • 可以选npm安装,或者简单下载一个开发版的vue.js文件
  • 浏览器打开加载有vue的文档时,控制台提示可以安装vue控制台插件,于是去chrome商店安装,Firefox的插件是通过模拟chrome插件来辅助安装的。但是第一次点击Vue Devtools提示“vue.js is not detected”,咦,原来我忘记勾选“允许访问文件地址”,勾选后就可以正常运行了。

背景

对于经常和动画开发打交道的开发者对于Animate.css这个动画库不会陌生,它把一些常见的动画效果都封装起来了,非常实用。但是有时候在开发中,仅仅只是需要某一两个动画效果,把整个CSS文件都引入,这样不是太好。

需求就出现了,能不能有一个工具可以直接预览Animate.css对应的动画效果,并且生成对应的动画代码呢?

作为一个UI开发,平时跟Chrome浏览器打交道最多,于是就整了一个Chrome插件可以及时预览对应Animate.css中的动画效果并生成对应的动画代码,这样在实际开发中碰到一些需要使用到Animate.css中的动画效果时,可以大大的提高我们的开发效率。

插件安装地址,快来安装体验吧!

作为一个程序员,捣鼓些小工具,不但可以学些新技术还可以提高我们的开发效率,何乐而不为呢。

下面就以一个简单的flexbox对齐预览的插件为例,讲讲使用vuejs开发Chrome插件的开发体验和效率。

扩展如下图所示:

澳门新浦京娱乐场网站 1

插件主要功能是根据用户选择的对齐方式,实时预览效果和显示对应的CSS代码,方便我们可以直接拷贝代码使用。

这是制作chrome扩展插件的入门指南,不需要任何编程基础,看完这个后,我们就着手做自己的Chrome插件了。好吧,我们现在就开始,其实我也是个新手。

作者:陈纬杰

第一个demo

Hello Vue!
关键词:模板语法、声明式

这里有个小bug,JSFiddle Hello World例子中,并没有为new Vue赋值变量,于是教程中接下来说的,“修改app.message”就没法实现,认真看教程中代码可以看到它为其赋值命名为app,下一个例子命名为app-2,命名后就可以在控制台采用“名称.属性”的形式访问修改内容了。

Chrome插件开发基本知识

在应用商店中下载下来的插件基本上都是以.crx为文件后缀,该文件其实就是一个压缩包,包括插件所需要的html、css、javascript、图片资源等等文件。

开发一个插件就跟我们平时做web开发流程没多大的区别,就是先搭好基本的页面,然后使用js来写交互逻辑等功能。

比如我这个插件的目录文件如下:

澳门新浦京娱乐场网站 2

澳门新浦京娱乐场网站 3

背景

对于经常和动画开发打交道的开发者对于Animate.css这个动画库不会陌生,它把一些常见的动画效果都封装起来了,非常实用。但是有时候在开发中,仅仅只是需要某一两个动画效果,把整个CSS文件都引入,这样不是太好。

需求就出现了,能不能有一个工具可以直接预览Animate.css对应的动画效果,并且生成对应的动画代码呢?

作为一个UI开发,平时跟Chrome浏览器打交道最多,于是就整了一个Chrome插件可以及时预览对应Animate.css中的动画效果并生成对应的动画代码,这样在实际开发中碰到一些需要使用到Animate.css中的动画效果时,可以大大的提高我们的开发效率。

插件安装地址,快来安装体验吧!

作为一个程序员,捣鼓些小工具,不但可以学些新技术还可以提高我们的开发效率,何乐而不为呢。

下面就以一个简单的flexbox对齐预览的插件为例,讲讲使用vuejs开发Chrome插件的开发体验和效率。

扩展如下图所示:

澳门新浦京娱乐场网站 4

并且还实时根据用户选择的对齐方式,显示对应的CSS代码,方便我们可以直接拷贝代码使用。

第二个demo

新指令:v-bind
用法

  • html——v-bind:title="message"
  • js——data:{message:'内容'}

新指令:v-if
用法:根据值的真假决定是否渲染DOM内容
原理:Vue可以绑定DOM结构到数据


新指令:v-for
用法

  • html——<li v-for="todo in todos">{{todo.text}}</li>
  • js——data:{todos:[{text:"内容1"},{text:"内容2"},{text:"内容3"}]}

原理:v-for是一个包装过的for in循环,对应的data内需要有一个数组


新指令:v-on
用法

  • html——绑定事件----v-on:click="事件名字"
  • js——methods:{事件名字:function(){处理内容}}

新指令:v-model
用法:

  • html——<input v-model="message">
  • js——data:{message:"hello vue"}

原理:v-model可实现表单输入和应用状态的双向绑定,修改表单内容,message对应值也会修改。

manifest.json文件

文件中需要注意一下的mainfest.json这个文件,这个json文件的作用是提供插件的各种信息,例如插件能够做的事情,以及插件的文件配置等等信息。下面是一个清单文件的示例:

{ "manifest_version": 2, "name": "One-click Kittens", "description": "This extension demonstrates a browser action with kittens.", "version": "1.0", "permissions": [ "" ], "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "manifest_version": 2,
 
  "name": "One-click Kittens",
  "description": "This extension demonstrates a browser action with kittens.",
  "version": "1.0",
 
  "permissions": [
    "https://secure.flickr.com/"
  ],
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  }
}

第一行声明我们使用清单文件格式的版本 2,必须包含(版本 1 是旧的,已弃用,不建议使用)。

接下来的部分定义扩展程序的名称、描述与版本。这些都会在 Chrome 浏览器中使用,向用户显示已安装的扩展程序,同时在 Chrome 网上应用店中向潜在的新用户显示您的扩展程序。名称应该简练,描述不要比一句话左右还长(后面将会有更多的空间用于更详细的描述)。

最后一部分首先请求权限,用于访问 上的数据,并声明该扩展程序实现了一个浏览器按钮,同时在这一过程中为它指定一个默认图标与弹出窗口。

定义浏览器按钮时指向了两个资源文件:icon.png 与 popup.html。这两个资源都必须在扩展程序包中存在,图片是扩展的显示,html是扩展具体运行的基础文件。

具体详细的开发教程可以看看官方的这个文档,非常简明的入门教程。

准备工具

Chrome插件开发基本知识

在应用商店中下载下来的插件基本上都是以.crx为文件后缀,该文件其实就是一个压缩包,包括插件所需要的html、css、javascript、图片资源等等文件。

开发一个插件就跟我们平时做web开发流程没多大的区别,就是先搭好基本的页面,然后使用js来写交互逻辑等功能。

比如我这个插件的目录文件如下:

澳门新浦京娱乐场网站 5

组件化应用构建

  • 注册组件
Vue.component('todo-item',{
      template:'<li>这是一个待办项</li>'
})
  • 使用
<ol>
    <todo-item></todo-item>
</ol>

但是这样实现,会为每个元素绑定相同文本,Vue可以将数据从父作用域传到子组件。

  • 注册组件
Vue.component('todo-item', {
  props: ['todo'],
  template: '<li>{{ todo.text }}</li>'
})
  • 创建元素并v-bind绑定数据到一个对象
<div id="app-7">
  <ol>
    <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item>
  </ol>
</div>
  • 创建对象
var app7 = new Vue({
  el: '#app-7',
  data: {
    groceryList: [
      { text: '蔬菜' },
      { text: '奶酪' },
      { text: '随便其他什么人吃的东西' }
    ]
  }
})
  • props是作为一个接口存在的。
  • Vue组件非常类似于自定义元素,但是有一些纯自定义元素不具备的重要功能,包括跨组件数据流,自定义事件通信和构建工具集成。

功能实现-Vuejs实践

整个插件的核心交互功能非常简单,如文章开头的动图所示,用户选择对齐方式,代码区域显示对应的代码。这种简单数据交互使用vuejs再适合不过了,vuejs基础知识这里就不再细说了。

这里需要注意的一点是,chrome 扩展的运行环境有一些特殊要求,称为 Content Security Policy (CSP),使得通常的 vue 不能被正常使用。如果用的是 vue 1.x,那么可以下载 csp 版本,在 这里。如果是 2.x 版本,请参考官网文档的这一段。

核心代码如下所示。

HTML:

XHTML

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- 引入样式 --> <link rel="stylesheet" href="main.css"> <link rel="stylesheet" href="mystique.css"> </head> <body> <div id="app"> <h1 class="title-box">flexbox对齐就是这么简单</h1> </div> <div id="type-select"> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select> <!-- <span>Selected: {{ selected }}</span> --> <div class="resule-preview"> <div v-bind:class="selected" class="cols"> <div class="col col-3"> <p>对齐</p> </div> <div class="col col-3"> <p>对齐</p> </div> <div class="col col-3"> <p>对齐</p> </div> </div> </div> <div class="resule-code"> <pre class="code-display"> <code class="code-lang"> {{ cssMsg }} </code> </pre> </div> </div> <!-- 先引入 Vue --> <script src="vue.js"></script> <!-- 引入组件库 --> <script src="main.js"></script> </body> </html><!-- 引入样式 -->

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- 引入样式 -->
  <link rel="stylesheet" href="main.css">
    <link rel="stylesheet" href="mystique.css">
</head>
<body>
    <div id="app">
      <h1 class="title-box">flexbox对齐就是这么简单</h1>
    </div>
    <div id="type-select">
      <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
          {{ option.text }}
        </option>
      </select>
      <!-- <span>Selected: {{ selected }}</span> -->
      <div class="resule-preview">
        <div v-bind:class="selected" class="cols">
          <div class="col col-3">
              <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
        </div>
      </div>
      <div class="resule-code">
        <pre class="code-display">
            <code class="code-lang">
               {{ cssMsg }}
            </code>
        </pre>
      </div>
    </div>
    <!-- 先引入 Vue -->
    <script src="vue.js"></script>
    <!-- 引入组件库 -->
    <script src="main.js"></script>
</body>
</html><!-- 引入样式 -->

做任何事情都要有个工具,制作chrome插件需要的工具很少。

manifest.json文件

文件中需要注意一下的mainfest.json这个文件,这个json文件的作用是提供插件的各种信息,例如插件能够做的事情,以及插件的文件配置等等信息。下面是一个清单文件的示例,

{
  "manifest_version": 2,

  "name": "One-click Kittens",
  "description": "This extension demonstrates a browser action with kittens.",
  "version": "1.0",

  "permissions": [
    "https://secure.flickr.com/"
  ],
  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  }
}

 

第一行声明我们使用清单文件格式的版本 2,必须包含(版本 1 是旧的,已弃用,不建议使用)。

接下来的部分定义扩展程序的名称、描述与版本。这些都会在 Chrome 浏览器中使用,向用户显示已安装的扩展程序,同时在 Chrome 网上应用店中向潜在的新用户显示您的扩展程序。名称应该简练,描述不要比一句话左右还长(后面将会有更多的空间用于更详细的描述)。

最后一部分首先请求权限,用于访问  上的数据,并声明该扩展程序实现了一个浏览器按钮,同时在这一过程中为它指定一个默认图标与弹出窗口。

定义浏览器按钮时指向了两个资源文件:icon.png 与 popup.html。这两个资源都必须在扩展程序包中存在,图片是扩展的显示,html是扩展具体运行的基础文件。

具体详细的开发教程可以看看官方的这个文档,非常简明的入门教程。

Vue实例

  • Vue 构造器
  • Vue.extend({})可以扩展Vue构造器
  • 每个Vue实例都会代理其data对象里面的所有属性,即实例.属性===data.属性
  • 实例引用内部属性和方法需要加前缀$
vm.$el===document.getElementById('exzample');
  • 实例声明周期与钩子
    created是实例被创建后调用,还有mounted、updated、destroyed,钩子的this指向调用它的实例

CSS就不列出来了,可以在源代码中查看。

下面来使用vuejs来实现插件的功能。

  • 记事本,用来编写代码
  • Chrome浏览器,这个不能少吧。Windows下,所有版本的Chrome都可以制作插件。Linux下需要下载Beta版本,Mac下载dev版本。

功能实现-Vuejs实践

整个插件的核心交互功能非常简单,如文章开头的动图所示,用户选择对齐方式,代码区域显示对应的代码。这种简单数据交互使用vuejs再适合不过了。

这里需要注意的一点是,chrome 扩展的运行环境有一些特殊要求,称为 Content Security Policy (CSP),使得通常的 vue 不能被正常使用。如果用的是 vue 1.x,那么可以下载 csp 版本,在 这里。如果是 2.x 版本,请参考官网文档的这一段。

核心代码如下所示。

HTML:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- 引入样式 -->
  <link rel="stylesheet" href="main.css">
    <link rel="stylesheet" href="mystique.css">
</head>
<body>
    <div id="app">
      <h1 class="title-box">flexbox对齐就是这么简单</h1>
    </div>
    <div id="type-select">
      <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
          {{ option.text }}
        </option>
      </select>
      <!-- Selected: {{ selected }} -->
      <div class="resule-preview">
        <div v-bind:class="selected" class="cols">
          <div class="col col-3">
              <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
        </div>
      </div>
      <div class="resule-code">
        <pre class="code-display">
            <code class="code-lang">
               {{ cssMsg }}
            </code>
        </pre>
      </div>
    </div>
    <!-- 先引入 Vue -->
    <script src="vue.js"></script>
    <!-- 引入组件库 -->
    <script src="main.js"></script>
</body>
</html>

 

CSS就不列出来了,可以在源代码中查看。

下面来使用vuejs来实现插件的功能。

模板语法

  • 文本:双大括号的文本插值(默认是响应式的,对应属性的值变化,此处内容会更新)
Message:{{ msg}}

也可以通过v-once执行一次性插值,不再更新内容,但是这会影响这个节点的所有数据绑定

This will never change:{{message}}
  • 纯HTML:用v-html可以输出真正的html
<div id="app-8" v-html='rawHtml'>   </div>
var app8=new Vue({
        el:'#app-8',
        data:{
            rawHtml:'<li>纯html</li>'
        }
    })
//输出:● 纯html

但是要注意只对可信内容使用html插值,不然容易导致xss攻击

  • 属性:html属性不能用双大括号语法,需要用v-bind。
<div id="app-2">
    悬停几秒看信息
</div>
  • 所有的数据绑定都可以用js表达式
{{ number   1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-'   id"></div>

然而,语句和流控制是不行滴,三元表达式是可以的

{{var a = 1 }}
{{if(ok){return message}}}
  • 指令:带有v-前缀的特殊属性,它的值预期是单一js表达式,指定的职责是,当表达式的值改变时相应的将某些行为应用到DOM上。
  • 部分指令接收一个参数,在指令后以冒号指明,比如v-bind:href="url"
    还比如v-on:click="方法名"绑定一个事件
  • 修饰符,以半角句号指明的特殊后缀,指出一个指令应该以特殊方式绑定,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
<form v-on:submit.prevent="onSubmit"></form>
  • 过滤器:大括号语法和v-bind表达式,用于文本转换
<div id="app-9">{{message|format}}</div>
var app9=new Vue({
        el:'#app-9',
        data:{
            message:'hello,Filters!'
        },
        filters:{
            format:function(value){
                value=value.toLowerCase()
            return value.charAt(0).toUpperCase() value.slice(1)
            }
        }
    })

过滤器可以串联,可以接受参数

  • 缩写:v-bind缩写为空,后接冒号
<a v-bind:href="url"></a>
<a :href="url"></a>

v-on缩写为@,并省略了后面的冒号

<a v-on:click="doSomething"></a>
<a @click="doSomething></a>

功能实现

使用 v-for 指令根据一组数组的选项列表进行渲染。 v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。

而下拉框(select)列表的渲染,就可以使用vue中的v-for方法来渲染下拉列表选项,下拉选项数据写在js中的data对象中的options中。用v-bind方法来绑定option的value值,代码如下所示:

XHTML

<select v-model="selected"> <option v-for="option in options" v-bind:value="option.value"> {{ option.text }} </option> </select>

1
2
3
4
5
<select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
          {{ option.text }}
        </option>
</select>

在vuejs中可以用 v-model 指令在表单控件元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。这里在select中使用v-model方法来监听选中的值。

为了能预览不同对齐的效果,先在CSS中写好和下拉框中值相同的对应的类名样式,这样当用户选中不同的值的时候能显示不同的效果。这里我们使用v-bind方法来实现这个功能,它主要用于属性绑定,我们可以给v-bind:class一个对象,以动态地切换class。

XHTML

<div v-bind:class="selected" class="cols"> <div class="col col-3"> <p>对齐</p> </div> <div class="col col-3"> <p>对齐</p> </div> <div class="col col-3"> <p>对齐</p> </div> </div>

1
2
3
4
5
6
7
8
9
10
11
<div v-bind:class="selected" class="cols">
          <div class="col col-3">
              <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
</div>

下拉框这块功能就这样,简简单单几行代码就实现了。想想要是用jquery或者是原生的js来实现同样的功能,不仅代码量要大而且写起来也没有vuejs这么舒服。

接下来是代码同步功能,即在代码区域显示对应flex对齐的CSS代码。

开始之前先讲讲vuejs中的computed属性方法,可计算属性 (computed properties) 就是不存在于原始数据中,而是在运行时实时计算出来的属性。

对应到我们这个实例,就是当用户选择flexbox不同的对齐方式的时候,及时同步对应的CSS代码到代码预览区域。简单起见,直接把几个不同的代码写到js中:

data: { selected: 'cols-center', cssText:{ 'cols-center' : 'nr-webkit-justify-content: center;nr-ms-flex-pack: center;nrjustify-content: center;', 'cols-space-between' : 'nr-webkit-justify-content: space-between;nr-ms-flex-pack: justify;nrjustify-content: space-between;', 'cols-space-around' : 'nr-webkit-justify-content: space-around;nr-ms-flex-pack: distribute;nrjustify-content: space-around;' }, options: [ { text: '居中对齐', value: 'cols-center'}, { text: '两端对齐', value: 'cols-space-between'}, { text: '间隔相等', value: 'cols-space-around'} ] },

1
2
3
4
5
6
7
8
9
10
11
12
13
data: {
    selected: 'cols-center',
    cssText:{
     'cols-center' : 'nr-webkit-justify-content: center;nr-ms-flex-pack: center;nrjustify-content: center;',
     'cols-space-between' : 'nr-webkit-justify-content: space-between;nr-ms-flex-pack: justify;nrjustify-content: space-between;',
     'cols-space-around' : 'nr-webkit-justify-content: space-around;nr-ms-flex-pack: distribute;nrjustify-content: space-around;'
    },
    options: [
      { text: '居中对齐', value: 'cols-center'},
      { text: '两端对齐', value: 'cols-space-between'},
      { text: '间隔相等', value: 'cols-space-around'}
]
    },

根据不同的名字对应不同的CSS代码。然后使用computed方法来根据用户选取的值实时取出对应的CSS代码:

computed:{ cssMsg:function(){ console.log(this) return this.cssText[this.selected]; } }

1
2
3
4
5
6
computed:{
     cssMsg:function(){
     console.log(this)
     return this.cssText[this.selected];
     }
    }

完整代码如下:

var typeSelect = new Vue({ el: 'body', data: { selected: 'cols-center', cssText:{ 'cols-center' : 'nr-webkit-justify-content: center;nr-ms-flex-pack: center;nrjustify-content: center;', 'cols-space-between' : 'nr-webkit-justify-content: space-between;nr-ms-flex-pack: justify;nrjustify-content: space-between;', 'cols-space-around' : 'nr-webkit-justify-content: space-around;nr-ms-flex-pack: distribute;nrjustify-content: space-around;' }, options: [ { text: '居中对齐', value: 'cols-center'}, { text: '两端对齐', value: 'cols-space-between'}, { text: '间隔相等', value: 'cols-space-around'} ] }, computed:{ cssMsg:function(){ console.log(this) return this.cssText[this.selected]; } } })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var typeSelect = new Vue({
   el: 'body',
   data: {
    selected: 'cols-center',
    cssText:{
     'cols-center' : 'nr-webkit-justify-content: center;nr-ms-flex-pack: center;nrjustify-content: center;',
     'cols-space-between' : 'nr-webkit-justify-content: space-between;nr-ms-flex-pack: justify;nrjustify-content: space-between;',
     'cols-space-around' : 'nr-webkit-justify-content: space-around;nr-ms-flex-pack: distribute;nrjustify-content: space-around;'
    },
    options: [
      { text: '居中对齐', value: 'cols-center'},
      { text: '两端对齐', value: 'cols-space-between'},
      { text: '间隔相等', value: 'cols-space-around'}
]
    },
    computed:{
     cssMsg:function(){
     console.log(this)
     return this.cssText[this.selected];
     }
    }
})

最后在html中绑定通过computed方法得到数据也就是CSS:

XHTML

<div class="resule-code"> <pre class="code-display"> <code class="code-lang"> {{ cssMsg }} </code> </pre> </div>

1
2
3
4
5
6
7
<div class="resule-code">
        <pre class="code-display">
            <code class="code-lang">
               {{ cssMsg }}  
            </code>
        </pre>
      </div>

插件代码下载

开发好之后,可以直接在chrome中运行来调试。打开扩展面板,勾选开发者模式,然后加载刚开发扩展所在的目录就可以直接运行了。

澳门新浦京娱乐场网站 6

一个简单的插件就完成了,通过这一个简单的chrome插件就可以体验到vuejs在web开发中简单、优雅的魅力,还有什么理由不用起来呢。

1 赞 5 收藏 评论

澳门新浦京娱乐场网站 7

开始制作第一个插件

功能实现

使用 v-for 指令根据一组数组的选项列表进行渲染。 v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。

而下拉框(select)列表的渲染,就可以使用vue中的v-for方法来渲染下拉列表选项,下拉选项数据写在js中的data对象中的options中。用v-bind方法来绑定option的value值,代码如下所示:

<select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">
          {{ option.text }}
        </option>
</select>

 

在vuejs中可以用 v-model 指令在表单控件元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。这里在select中使用v-model方法来监听选中的值。

为了能预览不同对齐的效果,先在CSS中写好和下拉框中值相同的对应的类名样式,这样当用户选中不同的值的时候能显示不同的效果。

<div v-bind:class="selected" class="cols">
          <div class="col col-3">
              <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
          <div class="col col-3">
            <p>对齐</p>
          </div>
</div>

 

下拉框这块功能就这样,简简单单几行代码就实现了。想想要是用jquery或者是原生的js来实现同样的功能,不仅代码量要大而且写起来也没有vuejs这么舒服。

接下来是代码同步功能,即在代码区域显示对应flex对齐的CSS代码。

开始之前先讲讲vuejs中的computed属性方法,可计算属性 (computed properties) 就是不存在于原始数据中,而是在运行时实时计算出来的属性。

对应到我们这个实例,就是当用户选择flexbox不同的对齐方式的时候,及时同步对应的CSS代码到代码预览区域。简单起见,直接把几个不同的代码写到js中:

data: {
        selected: 'cols-center',
        cssText:{
            'cols-center' : 'nr-webkit-justify-content: center;nr-ms-flex-pack: center;nrjustify-content: center;',
            'cols-space-between' : 'nr-webkit-justify-content: space-between;nr-ms-flex-pack: justify;nrjustify-content: space-between;',
            'cols-space-around' : 'nr-webkit-justify-content: space-around;nr-ms-flex-pack: distribute;nrjustify-content: space-around;'
        },
        options: [
          { text: '居中对齐', value: 'cols-center'},
          { text: '两端对齐', value: 'cols-space-between'},
          { text: '间隔相等', value: 'cols-space-around'}
        ]
    },

 

根据不同的名字对应不同的CSS代码。然后使用computed方法来根据用户选取的值实时取出对应的CSS代码:

computed:{
        cssMsg:function(){
            console.log(this)
            return this.cssText[this.selected];
        }
    }

 

完整代码如下:

var typeSelect = new Vue({
      el: 'body',
      data: {
        selected: 'cols-center',
        cssText:{
            'cols-center' : 'nr-webkit-justify-content: center;nr-ms-flex-pack: center;nrjustify-content: center;',
            'cols-space-between' : 'nr-webkit-justify-content: space-between;nr-ms-flex-pack: justify;nrjustify-content: space-between;',
            'cols-space-around' : 'nr-webkit-justify-content: space-around;nr-ms-flex-pack: distribute;nrjustify-content: space-around;'
        },
        options: [
          { text: '居中对齐', value: 'cols-center'},
          { text: '两端对齐', value: 'cols-space-between'},
          { text: '间隔相等', value: 'cols-space-around'}
        ]
    },
    computed:{
        cssMsg:function(){
            console.log(this)
            return this.cssText[this.selected];
        }
    }
})

 

最后在html中绑定通过computed方法得到数据也就是CSS:

<div class="resule-code">
        <pre class="code-display">
            <code class="code-lang">
               {{ cssMsg }}  
            </code>
        </pre>
      </div>

开发好之后,可以直接在chrome中运行来调试。打开扩展面板,勾选开发者模式,然后加载刚开发扩展所在的目录就可以直接运行了。

澳门新浦京娱乐场网站 8

完整的源代码已上传在附件,可以下下来直接运行。

一个简单的插件就完成了,通过这一个简单的chrome插件就可以体验到vuejs在web开发中简单、优雅的魅力,还有什么理由不用起来呢。

 

【有奖讨论】程序员,怎么应对三十岁? 点击查看详情

欢迎加入QQ群:374933367,与腾云阁原创作者们一起交流,更有机会参与技术大咖的在线分享!

计算属性

  • 声明一个计算属性,其后的函数,将会用作调用属性时的getter
    computed:{内容}——computed是关键字
  • computed计算属性 vs methods函数调用:
    计算属性基于依赖进行缓存,只要message不变,多次访问都是返回之前的结果,而函数调用是只要发生重新渲染就会执行该函数——例如,在计算缓存里返回Date.now(),不再更新,因为Date.now()不是响应式依赖。
  • computed vs watch
    watch用来观测,但是有些情况用computed更方便。
  • computed不止有getter,还有setter,需要显式设置:
var app11=new Vue({
        el:'#app-11',
        data:{
            firstName:'Foo',
            lastName:'Bar'
        },
        computed:{
            fullName:{
                get:function(){
                    return this.firstName ' ' this.lastName
                },
                set:function(newValue){
                    var names = newValue.split(' ')
                    this.firstName=names[0]
                    this.lastName=names[names.length-1]
                }   
            }

        }
    })
  • 在计算机中创建一个目录来存放插件代码。
  • 在目录里面创建文件manifest.json(注意后缀名是.json),用记事本打开,写入如下代码
    1. {
    2.   "name": "第一个Chrome插件",
    3.   "version": "1.0",
    4.   "description": "我的第一个Chrome插件,还不错吧",
    5.   "browser_action": {
    6.     "default_icon": "icon.gif"
    7.   }
    8. }

相关阅读

Vue.js前后端同构方案之准备篇——代码优化
Vue组件开发实践之scopedSlot的传递
Vue.js 实战总结


此文已由作者授权腾讯云技术社区发布,转载请注明文章出处
原文链接:
获取更多腾讯海量技术实践干货,欢迎大家前往腾讯云技术社区

 

 

 

class和style绑定

对class的增强绑定:

  • 传入一个对象:
<div id="app-01" v-bind:class="{active:isActive}"></div>
var app01=new Vue({
        el:'#app-01',
        data:{
            isActive:true
        }
    })
//div class="active"
  • v-bind:class可与普通class属性共存,并可以传入更多属性来动态切换:
<div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
  • 还可以绑定为一个对象:
<div id="app-02" v-bind:class='classObject'></div>
var app02=new Vue({
        el:'#app-02',
        data:{
            classObject:{
            active:true,
            'text-danger':false
            }
        }

    })
  • 还可以结合计算属性,加入函数
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal',
    }
  }
}

总结:只要冒号后的数据形式为‘名称:布尔值’就可以

  • 可以传入数组
    数组语法涉及逻辑判断很少,可以理解为对象语法的组合版。
<div v-bind:class="[activeClass, errorClass]">
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}
<div v-bind:class="[{ active: isActive }, errorClass]">
  • 可以用在组件上
<my-component v-bind:class="{ active: isActive }"></my-component>

和内置元素的使用差不多

对style样式增强绑定:
由于默认格式里就包括一对引号,要注意单双引号的区分,不然会出错

<div id='app-03' v-bind:style='{color:activeColor,fontSize:fontSize   "px"}'>
<p>1111</p>
</div>
var app03=new Vue({
        el:'#app-03',
        data:{
            activeColor:'red',
            fontSize:30
        }
    })
  • 把下面两张图片保存到文件夹中,分别取名icon.gif和smile.gif
    图片一: 澳门新浦京娱乐场网站 9     图片二: 澳门新浦京娱乐场网站 10
  • 安装这个插件:
    a.点击右上角扳手,选择扩展程序,打开扩展中心。
    b.点击右上角的“开发人员模式”,使得前面的“ ”变成“-”,打开相应的菜单。如果一开始就是“-”,那么不用点击。
    c.点击“载入正在开发的扩展程序按钮”,导入刚才创建的文件夹。

条件渲染

  • v-if/v-else
<div id="app-04">
    <p v-if="ok">Yes</p>
    <p v-else>No</p>
</div>
var app04=new Vue({
        el:'#app-04',
        data:{
            ok:false
        }
    })
  • template可以作为一个包装元素,包裹多个需要同一个v-if的元素
<div id="app-04">
    <template v-if="ok">
    <h1>Title</h1>
    <p>Para</p>
    </template>
    <p v-else>No</p>
</div>
  • 还有一个v-else-if作为链式使用判断
  • template包装起来,用v-if和v-else判断的组件,默认是复用的,不想复用,给各自添加一个不同名称的key就可以了。
    复用的如下:
<div id="app-05">
<template v-if="loginType==='username'">
    <label for="">Username</label>
    <input placeholder="Enter your username">
</template> 
<template v-else>
    <label for="">Email</label>
    <input placeholder="Enter your email address">
</template>
<button v-on:click="toggle">Toggle login type</button>
</div>
var app05=new Vue({
        el:'#app-05',
        data:{
            loginType:'username'
        },
        methods:{
            toggle:function(){
                this.loginType==='username'?this.loginType='email':this.loginType='username'
            }
        }

    })

不复用的如下:

<div id="app-05">
<template v-if="loginType==='username'">
    <label>Username</label>
    <input placeholder="Enter your username" key="username">
</template> 
<template v-else>
    <label>Email</label>
    <input placeholder="Enter your email address" key="email">
</template>
<button v-on:click="toggle">Toggle login type</button>
</div>
  • v-show始终都会渲染,简单的切换display属性,不支持template语法,也不支持v-else
<h1 v-show='ok'>222</h1>

v-show vs v-if
v-show适合频繁切换,v-if适合条件不太改变的情况

如果一切顺利,你的Chrome地址栏将会有个新图标,你的第一个插件诞生了。

列表渲染

  • 基本用法:v-for = "item in items",items是源数组,item是数组元素迭代的别名
<ul id="app-06">
    <li v-for="item in items">{{item.message}}</li>
</ul>
var app06=new Vue({
        el:'#app-06',
        data:{
            items:[
            {message:'Foo'},
            {message:'Bar'}
            ]
        }
    })
  • v-for支持索引参数,但是是从0开始滴(改为{{index 1}}就是从1开始了),并且拥有对父作用域的完全访问权限,可以引用其他属性,比如例子中的parentMessage
<ul id="app-06">
    <li v-for="(item,index) in items">{{parentMessage}}-{{index}}-{{item.message}}</li>
</ul>
  • 还可以用of替代in作为分隔符,更接近js迭代器
  • 支持template组合语句单元
<ul id="app-07">
    <template v-for="(item,index) in items">
        组合列表{{index 1}}
        <li>{{item.message}}</li>       
    </template>
</ul>
  • 对象迭代
    v-for = "value in object"——object是一个拥有多个属性的对象,不再是数组。
    不同于数组迭代,对象迭代是三个参数,分别为迭代内容,迭代键值和参数:(item,key ,index)顺序固定
<ul id="app-08">
    <li v-for="(item,key,index) in object">
        {{item}}-{{key}}-{{index}}
    </li>
</ul>
  • v-for也可做简单的数字循环:
<ul id='app-09'>
  <li v-for="n in 10">{{n}}</li>
</ul>

但是同样需要建立Vue对象,

var app09=new Vue({
        el:'#app-09'
    })
  • ‘就地复用’的选择:与v-if相同,添加唯一key属性值可以不复用,v-for中最好绑定一个唯一id
<ul id="app-10" >
<li v-for="(item,index) in items"  :key='item.id=index 3'>{{item.message}}-{{index}}-{{item.id}}</li>
</ul>

这里我绑了元素的index在id上

  • 包含一组观察数组的变异方法:
  • push()——数组末端添加新项(返回新长度)
  • pop()——删除数组最后一项(返回元素值)
  • shift()——删除数组第一项(返回元素值)
  • unshift()——数组头部添加新项(返回新长度)
  • splice()——添加或删除项目
  • sort()
  • reverse()
  • 包含几个非变异数组方法(变异是指改变原数组):
  • filter()
  • concat()
  • slice()
  • 数组操作方法的局限:
  • 不能通过索引值直接设置一个项:
vm.items[indexOfItem] = newValue
  • 但是可以用set方法设置:
Vue.set(example1.items,indexOfItem,newValue)
  • 或者用万能的splice:
example1.items.splice(indexOfItem,1,newValue)

注意这里的第二个参数为"1",表示原地替换原元素

  • 不能直接修改数组长度:
vm.items.length = newLength

但是依旧可以用万能的splice:

example1.items.splice(newLength)
第二个参数为删除个数,不填第二个参数时表示删除到末尾

此处翻阅了犀牛书和高程,高程中没提到splice()省略第二个参数的情况,犀牛书提到了,省略第二个参数,从起始点到结尾的所有元素都将被删除。查了ecma-262的文档,原文是:

5  If the number of actual arguments is 0, then
     a. Let insertCount be 0.
     b. Let actualDeleteCount be 0.
6  Else if the number of actual arguments is 1, then 
     a. Let insertCount be 0. 
     b. Let actualDeleteCount be len ‑ actualStart.
  • 显示过滤、排序结果
  • 使用计算属性computed
<ul id="app-11">
    <li v-for="n in evenNumbers">{{n}}</li>
</ul>
var app11=new Vue({
        el:'#app-11',
        data:{
            numbers:[1,2,3,4,5]
        },
        computed:{
            evenNumbers:function(){
                return this.numbers.filter(function(number){
                    return number%2 === 0
                })
            }
        }
    })
  • 使用方法,methods——区别很小,引用时需要传入参数
<ul id="app-11">
    <li v-for="n in evenNumbers(numbers)">{{n}}</li>
</ul>
var app11=new Vue({
        el:'#app-11',
        data:{
            numbers:[1,2,3,4,5]
        },
        methods:{
            evenNumbers:function(){
                return this.numbers.filter(function(number){
                    return number%2 === 0
                })
            }
        }
    })
给第一个插件增加新功能

事件处理器

  • 最简单的把处理代码写在v-on:click里:
<div id="app-12">
    <button v-on:click="counter =1">增加1</button>
    <p>这个按钮被点击了{{counter}}次</p>
</div>
var app12=new Vue({
        el:"#app-12",
        data:{
            counter:0
        }
    })
  • 命名一个方法,把方法名写在v-on:click后
  • 可以传参数
<div id="app-13">
    <button v-on:click="say('hi')">1</button>
    <button v-on:click="say('what')">2</button>
</div>
var app13=new Vue({
        el:'#app-13',
        data:{
            message:'new event!'
        },
        methods:{
            say:function(m){
                alert(m)
            }
        }
    })
  • 可以访问原生DOM事件,用特殊变量$event传入
<div id="app-14">
    <button v-on:click="mod('event is modified',$event)">submit</button>
</div>
var app14=new Vue({
        el:'#app-14',
        methods:{
            mod:function(message,e){
                if(e)e.preventDefault()
                alert(message)
            }
        }
    })

代码中点击button会触发一个click事件,把event作为参数传入,就可以对这个事件进行操作

  • 事件修饰符
    从方法中拆分出了事件处理过程给指令,表达更直观。
  • .stop——阻止冒泡
  • .prevent——?
  • .capture——捕获事件
  • .self——该元素本身(而不是子元素)时触发回调
  • .once——点击事件只会触发一次
  • 按键修饰符:用于监听键盘事件
<input type="text" id="app-1" v-on:keyup.13="submit()">
var app1=new Vue({
   el:'#app-1',
   methods:{
       submit:function(){
           alert('success')
       }
   }
})

keyup.13是"enter"
还有别名:

<input type="text" v-on:keyup.13="submit">
<input type="text" v-on:keyup.enter="submit">
<input type="text" @keyup.enter="submit">
  • .enter
  • .tab
  • .delete
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
  • .ctrl
  • .alt
  • .shift
  • .meta
  • 还可以自定义别名:
Vue.config.keyCodes.f2=113

你现在虽然做了第一个插件,但实际上他并没有实现任何功能,我们点击图标,没有任何反应。下面我们就给他增加点功能。

表单控件绑定

v-model本质上是语法糖,监听输入事件以更新数据

  • 基础用法:
<div id="app-2">
    <input type="text" v-model="message" placeholder="'edit me">
    <p>Message is:{{message}}</p>   
</div>
var app2=new Vue({
    el:'#app-2',
    data:{
        message:''
    }   
})

多行文本同理

  • 单选框很方便
<div id="app-3">
    <input type="checkbox" id="chechbox" v-model="checked">
    <label for="checkbox">{{checked}}</label>
</div>
var app3=new Vue({
    el:'#app-3',
    data:{
        checked:false
    }
})

这里,checked预设值如果设为空,则开始时label没有内容,如果设为true,则选框会默认选上,所以最好只设为false

  • 复选框可共用v-model
<div id="app-4">
    <input type="checkbox" value="Jack" v-model="checkedNames" id="jack">
    <label for="jack">jack</label>
    <input type="checkbox" value="John" v-model="checkedNames" id="john">
    <label for="john">john</label>
    <input type="checkbox" value="Mike" v-model="checkedNames" id="mike" >
    <label for="mike">mike</label>
    <br>
    checked names: {{ checkedNames }}
</div>
var app4=new Vue({
    el:'#app-4',
    data:{
        checkedNames:[]
    }
})
  • 单选按钮
  • 单选列表
<div id="app-6">
    <select name="" id="" v-model="selected">
        <option>A</option>
        <option>B</option>
        <option>C</option>
    </select>
    selected:{{selected}}
</div>
var app06=new Vue({
    el:'#app-6',
    data:{
        selected:""
    }
})

此处遇到一小问题,建立option时,emmet的补全加了属性value='',如果不改动的话,默认option的值是为空的,选中无效,需要删除这个属性或者显式填值

  • 多选列表,在select处添加属性,multiple="multiple"就可以了。多选时按住ctrl或command键才可以多选
  • 动态选项值
<div id="app-6">
    <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">{{option.text}}</option>
    </select>
    selected:{{selected}}
</div>
var app06=new Vue({
    el:'#app-6',
    data:{
        selected:'A',
        options:[
        {text:'One',value:'A'},
        {text:'Two',value:'B'},
        {text:'Tree',value:'C'}
        ]
    }
})

此例子将选项内容与选项值区分成两组数据,而selected显示的是value的内容,同上一个小问题相同,option不显式设置值时,option标签内容即为值,显式设置后,value值会覆盖标签内容被发送。

  • 动态value值
    v-model绑定的value通常是静态字符串,通过v-bind可以动态绑定变量到value上,语法是v-bind:true-value/v-bind:false-value
<div id="app-7">
    <input id="bindvalue" type="checkbox" v-model="toggle" v-bind:true-value="a" v-bind:false-value='b'>
    <label for="bindvalue">{{toggle}}</label>
</div>
var app07=new Vue({
    el:'#app-7',
    data:{
        toggle:'false',
            a:'true',
            b:'false'       
    }
})

例子中绑定了true-value到a变量,false-value到b变量
单选框同理:

<input type="radio" v-model='pick' v-bind:value="a">
  • 修饰符
  • .lazy——默认情况下v-model载input事件中同步输入框的值与数据,添加一个.lazy修饰符后,转变为在change事件中同步,问题是,change事件是神马?存疑
<input v-model.lazy="msg">
  • .number自动将输入值转为Number类型
<input v-model.number='age' type='number'>

这个例子玄机很多:
输入字母e/E情况特殊,会被理解为指数标志,不同设定效果不同:

  1. 只设置type为number:字母输入无效;e后为有效数字时会正常显示,比如:

    输入:123abc456, 框内显示为:123456,值显示为123456 、、、 输入:123e12, 框内显示为:123e12 值显示为:123e12

但是超过一定数值会显示为空:

(很大很大一个数字)显示为:
123e1234 值显示为:

然而负指数会正确显示:

123e-1234 值显示为 123e-1234

   2. 只设置v-model为number时:

输入:123abc456,
框内显示为123abc456,失去焦点时更新为123,
值显示为123
、、、
输入:abc123,
框内显示为abc123,失去焦点没变化,
值显示为abc123,说明判定失效啦
、、、
123e12 值显示为:123000000000000
——同时输入框内会被更新成123000000000000

指数e超过一定数值会显示为Infinity

123e1234值显示为:Infinity
——同时输入框内会被更新成Infinity

在一个范围内的负指数会被格式化后显示,
超过一定值的负指数会被显示为0:

123e-123  值显示为:1.23e-121
123e-1234 值显示为:0
——同时输入框内会被更新

   3. 设置type为number并且v-model为number时:

输入123abc456,
框内显示为:123456,值显示为123456
、、、
输入abc123,
框内显示为:123,值显示为123
、、、
123e12 值显示为:123000000000000
——同时输入框内会被更新成123000000000000
指数大于20位会转化成指数形式

超过一定数值显示为空:

123e1234 值显示为:

在一个范围内的负指数会被格式化后显示,
超过一定值的负指数会被显示为0:

123e-123  值显示为:1.23e-121
123e-1234 值显示为:0
——同时输入框内会被更新

总结:控制数字输入的主要依赖type="number",v-model.number是将输入值转化为Number类型,但是表现不太稳定。

  • .trim自动过滤用户输入的首尾空格:
空空abc空空def空空  ——>  abc空空def
  • 编辑manifest.json这个文件,用下面的代码替换现有的代码,其实我们只是加了一行代码和一个逗号而已。

    1.    "name": "第一个Chrome插件", 
    2.    "version": "1.0", 
    3.    "description": "我的第一个Chrome插件,还不错吧", 
    4.    "browser_action": { 
    5.       "default_icon": "icon.gif", 
    6.       "popup": "popup.html" 
    7.    }
    8. }
  • 下面我们创建一个文本文件popup.html,用记事本打开,将下面的代码写进去

    1. <p>Hello,Chrome!</p>
    2. <p>我的名字叫ChromeChina!</p>
    3. <p><a href="" target="_blank">Chrome中文论坛欢迎你</a>
    4. <p><img src="smile.gif" /></p>

组件

  • 基础语法:
<div id="app-01">
    <my-component></my-component>
</div>
Vue.component('my-component',{
    template:'<div>A custom component!</div>'
})
var app01=new Vue({
    el:'#app-01'
})

要确保,先注册组件,再初始化实例,调换前后顺序会出错

  • 局部注册:把组件用components注册在实例中,注意components为复数形式,好处是限制了作用域
<div id="app-01">
    <my-component></my-component>
</div>
var app01=new Vue({
    el:'#app-01',
    components:{
        'my-component':{
            template:'<div>A custom component!</div>'
        }
    }
})

注意此处相当于先实例再在实例中注册组件,因此可以判断,注册组件行为不能落后于实例化,但是可以包含在实例的同时进行。

  • DOM模板解析——当把模板加载到一些已存在的元素上时,可能会受到HTML的一些限制,因为像一些ul/ol/table/select限制了能被它包裹的元素,而一些如option的元素只能出现在某些元素内部,因此,有时自定义组件会失效而出错:
<table>
  <my-row>...</my-row>
</table>

需要使用特殊的is属性:

<table id="app-01">
    <tr is="my-component"></tr>
</table>

这相当于把组件伪装成一个tr ,查看浏览器文档结构解析为:

<table id="app-01">
        <tbody>
        <div>A custom component</div>——(组件内容)
        </tbody>
</table>

tbody问题
此处出现的tbody是html解析自动补全的,tbody功能为,划分表格结构,默认情况下是一个tbody,也可手动建立多个并行的tbody,这影响表格分别渲染及切分(很长的表格换页的时候断在哪里就是切分)

  • 限制不适用情况没看懂(存疑):
    • <script type="text/x-template">----这个解决了,后面有解释
    • JavaScript内联模版字符串
    • .vue 组件
  • 组件关联构造器的data必须是函数,否则会报错,深层次的原因是,每个模板都会引用data,如果data是定值,则每个模板引用的都是同一个,如果data是函数,则返回不同,每个模板才会区别开
<div id="app-02">
    <simple-counter></simple-counter>
    <simple-counter></simple-counter>
    <simple-counter></simple-counter>
</div>
如果是:
var data={counter:0}
var app02=new Vue({
    el:'#app-02',
    components:{
        'simple-counter':{
            template:'<button v-on:click="counter  =1">{{counter}}</button>',
            data:function(){
                    return data
                }
        }

    }
则修改一个模板,其他模板数字也被修改,因为data的返回值是data自身,而所有模板都会引用data,都有修改权。
改一下:
var app02=new Vue({
    el:'#app-02',
    components:{
        'simple-counter':{
            template:'<button v-on:click="counter  =1">{{counter}}</button>',
            data:function(){
                    return {counter:0}
                }
        }

    }
每个模板可以有独立的值了,因为data作为一个函数返回的是不同的counter,不会被共用

模板内部的data与外部是冲突的

  • 回到Chrome的扩展中心,点击插件下的“重新载入 ”。
构成组件
<div id="app-03">
    <child message="hello"></child>
    <div>{{value}}</div>
</div>
var app03=new Vue({
    el:'#app-03',
    components:{
        'child':{
            template:'{{message}}',
            props:['message']
        }
    },
    data:{
        value:'yyy'
    }
})

此例子中,props请求的message通过组件元素传入,即特性传入,props与外部的data不冲突

  • 特性命名问题:
  • 矛盾点一:html的特性不区分大小写
  • 矛盾点二:Vue中除了模板命名,其他命名不允许出现小横杠 ‘-’
    于是当两个单词串联成一个名字时,怎么区分呢?
    vue貌似做了一个命名自动转换,在js文件内,命名为驼峰式,camerCase,进入html文件,自动转换成短横线隔开式,kebab-case,对应的是同一个变量
props:['myMessage']——js内
<child-11 my-message="hello"></child-11>——html内
  • 也可以用v-bind动态绑定prop到一个model
<div id="app-03">
    <input type="text" v-model='parentMsg'>
    <child-11 v-bind:my-message="parentMsg"></child-11>
</div>
var app03=new Vue({
    el:'#app-03',
    components:{
        'child-11':{
            template:'{{myMessage}}',
            props:['myMessage']
        }
    },
    data:{
        parentMsg:''
    }
})
  • 字面量语法vs动态语法:
<comp some-prop='1'></comp>
由于这是一个字面prop,传递了一个字符串'1',它的值是字符串‘1’而不是number
<comp v-bind:some-prop='1'></comp>
这样会把值当做一个javascript表达式计算,才是number
(存疑)
- prop是单向绑定:父组件属性变化时,将传到给子组件,但不会反过来。同时,每次父组件更新时,子组件的所有prop都会更新为最新值,这意味着,不应该在子组件内部改变prop。但是还要用怎么办呢?
  - 定义一个局部变量,用prop初始化
  - 定义一个计算属性,处理prop值
然而,js中,对象和数组是引用类型,指向同一个内存空间,如果prop是对象或者数组,在子组件内部改变也会影响父组件的状态。
- Prop验证

<div id="app-04">
<child prop-c="111"></child>

<child prop-c="333" prop-d="222"></child>
</div>
var app04=new Vue({
el:'#app-04',
components:{
'child':{
template:'<span>{{propC}}-{{propD}}-{{propE}}</span>',
props:{
propC:{
type:String,
required:true
},
propD:[String,Number],
propE:{
type:[String,Number],
default:100
}
}
}
}
})

有几种验证:
 - 指定类型验证:

单个的,propA:Number;
多个的,propB:[String,Number]

 - 是否必须存在的验证:

propC:{
type:String,
required:true
}

 - 带默认值的验证:

propD:{
type:Number,
default:100
}

默认值可以是函数:

propE:{
type:Object,
default:function(){
return { message:'hello'}

 - 还可以自定义验证函数:

propF:{
validator:function(value){
return value>0
}
这个验证失败时是控制台报错

- type的类型是以下原生构造器:
 - String
 - Number
 - Boolean
 - Function
 - Object
 - Array

#####自定义事件

<div id="app-05">
<p>{{total}}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
var app05=new Vue({
el:'#app-05',
components:{
'button-counter':{
template:'<button v-on:click="increment">{{counter}}</button>',
data:function(){
return{
counter:0
}
},
methods:{
increment:function(){
this.counter =1
this.$emit('increment')
}
}
}
},
data:{
total:0
},
methods:{
incrementTotal:function(){
this.total =1
}
}
})

这个例子中,创建了父元素和内部的子组件,子组件包含一个点击事件,v-on:click=‘increment’,点击后改变counter数值,同时为了上传事件,在函数increment内部自定义了一个事件,并在点击时触发此事件,$emit,也叫increment,并在子元素上绑定了这个事件,v-on:increment,然后对此在父元素上绑定了一个函数,incrementTotal,从而达到计算总数的效果。
我觉得这个名字区分一下比较好,子组件的方法不必和触发事件同一个名字,所以改一下:

<div id="app-05">
<p>{{total}}</p>
<button-counter v-on:user-defined="incrementTotal"></button-counter>
<button-counter v-on:user-defined="incrementTotal"></button-counter>
</div>
var app05=new Vue({
el:'#app-05',
components:{
'button-counter':{
template:'<button v-on:click="increment">{{counter}}</button>',
data:function(){
return{
counter:0
}
},
methods:{
increment:function(){
this.counter =1
this.$emit('user-defined')
}
}
}
},
data:{
total:0
},
methods:{
incrementTotal:function(){
this.total =1
}
}
})

- 给组件绑定原生事件
用.native修饰v-on

<new-component v-on:click.native="doSomeThing"></new-component>

- v-on与$on的不同:
v-on可以被父组件用来监听子组件的事件
(存疑):$on的用法
- v-model的使用:
 - ref与$.refs——注册引用信息和使用:
   - 在元素上注册:<p ref="a">hello</p>
使用注册:vm.$refs.a就是p这个DOM节点
   - 在组件上注册:<input ref="b">
使用注册:this.$refs.b就是指向了组件实例,this.$refs.b.value指向的是组件input.value
  - mounted ——生命周期钩子,当el被新创建的vm.$el替换,并挂载到实例上之后调用该钩子
 - NumberObject.toFixed(num)——把Number四舍五入为指定小数位数的数字

<script src=";
//载入一个验证插件
<div id="app-07">
<currency-input label="Price" v-model="price"></currency-input>
<currency-input label="Shipping" v-model="shipping"></currency-input>
<currency-input label="Handling" v-model="handling"></currency-input>
<currency-input label="Discount" v-model="discount"></currency-input>
//此处有一个合计
<p>Total: ${{total}}</p>
</div>
//组件部分
Vue.component('currency-input',{
template:'<div>
//如果有label,则显示,否则不显示
<label v-if="label">{{label}}</label>
$<input ref="input" v-bind:value="value" v-on:input="updateValue($event.target.value)"
v-on:focus="selectAll" v-on:blur="formatValue"></div>',
props:{
//对参数进行验证
value:{
type:Number,
default:0
},
label:{
type:String,
default:''
}
},
//生命周期钩子,当组件被挂载到实例时会触发
mounted:function(){
this.formatValue()
},
methods:{
updateValue:function(value){
var result=currencyValidator.parse(value,this.value)
if(result.warning){
this.$refs.input.value=result.value
}
this.$emit('input',result.value)
},
formatValue:function(){
this.$refs.input.value =currencyValidator.format(this.value)
},
//做setTimeout是由于safari此处有bug,不考虑兼容的话不必如此
selectAll:function(event){
setTimeout(function(){
event.target.select()
},0)
}
}
})

- 非父子组件间的通信(简单场景)——创建一个空的Vue实例作为连接:

var bus = new Vue()
//在A组件内
bus.$emit('id-selected', 1)
//在B组件内
bus.$on('id-selected', function (id) {
// ...
})

- slot 内容分发
 - 单个slot:子组件只有一个没有名字的slot时,父组件的整个内容片断会插入到slot所在的DOM位置
 - 具名slot:

子模板
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父模板
<app-layout>
<h1 slot="header">这里可能是一个页面标题</h1>
<p>主要内容的一个段落。</p>
<p>另一个主要段落。</p>
<p slot="footer">这里有一些联系信息</p>
</app-layout>
渲染结果
<div class="container">
<header>
<h1>这里可能是一个页面标题</h1>
</header>
<main>
<p>主要内容的一个段落。</p>
<p>另一个主要段落。</p>
</main>
<footer>
<p>这里有一些联系信息</p>
</footer>
</div>

 - 作用域插槽:子组件中把数据传递到插槽slot,父元素用一个template scope="props" 获取数据,然后就可以使用了

Vue.component('child',{
template:'<div><slot text="hello from child"></slot></div>'
})
var app03=new Vue({
el:'#app-03',
components:{
'parent-component':{
template:'<div>
<child>
<template scope="props">
<span>hello from parent</span>
<span>{{props.text}}</span>
</template>
</child></div>'
}
}
})
//显示为:
hello from parent hello from child

 - 更复杂的列表组件的例子:

//需要把mylist传递进parent-list
<parent-list id="app-04" v-bind:mylist="mylist"></parent-list>
Vue.component('child-list',{
props:['mylist'],
template:'<ul><slot name="item" v-for="item in mylist" v-bind:text="item.text"></slot></ul>'
})
var app04=new Vue({
el:'#app-04',
data:{
mylist:[
{text:'蔬菜'},
{text:'水果'},
{text:'肉'}
]
},
components:{
'parent-list':{
props:['mylist'],
//此处也需要把mylist传递进child-list
template:'<child-list v-bind:mylist="mylist">
<template slot="item" scope="props">
<li>{{props.text}}</li>
</template>
</child-list>'
}
}
})
显示为:

  • 蔬菜
  • 水果
- 渲染一个元组件为动态组件,根据is的值来决定渲染哪个组件

<component id="app-06" v-bind:is="currentView"></component>
var app06=new Vue({
el:'#app-06',
data:{
currentView:'posts'
},
components:{
'home':{
template:'<span>home</span>'
},
'posts':{
template:'<span>posts</span>'
},
'archive':{
template:'<span>archive</span>'
}
}
})
//输入为posts

- keep-alive保留状态或避免重新渲染

<keep-alive><component id="app-06" v-bind:is="currentView"></component></keep-alive>

- 可复用组件,三个接口:
 - props
 - events
 - slots

<my-component
:foo="baz"
:bar="qux"
@event-a="doThis"
@event-b="doThat"

<img slot="icon" scr="...">
<p slot="main-text">Hello!</p>
</my-component>

- 子组件索引:使用ref指定一个索引id

<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({el:'#parent'})
var child = parent.$refs.profile

当ref与v-for一起使用时,ref是一个数组或对象,包含相应的子组件,是非响应式的,应避免在模板或计算属性中使用
- 异步组件,接受一个工厂函数,可以动态解析组件的定义:
  • 可以搭配webpack的代码分割功能
  • 可以使用webpack2 es2015返回一个promise resolve函数
  • 组件命名约定,三种都可以:kebab-case,camelCase,TitleCase
    但是,html模板中,只能使用kebab-case
    字符串模板中,三种都可以
  • 递归组件,组件可以递归的调用自己
    (这里的雷是,不能在实例内部创建组件,因为递归时会查找不到子组件,需要定义全局组件)
<div id="app-07">
  <recursion-component :count="0"></recursion-component>
</div>
Vue.component('recursion-component',{
  props:['count'],
  name:'count',
  template:'<div>{{count}}<recursion-component :count="count 1" v-if="count<10"></recursion-component></div>'
})
var app07=new Vue({
  el:'#app-07'
})
//输出是:0 1 2 3 4 5 6 7 8 9 10
  • 组件间的循环引用——注册为全局组件时没有问题,但是使用webpack或者browerify用requiring/importing组件的话,会报错,需要用生命周期钩子中注册它的优先级:
beforeCreate:function(){
this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue')
}

此处(存疑,以后用了webpack再说)
文件目录树的例子:

<div id="app-08">
  <tree-folder :folder="folder"></tree-folder>
</div>
Vue.component('tree-folder',{
  template:'<p>{{folder.name}}<tree-folder-contents :children="folder.children"/></p>',
  props:['folder']
})
Vue.component('tree-folder-contents',{
  template:'<ul><li v-for="child in children">
  <tree-folder v-if="child.children" :folder="child"/>
  {{child.name}}
  </li></ul>',
  props:['children']
})
var app08=new Vue({
  el:'#app-08',
  data:{
    folder:{
      name:'总目录',
      children:[
        {name:"二层目录1"},
        {name:"二层目录2",
          children:[
          {name:"三层目录1"},
          {name:"三层目录1"}
          ]
        },
        {name:'二层目录3'}
      ]
    }
  }
})
//输出:
总目录
  - 二层目录1
  - 二层目录2
     - 三层目录1
     - 三层目录2
  - 二层目录3
  • 内联模板:一个组件有inline-template属性时,组件会把它的内容当做它的模板,而不是当做分发内容。应对于很简单的模板,因为有作用域问题
<parent-com>啦啦啦</parent-com>
\js部分
Vue.component('parent-com',{
  template:'<div><child-com>this is part of parents</child-com></div>'
})
\默认情况下,“啦啦啦”作为分发内容,不会显示,而是显示this is part of parents.
\如果改为:
<parent-com inline-template>啦啦啦</parent-com>
\则显示为“啦啦啦”,原设定的template被覆盖了
  • 另一种定义模板的方式:x-template
<div id="app-10">
  <hello-world></hello-world>
</div>
\先单独一个js,类型为type="text/x-template",并且需要有id
<script type="text/x-template" id="hello-world-template">
  <p>Hello hello hello</p>
</script>
\然后在另一个js里创建组件,只不过模板可以直接引用这个id:
Vue.component('hello-world', {
  template: '#hello-world-template'
})
\别忘了创建实例(掩面)
var app10=new Vue({
  el:'#app-10'
})
  • 对低开销的静态组件使用v-once只渲染一次,下次时直接应用缓存
Vue.component('terms-of-service', {
  template: '
    <div v-once>
      <h1>Terms of Service</h1>
      ... a lot of static content ...
    </div>
  '
})

基础部分结束

现在点击插件图标看看。我们的第一个插件算是制作成功了。

打包插件

我们想把自己制作的插件给其他人用,那么就需要将插件打包。

  • 回到Chrome的插件扩展中心,点击“打包扩展程序”按钮。
  • 选择刚才创建的文件夹,点击确定生成后缀为crx和cpm文件各一个。

把crx文件发送给自己的朋友,告诉他们你也会制作chrome插件吧。

你可以修改里面的文字图片,制作出极具个性的扩展来了。

要是在制作过程中有任何问题,欢迎到http://dev.chromechina.com来讨论交流。本文参考官方指南编写。

二、概述

这篇文章翻译自。

只要看完这篇文章,并且做过入门指南中的例子,你就可以真正开始开发属于自己的Chrome插件了。

基础知识

一个Chrome扩展是由HTML、CSS、JavaScript、图片等文件压缩而成。扩展实际上就是一个web页面,你可以用任何浏览器提供给web页面的接口,从XMLHttpRequest 到JSON ,再到HTML本地缓存都可以使用。

Chrome扩展能做什么呢?我们肯定使用过一些扩展,会发现有些扩展在Chrome地址栏右侧区域增加一个图标。还有些扩展能够和浏览器的一些元素(如书签、tab导航标签)交互。扩展还可以和web页面交互,甚至是从web服务器获取数据。更加详细的内容可以从Developer's Guide看到。

Chrome扩展的组成文件

每个扩展由下列文件组成:

  • 一个manifest文件(主文件,json格式)
  • 至少一个HTML文件(主题可以没有HTML文件)
  • JavaScript文件 (可选,非必须)
  • 任何其他你需要的文件(比如图片)

当你开发一个扩展的时候,需要把这些文件放在一个文件夹里,当你发布这个扩展的时候,这个文件夹下的所有文件将会打包成一个特殊后缀.crx的ZIP文件。

引用文件

你可以放置任何文件到你的扩展里面,但是怎么调用这些文件呢?一般来说,使用相对地址调用,类似HTML中调用文件。下面是个例子,在子文件夹images中有个图片myimage.png,我们可以这样调用它

  1. <img src="images/myimage.png">

复制代码

其中images/myimage.png表示这个文件。

也许你注意到当使用Google Chrome debugger查看这些文件的时候给,每个文件的地址是下面这种格式

  1. chrome-extension://<extensionID>/<pathToFile>

复制代码

这个地址中,<extensionID>是你制作的扩展的唯一标示符,也就是扩展的身份证编号。<pathToFile>是文件相对扩展顶级文件夹得位置。

manifest文件

主文件取名manifest.json,用来描述这个扩展,包括扩展名字、版本、调用的文件、可用域等信息。下面是个典型的manifest文件,这个扩展可以调用google.com的内容。

  1. {
  2.   "name": "My Extension",
  3.   "version": "2.1",
  4.   "description": "Gets information from Google.",
  5.   "icons": { "128": "icon_128.png" },
  6.   "background_page": "bg.html",
  7.   "permissions": ["", "],
  8.   "browser_action": {
  9.     "default_title": "",
  10.     "default_icon": "icon_19.png",
  11.     "popup": "popup.html"
  12.   }
  13. }

复制代码

扩展结构组成结构

绝大部分扩展有background文件,一个不可见的文件控制着整个扩展的运行。

澳门新浦京娱乐场网站 11

上面这个图片显示的浏览器至少安装了两个扩展:一个浏览器行为扩展(黄色的图标),页面行为扩展(蓝色的图标)。这个浏览器行为扩展的background文件是用一个HTML文件定义的(background.html),这个background文件中有JavaScript代码控制整个浏览器的活动。

HTML页面

background不是唯一存在的HTML文件,比如浏览器行为可能是弹出一个小窗口,这个小窗口的内容就可以调用一个HTML文件。Chrome扩展也能够用chrome.tabs.create() or window.open()这种函数来显示HTML文件。

扩展里面的HTML文件可以互相访问对方的DOM结构,可以引用其他文件中定义的函数。

下面的图展示了浏览器弹出一个窗口这个功能的结构(这正是我们最开始的例子)。这个弹出窗口的内容是一个HTML的web文件,这个弹出窗口不需要包含background文件中的代码,因为,popup.html和background是可以互相访问的。

澳门新浦京娱乐场网站 12

内容脚本(Content scripts)

如果你插件需要和网页交互,那么他就需要一个内容脚本(Content scripts),内容脚本常由JavaScript编写,会在网页载入完成后调用。完全可以把内容脚本看做是网页的一部分,而不是扩展的一部分。

内容脚本可以访问到当前浏览器浏览的页面,而且还可以改变网页的显示方式(油猴脚本就是内容脚本)。下面的图片中,内容脚本可以读取、更改网页的DOM。注意,他不能更改background.html中的内容。

澳门新浦京娱乐场网站 13

内容脚本也不是和父扩展完全隔离开来,他也可以和父级扩展交换信息。如下图中所示,内容脚本在发现一个RSS Feed地址后将会给background.html发送一个信息。或者background.html给内容脚本发送一个信息要求改变网页外观。

澳门新浦京娱乐场网站 14

不同页面间的交互

一个扩展中的文件常常需要交互。由于扩展的所有文件都由同一个进程执行,网页能够直接给其他页面发送命令。

可以使用类似chrome.extension methods such as getViews() and getBackgroundPage()这样的方法引用扩展中的方法。一旦页面中引用了另外的页面,第一个页面就可以调用其他页面的函数,甚至可以控制DOM。

结束语

好了,你已经大概了解了一个扩展程序的基本内容,可以开始写作自己的扩展了。

本文由ChromeChina翻译,转载注明出处

三、扩展图标

这是扩展开发指南的第三篇,前面我们首先作了第一个扩展,然后学习了Chrome扩展的大概结构,看完后可能会有些迷惑,别担心,相信随着我们学习的深入,我们渐渐发现我们已经可以做扩展了。当然为了做出优秀的扩展,我们还需要学习一些HTML、CSS、JavaScript的基础知识,网站就不错。

今天的文章翻译自,介绍Browser Action,即右侧的扩展图标。这节的内容还是挺有趣的。(同样,有翻译需要改进的地方请指出来)

Browser Actions的作用就是控制Chrome地址栏右侧添加一个图标。除了给chrome增加一个图标的功能外,还可以设置提示文字、图标标记、弹出窗口。

下图中,在地址栏右侧的彩色图标就是一个Browser Action。

澳门新浦京娱乐场网站 15

Browser Actions创建的图标是一直可见的,如果你想创建一个不是一直不可见的图标,可以使用page action。

Browser Action在Manifest文件中的位置

下面是个在扩展的manifest文件中注册browser action的例子:

  1. {
  2.   "name": "My extension",
  3.   ...
  4.   "browser_action": {
  5.     "default_icon": "images/icon19.png", // required
  6.     "default_title": "Google Mail",      // optional; shown in tooltip
  7.     "default_popup": "popup.html"        // optional
  8.   },
  9.   ...
  10. }
UI部分

Browser Action必须有一个图标。同时还可以有提示文字、图标标记、弹窗。

图标

Browser Action的图标会被浏览器缩放成19px*19px大小,太大的图标是没有意义的。

你可以用两种方法定义图标:用一个静态图片,或者用HTML中的canvas元素。用静态图片的话简单些,但是用canvas元素可以创建更加平滑的图片。

静态图片可以是任意常见格式的图片,包括BMP, GIF, ICO, JPEG, or PNG。

我们可以在manifest文件中用default_icon语句来定义这个图标,也可以调用setIcon()函数。

提示文字

提示文字是指将鼠标移到扩展图标上显示的文字。我们可以在manifest中用default_title定义,也可以通过调用setTitle()函数。

图标标记

图标标记是指覆盖在扩展图标上的一些文字,比如Gmail提醒图标上未读邮件数,PR查询工具上PR值。由于标记的位置很小,他最多只能容纳4个字母。

设置标记文字或者背景可以分别使用 setBadgeText() and setBadgeBackgroundColor()。

弹窗

当我们点击一些扩展的时候,会发现有个小弹窗出现,比如我们一开始的例子中。这个弹窗可以包含任何HTML内容,他的大小也是和内容自适应的。

给Browser Action增加弹窗可以在manifest的default_popup定义弹窗中显示的html文件名字,当然也可以使用setPopup()函数。

几个小提醒

为了扩展更加美观,请遵守下列守则:

仅在这个扩展需要在大部分页面运行的时候才使用browser action

仅在小部分页面起作用的话就不要用browser action,而是用page actions。

使用显眼的图标

不要试图模仿chrome浏览器原有的扳手/页面图标,你的扩展要独特一些。

你的图标边缘应该使用alpha透明,这样的话可以融合到各种不同的浏览器主题里。

例子解析

激动人心的时候来了,在这个文件夹下examples/api/browserAction有些browser action的例子。其中有个set_page_color,我们试着重新编写他。

首先我们知道,首先新建一个文件夹myExtension用来存放所有文件,我们知道每个Chrome扩展需要有个manifest.json文件来描述这个扩展,新建文件manifest.json,用文本编辑器打开,输入:

  1. {
  2.   "name": "我的扩展实例",
  3.   "version": "1.0",
  4.   "permissions": [
  5.     "tabs", "", ""
  6.   ],
  7.   "browser_action": {
  8.       "default_澳门新浦京娱乐场网站:完整实现代码,插件开发实录。title": "Set this page's color.",
  9.       "default_icon": "icon.png",
  10.       "popup": "popup.html"
  11.   }
  12. }

这是一个很简单的manifest.json文件模板,其中browser_action就是这篇文章降到的东西,default_title是描述,default_icon是图标,popup是弹窗。这里的弹窗调用了popup.html文件,我们再创建一个文件popup.html,popup.html是个普通的HTML文件,内容如下:

  1. <style>
  2. body {
  3.   overflow: hidden;
  4.   margin: 0px;
  5.   padding: 0px;
  6.   background: white;
  7. }
    1. div:first-child {
  8.   margin-top: 0px;
  9. }
    1. div {
  10.   cursor: pointer;
  11.   text-align: center;
  12.   padding: 1px 3px;
  13.   font-family: sans-serif;
  14.   font-size: 0.8em;
  15.   width: 100px;
  16.   margin-top: 1px;
  17.   background: #cccccc;
  18. }
  19. div:hover {
  20.   background: #aaaaaa;
  21. }
  22. #red {
  23.   border: 1px solid red;
  24.   color: red;
  25. }
  26. #blue {
  27.   border: 1px solid blue;
  28.   color: blue;
  29. }
  30. #green {
  31.   border: 1px solid green;
  32.   color: green;
  33. }
  34. #yellow {
  35.   border: 1px solid yellow;
  36.   color: yellow;
  37. }
  38. </style>
  39. <script>
  40. function click(color) {
  41.   chrome.tabs.executeScript(null,
  42.       {code:"document.body.style.backgroundColor='" color.id "'"});
  43.   window.close();
  44. }
  45. </script>
  46. <div onclick="click(this)" id="red">red</div>
  47. <div onclick="click(this)" id="blue">blue</div>
  48. <div onclick="click(this)" id="green">green</div>
  49. <div onclick="click(this)" id="yellow">yellow</div>

这个文件的内容有三种语言,HTML、CSS、JavaScript,这三种语言组成一个基本的网页,如果你还不是很清楚的话可以以后慢慢学些。其中调用了Chrome接口函数chrome.tabs.executeScript,也是以后会看到的。整个文件的意思是:1、显示四格不同颜色的矩形框,2、当点击这些矩形框的时候变换页面背景色。

我们还需要一个图标显示在工具栏上,把这个图片保存到文件夹中澳门新浦京娱乐场网站 16

好了,我们的扩展制作完成了,载入他们测试一下吧!

如果有一些JavaScript知识,可以修改这些扩展,创建一些丰富多彩的效果。

比如把popup.html中的

  1. function click(color) {
  2.   chrome.tabs.executeScript(null,
  3.       {code:"document.body.style.backgroundColor='" color.id "'"});
  4.   window.close();
  5. }
  6. </script>
  7. <div onclick="click(this)" id="red">red</div>
  8. <div onclick="click(this)" id="blue">blue</div>
  9. <div onclick="click(this)" id="green">green</div>
  10. <div onclick="click(this)" id="yellow">yellow</div>

换成

  1. function click(color) {
  2.   chrome.tabs.executeScript(null,
  3.       {code:"document.getElementById('lg').getElementsByTagName('img')[0].src='" color.title "'"});
  4.   window.close();
  5. }
  6. </script>
  7. <div onclick="click(this)" id="red" title=";
  8. <div onclick="click(this)" id="blue">blue</div>
  9. <div onclick="click(this)" id="green">green</div>
  10. <div onclick="click(this)" id="yellow">yellow</div>

在百度主页上打开这个扩展,点击第一个按钮"Google",可以把百度的logo换成google的。

四、选择页面

你可以提供一个选项页面(Options Pages)让用户自定义你的扩展。如果设置了选项页面,那么扩展管理页chrome://extensions将会有一个链接指向选项页面。

定义选项页面包括两步:

1、在manifest中定义选项页
  1. {
  2.   "name": "My extension",
  3.   ...
  4.   "options_page": "options.html",
  5.   ...
  6. }

上例中,options_page代表选项页面,options.html是具体的文件地址。

2、编写选项页面

选项页面是一个典型的网页,下面是一个选项页面的例子:

  1. <html>
  2. <head><title>My Test Extension Options</title></head>
  3. <script type="text/javascript">
    1. // Saves options to localStorage.
  4. function save_options() {
  5.   var select = document.getElementById("color");
  6.   var color = select.children[select.selectedIndex].value;
  7.   localStorage["favorite_color"] = color;
    1.   // Update status to let user know options were saved.
  8.   var status = document.getElementById("status");
  9.   status.innerHTML = "Options Saved.";
  10.   setTimeout(function() {
  11.     status.innerHTML = "";
  12.   }, 750);
  13. }
    1. // Restores select box state to saved value from localStorage.
  14. function restore_options() {
  15.   var favorite = localStorage["favorite_color"];
  16.   if (!favorite) {
  17.     return;
  18.   }
  19.   var select = document.getElementById("color");
  20.   for (var i = 0; i < select.children.length; i ) {
  21.     var child = select.children[i];
  22.     if (child.value == favorite) {
  23.       child.selected = "true";
  24.       break;
  25.     }
  26.   }
  27. }
    1. </script>
    1. <body onload="restore_options()">
    1. Favorite Color:
  28. <select id="color">
  29. 澳门新浦京娱乐场网站:完整实现代码,插件开发实录。<option value="red">red</option>
  30. <option value="green">green</option>
  31. <option value="blue">blue</option>
  32. <option value="yellow">yellow</option>
  33. </select>
    1. <br>
  34. <button onclick="save_options()">Save</button>
  35. </body>
  36. </html>
注意事项

早期版本的chrome可能不支持这个功能。

我们正计划提供一个默认的css来使得不同扩展的选项页面保持风格一致,你可以从这里()查看最新的进展。

知识补充

上面的例子中使用LOCALSTORAGE保存数据,具体介绍可以查看《使用LOCALSTORAGE保存数据》

原文 

由ChromeChina翻译,转载注明出处

五、重置页面

重置是一种用自己提供的页面替换Google Chrome默认页面的方法。一个重置页面常常是用HTML、JavaScript、CSS组成。

当前,能够替换的页面只有新标新标签页,新标签页就是我们打开一个新标签时出现的页面。

我们可以把默认的新标签页:


替换成这种样式:


重置页面非常简单,只需在Manifest中定义自己的页面地址。比如下面的例子中,我们使用了newtab.html来重定义新标签页。

  1. {
  2.   "name": "My extension",
  3.   ...
  4.   "chrome_url_overrides": {
  5.     "newtab": "newtab.html"
  6.   },
  7.   ...
  8. }


几点注意事项

为了让你定义的新标签页看起来不错,请遵循下面几点建议:

  • 保持页面简洁,使得能够快速加载
    由于新标签页经常出现,外观就显得特别重要。比如我们要避免从远程调用数据,或者读取数据库资源。
  • 确保有<title>标签
    如果没有<title>,大家讲会看到页面的URL,这会让人很迷惑,我们应该包含这样一句 <title>New Tab's Name</title>
  • 不要让键盘焦点在页面上
    我们应该让用户新建标签页的时候键盘焦点在地址栏上。
  • 不要模仿默认的新标签页面
    创建默认标签页的API(比如最近关闭的标签、最常访问的网站等等)不存在!你必须做出一些完全不同的东西。

例子

这儿examples/api/override有一些重置新标签页的例子。

其中有个我们至学习以来碰到的最简单的例子,把新标签页面换成空白页面

新建manifest.json文件:

  1. {
  2.   "name": "空白的新标签页",
  3.   "version": "0.1",
  4.   "chrome_url_overrides": {
  5.     "newtab": "blank.html"
  6.   }
  7. }

新建文件blank.html作为默认标签页,我们可以只写这样一句话:

  1. <title>新标签页</title>

好的,看看效果吧,就这么简单,你现在就可以动手DIY了。

原文 http://code.google.com/chrome/extensions/override.html
ChromeChina翻译,转载注明出处http://dev.chromechina.com/

以上文章均转自 Chrome扩展插件开发论坛

本文由澳门新浦京娱乐场网站发布于新浦京娱乐场官网,转载请注明出处:澳门新浦京娱乐场网站:完整实现代码,插件开