├── .gitignore ├── AxiosAsset.php ├── README.md ├── Vue.php ├── VueAsset.php ├── VueComponent.php ├── VueRouter.php ├── VueRouterAsset.php ├── composer.json ├── package.json └── views └── foo.php /.gitignore: -------------------------------------------------------------------------------- 1 | # node_modules 2 | /node_modules 3 | 4 | /package-lock.json -------------------------------------------------------------------------------- /AxiosAsset.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | class AxiosAsset extends \yii\web\AssetBundle{ 10 | public $sourcePath = '@vueroot/node_modules/axios/dist'; 11 | 12 | public $js = [ 13 | 'axios.min.js', 14 | ]; 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vuejs 2 | 3 | for yii2 web application 4 | 5 |

6 | 7 | [![Latest Stable Version](https://poser.pugx.org/aki/yii2-vue/v/stable)](https://packagist.org/packages/aki/yii2-vue) 8 | [![Total Downloads](https://poser.pugx.org/aki/yii2-vue/downloads)](https://packagist.org/packages/aki/yii2-vue) 9 | 10 |

11 | 12 | ## Installation 13 | 14 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 15 | 16 | Either run 17 | 18 | ``` 19 | php composer.phar require aki/yii2-vue "*" 20 | ``` 21 | 22 | or add 23 | 24 | ``` 25 | "aki/yii2-vue": "*" 26 | ``` 27 | 28 | to the require section of your `composer.json` file. 29 | 30 | ## After installing the extension, first install the vuejs framework 31 | 32 | Either run 33 | ``` 34 | # Move to folder 35 | cd ./vendor/aki/yii2-vue/ 36 | ``` 37 | and run command 38 | 39 | ``` 40 | # install deps 41 | npm install 42 | ``` 43 | 44 | Usage 45 | 46 | --- 47 | 48 | Once the extension is installed, simply use it in your code by : 49 | 50 | ```php 51 | 54 | "vue-app", 56 | 'data' => [ 57 | 'message' => "hello world!!", 58 | 'seen' => true, 59 | 'todos' => [ 60 | ['text' => "akbar joudi"], 61 | ['text' => "aref mohhamdzadeh"] 62 | ] 63 | ], 64 | 'methods' => [ 65 | 'reverseMessage' => new yii\web\JsExpression("function(){" 66 | . "this.message = this.message.split('').reverse().join(''); " 67 | . "}"), 68 | ], 69 | 'watch' => [ 70 | 'message' => new JsExpression('function(newval, oldval){ 71 | console.log(newval) 72 | }'), 73 | ] 74 | ]); ?> 75 | 76 |

{{ message }}

77 | 78 | 79 |

Now you see me

80 | 81 | 82 |
    83 |
  1. 84 | {{ todo.text }} 85 |
  2. 86 |
87 | 88 |

{{ message }}

89 | 90 | 91 | 92 | 93 | ``` 94 | 95 | Add Vue Router 96 | 97 | --- 98 | 99 | simply use it in your code by : 100 | 101 | ```php 102 | 107 | "vue-app", 109 | 'vueRouter'=> VueRouter::widget([ 110 | 'routes' => [ 111 | [ 112 | 'path' => '/foo', 113 | 'component' => new VueComponent([ 114 | 'template' => '@vueroot/views/foo.php', 115 | 'components' => [ 116 | 'yoo-component'=> new VueComponent([ 117 | 'template' => '
yoo!!! {{id}}
', 118 | 'props' => [ 119 | 'id' 120 | ] 121 | ]) 122 | ], 123 | ]) 124 | ], 125 | [ 126 | 'path' => '/bar', 127 | 'component' => new VueComponent([ 128 | 'template' => '
hello
' 129 | ]) 130 | ] 131 | ] 132 | ]) 133 | ]); ?> 134 | 135 | Go to Foo 136 | Go to Bar 137 | 138 | 139 | 140 | 141 | ``` 142 | -------------------------------------------------------------------------------- /Vue.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class Vue extends \yii\base\Widget 13 | { 14 | public $jsName = 'app'; 15 | 16 | /** 17 | * @see aki/vue/VueRouter 18 | */ 19 | public $vueRouter; 20 | 21 | /** 22 | * 23 | * @var Array 24 | */ 25 | public $data; 26 | 27 | /** 28 | * template 29 | */ 30 | public $templete; 31 | 32 | /** 33 | * 'methods' => [ 34 | * 'reverseMessage' => new yii\web\JsExpression("function(){" 35 | * . "this.message =1; " 36 | * . "}"), 37 | * ] 38 | * @var Array 39 | */ 40 | public $methods; 41 | 42 | /** 43 | * 44 | * @var Array 45 | */ 46 | public $watch; 47 | 48 | /** 49 | * 50 | * @var Array 51 | */ 52 | public $computed; 53 | 54 | /** 55 | * 56 | * @var \yii\web\JsExpression 57 | */ 58 | public $beforeCreate; 59 | 60 | /** 61 | * 62 | * @var \yii\web\JsExpression 63 | */ 64 | public $created; 65 | 66 | /** 67 | * 68 | * @var \yii\web\JsExpression 69 | */ 70 | public $beforeMount; 71 | 72 | /** 73 | * 74 | * @var \yii\web\JsExpression 75 | */ 76 | public $mounted; 77 | 78 | /** 79 | * 80 | * @var \yii\web\JsExpression 81 | */ 82 | public $beforeUpdate; 83 | 84 | /** 85 | * 86 | * @var \yii\web\JsExpression 87 | */ 88 | public $updated; 89 | 90 | /** 91 | * 92 | * @var \yii\web\JsExpression 93 | */ 94 | public $activated; 95 | 96 | /** 97 | * 98 | * @var \yii\web\JsExpression 99 | */ 100 | public $deactivated; 101 | 102 | /** 103 | * 104 | * @var \yii\web\JsExpression 105 | */ 106 | public $beforeDestroy; 107 | 108 | /** 109 | * 110 | * @var \yii\web\JsExpression 111 | */ 112 | public $destroyed; 113 | 114 | /** 115 | * @var Array 116 | */ 117 | public $components; 118 | 119 | 120 | public $use; 121 | 122 | /** 123 | * 124 | * @var \yii\web\JsExpression 125 | */ 126 | public $sockets; 127 | 128 | /** 129 | * @var boolean 130 | */ 131 | public $useAxios = false; 132 | 133 | 134 | public function init() 135 | { 136 | $this->view->registerAssetBundle(VueAsset::class); 137 | if ($this->useAxios) { 138 | $this->view->registerAssetBundle(AxiosAsset::class); 139 | } 140 | 141 | if ($this->vueRouter) { 142 | $this->view->registerAssetBundle(VueRouterAsset::class); 143 | } 144 | $this->view->registerCss(" 145 | [v-cloak] { 146 | display:none; 147 | } 148 | "); 149 | } 150 | 151 | public static function begin($config = array()) 152 | { 153 | $obj = parent::begin($config); 154 | echo '
'; 155 | return $obj; 156 | } 157 | 158 | 159 | public static function end() 160 | { 161 | echo '
'; 162 | return parent::end(); 163 | } 164 | 165 | public function run() 166 | { 167 | return $this->renderVuejs(); 168 | } 169 | 170 | public function renderVuejs() 171 | { 172 | 173 | $data = $this->generateData(); 174 | $methods = $this->generateMethods(); 175 | $watch = $this->generateWatch(); 176 | $computed = $this->generateComputed(); 177 | $components = $this->generateComponents(); 178 | $sockets = $this->generateSockets(); 179 | $el = $this->id; 180 | 181 | $use = $this->initUse(); 182 | 183 | $js = " 184 | var $el = { 185 | data : " . (!empty($data) ? $data : "''") . " 186 | }; 187 | 188 | " . (($this->vueRouter) ? $this->vueRouter : null) . " 189 | $use 190 | var ".$this->jsName.$el." = new Vue({ 191 | el: '#" . $el . "', 192 | " . (($this->vueRouter) ? "router," : null) . " 193 | " . (!empty($this->template) ? "template :'" . $this->template . "'," : null) . " 194 | " . (!empty($components) ? "components :" . $components . "," : null) . " 195 | " . (!empty($data) ? "data :".$el.".data," : null) . " 196 | " . (!empty($methods) ? "methods :" . $methods . "," : null) . " 197 | " . (!empty($watch) ? "watch :" . $watch . "," : null) . " 198 | " . (!empty($computed) ? "computed :" . $computed . "," : null) . " 199 | " . (!empty($this->beforeCreate) ? "beforeCreate :" . $this->beforeCreate->expression . "," : null) . " 200 | " . (!empty($this->created) ? "created :" . $this->created->expression . "," : null) . " 201 | " . (!empty($this->beforeMount) ? "beforeMount :" . $this->beforeMount->expression . "," : null) . " 202 | " . (!empty($this->mounted) ? "mounted :" . $this->mounted->expression . "," : null) . " 203 | " . (!empty($this->beforeUpdate) ? "beforeUpdate :" . $this->beforeUpdate->expression . "," : null) . " 204 | " . (!empty($this->updated) ? "updated :" . $this->updated->expression . "," : null) . " 205 | " . (!empty($this->beforeDestroy) ? "beforeDestroy :" . $this->beforeDestroy->expression . "," : null) . " 206 | " . (!empty($this->destroyed) ? "destroyed :" . $this->destroyed->expression . "," : null) . " 207 | " . (!empty($this->activated) ? "activated :" . $this->activated->expression . "," : null) . " 208 | " . (!empty($this->deactivated) ? "deactivated :" . $this->deactivated->expression . "," : null) . " 209 | " . (!empty($this->sockets) ? "sockets :" . $sockets . "," : null) . " 210 | }); 211 | "; 212 | Yii::$app->view->registerJs($js, \yii\web\View::POS_END); 213 | } 214 | 215 | public function generateData() 216 | { 217 | if (!empty($this->data)) { 218 | return json_encode($this->data); 219 | } 220 | } 221 | 222 | public function generateMethods() 223 | { 224 | if (is_array($this->methods) && !empty($this->methods)) { 225 | $str = ''; 226 | foreach ($this->methods as $key => $value) { 227 | if ($value instanceof \yii\web\JsExpression) { 228 | $str .= $key . ":" . $value->expression . ','; 229 | } 230 | } 231 | $str = rtrim($str, ','); 232 | return "{" . $str . "}"; 233 | } 234 | } 235 | 236 | 237 | public function generateWatch() 238 | { 239 | if (is_array($this->watch) && !empty($this->watch)) { 240 | $str = ''; 241 | foreach ($this->watch as $key => $value) { 242 | if ($value instanceof \yii\web\JsExpression) { 243 | $str .= $key . ":" . $value->expression . ','; 244 | } 245 | else{ 246 | $str .= $key . ":" . $value.','; 247 | } 248 | } 249 | $str = rtrim($str, ','); 250 | return "{" . $str . "}"; 251 | } 252 | } 253 | 254 | public function generateComputed() 255 | { 256 | if (is_array($this->computed) && !empty($this->computed)) { 257 | $str = ''; 258 | foreach ($this->computed as $key => $value) { 259 | if ($value instanceof \yii\web\JsExpression) { 260 | $str .= $key . ":" . $value->expression . ','; 261 | } 262 | } 263 | $str = rtrim($str, ','); 264 | return "{" . $str . "}"; 265 | } 266 | } 267 | 268 | public function generateComponents() 269 | { 270 | if (!empty($this->components)) { 271 | $components = ''; 272 | for ($i = 0; $i < count($this->components); $i++) { 273 | $component = new VueComponent($this->components[$i]); 274 | $components .= $component . ','; 275 | } 276 | return substr($components, 0, strlen($components) - 1); 277 | } 278 | return; 279 | } 280 | 281 | public function component($tagName, $option) 282 | { 283 | $option = json_encode($option); 284 | $this->view->registerJs(" 285 | Vue.component($tagName, $option); 286 | "); 287 | } 288 | 289 | public function generateSockets() 290 | { 291 | if (is_array($this->sockets) && !empty($this->sockets)) { 292 | $str = ''; 293 | foreach ($this->sockets as $key => $value) { 294 | if ($value instanceof \yii\web\JsExpression) { 295 | $str .= $key . ":" . $value->expression . ','; 296 | } 297 | } 298 | $str = rtrim($str, ','); 299 | return "{" . $str . "}"; 300 | } 301 | } 302 | 303 | 304 | public function initUse() 305 | { 306 | $use = ""; 307 | if ($this->use) { 308 | foreach ($this->use as $item) { 309 | $use .= "{$item->expression}"; 310 | } 311 | } 312 | return $use; 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /VueAsset.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | class VueAsset extends \yii\web\AssetBundle{ 10 | public $sourcePath = '@vueroot/node_modules/vue/dist'; 11 | 12 | public $js = [ 13 | ]; 14 | 15 | public function init() 16 | { 17 | $this->js[] = YII_ENV_DEV ? 'vue.js' : 'vue.min.js'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /VueComponent.php: -------------------------------------------------------------------------------- 1 | [ 30 | * 'reverseMessage' => new yii\web\JsExpression("function(){" 31 | * . "this.message =1; " 32 | * . "}"), 33 | * ] 34 | * @var Array 35 | */ 36 | public $methods; 37 | 38 | /** 39 | * 40 | * @var Array 41 | */ 42 | public $watch; 43 | 44 | /** 45 | * 46 | * @var Array 47 | */ 48 | public $computed; 49 | 50 | /** 51 | * 52 | * @var \yii\web\JsExpression 53 | */ 54 | public $beforeCreate; 55 | 56 | /** 57 | * 58 | * @var \yii\web\JsExpression 59 | */ 60 | public $created; 61 | 62 | /** 63 | * 64 | * @var \yii\web\JsExpression 65 | */ 66 | public $beforeMount; 67 | 68 | /** 69 | * 70 | * @var \yii\web\JsExpression 71 | */ 72 | public $mounted; 73 | 74 | /** 75 | * 76 | * @var \yii\web\JsExpression 77 | */ 78 | public $beforeUpdate; 79 | 80 | /** 81 | * 82 | * @var \yii\web\JsExpression 83 | */ 84 | public $updated; 85 | 86 | /** 87 | * 88 | * @var \yii\web\JsExpression 89 | */ 90 | public $activated; 91 | 92 | /** 93 | * 94 | * @var \yii\web\JsExpression 95 | */ 96 | public $deactivated; 97 | 98 | /** 99 | * 100 | * @var \yii\web\JsExpression 101 | */ 102 | public $beforeDestroy; 103 | 104 | /** 105 | * 106 | * @var \yii\web\JsExpression 107 | */ 108 | public $destroyed; 109 | 110 | /** 111 | * @var Array 112 | */ 113 | public $components; 114 | 115 | /** 116 | * @var Array 117 | */ 118 | public $props; 119 | 120 | 121 | public function exec() 122 | { 123 | $data = $this->generateData(); 124 | $methods = $this->generateMethods(); 125 | $watch = $this->generateWatch(); 126 | $computed = $this->generateComputed(); 127 | $components = $this->generateComponents(); 128 | $props = $this->generateProps(); 129 | 130 | $output = ''; 131 | $path = Yii::getAlias($this->template); 132 | if (is_dir(dirname($path))) { 133 | ob_start(); 134 | include $path; 135 | $output = ob_get_contents(); 136 | ob_end_clean(); 137 | 138 | $output = str_replace(array("\r\n", "\r"), "\n", $output); 139 | $lines = explode("\n", $output); 140 | $new_lines = array(); 141 | 142 | foreach ($lines as $i => $line) { 143 | if (!empty($line)) 144 | $new_lines[] = trim($line); 145 | } 146 | $output = implode($new_lines); 147 | } else { 148 | $output = $this->template; 149 | } 150 | 151 | // if() 152 | return " { 153 | template: '" . $output . "', 154 | ".(!empty($data) ? "data: function () { 155 | return { 156 | ".$data." 157 | } 158 | },":null)." 159 | ".(!empty($methods) ? "methods :".$methods.",":null)." 160 | ".(!empty($watch) ? "watch :".$watch.",":null)." 161 | ".(!empty($computed) ? "computed :".$computed.",":null)." 162 | ".(!empty($components) ? "components :{".$components."},":null)." 163 | ".(!empty($props) ? "props :[".$props."]":null)." 164 | }"; 165 | } 166 | 167 | public function generateProps() { 168 | if(!empty($this->props)){ 169 | $str =''; 170 | foreach ($this->props as $key => $value) { 171 | $str .= "'".$value."',"; 172 | } 173 | $str = substr($str, 0, strlen($str)-1); 174 | return $str; 175 | } 176 | } 177 | public function generateData() { 178 | if(!empty($this->data)){ 179 | $str =''; 180 | foreach ($this->data as $key => $value) { 181 | if(is_numeric($value)){ 182 | $str .= $key.':'.$value.','; 183 | } 184 | else{ 185 | $str .= $key.':"'.$value.'",'; 186 | } 187 | 188 | } 189 | $str = substr($str, 0, strlen($str)-1); 190 | return $str; 191 | } 192 | } 193 | 194 | public function generateMethods() { 195 | if(is_array($this->methods) && !empty($this->methods)){ 196 | $str = ''; 197 | foreach ($this->methods as $key => $value) { 198 | if($value instanceof \yii\web\JsExpression){ 199 | $str.= $key.":".$value->expression.','; 200 | } 201 | } 202 | $str = rtrim($str,','); 203 | return "{".$str."}"; 204 | } 205 | } 206 | 207 | 208 | public function generateWatch() { 209 | if(is_array($this->watch) && !empty($this->watch)){ 210 | $str = ''; 211 | foreach ($this->watch as $key => $value) { 212 | if($value instanceof \yii\web\JsExpression){ 213 | $str.= $key.":".$value->expression.','; 214 | } 215 | } 216 | $str = rtrim($str,','); 217 | return "{".$str."}"; 218 | } 219 | } 220 | 221 | public function generateComputed() { 222 | if(is_array($this->computed) && !empty($this->computed)){ 223 | $str = ''; 224 | foreach ($this->computed as $key => $value) { 225 | if($value instanceof \yii\web\JsExpression){ 226 | $str.= $key.":".$value->expression.','; 227 | } 228 | } 229 | $str = rtrim($str,','); 230 | return "{".$str."}"; 231 | } 232 | } 233 | 234 | public function generateComponents() { 235 | if(!empty($this->components)) 236 | { 237 | // die(var_dump(($this->components))); 238 | $components=''; 239 | foreach ($this->components as $key => $value) { 240 | 241 | if(is_object($value)){ 242 | 243 | $component = "'".$key."':".($value)->exec(); 244 | 245 | } 246 | else{ 247 | $component = "'".$key."':".new VueComponent($value); 248 | } 249 | 250 | $components .= $component.','; 251 | } 252 | return substr($components, 0, strlen($components)-1); 253 | } 254 | return; 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /VueRouter.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class VueRouter extends \yii\base\Widget 12 | { 13 | public static $outlet = ""; 14 | /** 15 | * 16 | */ 17 | public $routes = []; 18 | 19 | 20 | 21 | /** 22 | * 23 | */ 24 | public function run() 25 | { 26 | // die(var_dump(($this->routes[0]['component']->exec()))); 27 | $str = " 28 | const routes = [ 29 | "; 30 | 31 | for($i=0; $iroutes); $i++) 32 | { 33 | $str.= "{path:'".$this->routes[$i]['path']."', component:".$this->routes[$i]['component']->exec()."},"; 34 | } 35 | $str = substr($str, 0, strlen($str)-1); 36 | $str .=" 37 | ] 38 | "; 39 | $routerstr = $str." 40 | const router = new VueRouter({ 41 | routes 42 | }) 43 | "; 44 | return $routerstr; 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /VueRouterAsset.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | class VueRouterAsset extends \yii\web\AssetBundle{ 10 | public $sourcePath = '@vueroot/node_modules/vue-router/dist'; 11 | 12 | public $js = [ 13 | ]; 14 | 15 | public function init() 16 | { 17 | $this->js[] = YII_ENV_DEV ? 'vue-router.js' : 'vue-router.min.js'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aki/yii2-vue", 3 | "description": "for yii2 web application ", 4 | "type": "yii2-extension", 5 | "keywords": ["yii2","vue"," yii2-vue"," yii2"," vuejs"," akbar-joudi"," vue.js"], 6 | "license": "LGPL-3.0+", 7 | "authors": [ 8 | { 9 | "name": "akbar joudi", 10 | "email": "akbar.joody@gmail.com" 11 | } 12 | ], 13 | "require": { 14 | "yiisoft/yii2": "*" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "aki\\vue\\": "" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yii2-vue", 3 | "version": "1.0.0", 4 | "description": "vuejs ===== for yii2 web application", 5 | "dependencies": { 6 | "axios": "^0.19.2", 7 | "vue": "^2.6.11", 8 | "vue-router": "^3.1.6" 9 | }, 10 | "devDependencies": {}, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "author": "akbar joudi", 15 | "license": "ISC" 16 | } 17 | -------------------------------------------------------------------------------- /views/foo.php: -------------------------------------------------------------------------------- 1 |
2 |
foo Panel Heading
3 |
{{this.$data.name}}
4 | 5 | 6 |
7 | --------------------------------------------------------------------------------